制定振荡器波型代码,并创建新的波型

时间:2012-02-08 17:31:17

标签: objective-c audio ios5 core-audio synthesizer

我想在我的音频生成器应用程序中找出一些生成振荡器波形的代码。这个例子中的一个是正弦波,有人可以告诉我代码是如何工作的,因为我希望将来制作自定义波形类型和方形,锯齿形和三角形类型。

OSStatus RenderTone(
    void *inRefCon, 
    AudioUnitRenderActionFlags  *ioActionFlags, 
    const AudioTimeStamp        *inTimeStamp, 
    UInt32                      inBusNumber, 
    UInt32                      inNumberFrames, 
    AudioBufferList             *ioData)

{
    // Fixed amplitude is good enough for our purposes
    const double amplitude = 0.25;

    // Get the tone parameters out of the view controller
    ToneGeneratorViewController *viewController =
        (ToneGeneratorViewController *)inRefCon;
    double theta = viewController->theta;
    double theta_increment = 2.0 * M_PI * viewController->frequency / viewController->sampleRate;

    // This is a mono tone generator so we only need the first buffer
    const int channel = 0;
    Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;

     // Generate the samples
     for (UInt32 frame = 0; frame < inNumberFrames; frame++) 
    {
        buffer[frame] = sin(theta) * amplitude;

        theta += theta_increment;
        if (theta > 2.0 * M_PI)
        {
             theta -= 2.0 * M_PI;
        } 
    }

    // Store the theta back in the view controller
    viewController->theta = theta;

    return noErr;

}

2 个答案:

答案 0 :(得分:1)

正在生成实际的正弦波样本,并在下面的代码段中填充缓冲区

for (UInt32 frame = 0; frame < inNumberFrames; frame++) 
{
    buffer[frame] = sin(theta) * amplitude;

    theta += theta_increment;
    if (theta > 2.0 * M_PI)
    {
         theta -= 2.0 * M_PI;
    } 
}

在分配buffer[frame]的行中,您正在调用sin(theta) * amplitude,并且对于for循环的每次迭代,您通过某个有限步骤递增theta大小取决于您的频率和采样率,通过

double theta_increment = 2.0 * M_PI * viewController->frequency / viewController->sampleRate;

基本上将2.0 * PI * frequency除以您的采样率。

在循环theta循环时递增for变量基本上是一次一个样本的时间步长,直到缓冲区已满(即frame == iNumberFrames)。

如果您想要生成除正弦波以外的其他内容,您只需使用其他功能替换以下行:

buffer[frame] = sin(theta) * amplitude;

即。比方说,你想要无限傅立叶级数中的前三个项收敛为三角波;你可能会有以下代码......

buffer[frame] = (8 / pow(M_PI,2)) * (sin(theta) - sin(3*theta)/9 + sin(5*theta)/25);

答案 1 :(得分:1)

要生成所需的波形,您需要将sin()函数替换为产生所需波形的函数。

您可以在带有图形示例的函数表中找到此函数,或者您可能必须创建函数。有很多方法可以创建一个函数逼近,包括多项式,傅里叶级数,有或没有插值的表查找,递归等等。但这本身就是一个很大的主题(许多教科书等)