2

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

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;

}
4

2 回答 2

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);
于 2012-02-08T17:37:58.583 回答
1

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

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

于 2012-02-08T22:21:55.710 回答