2012-02-08 64 views
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; 

} 
+1

什么是你的问题,具体是? – Brad 2012-02-08 17:32:37

+1

我想知道“生成样本”是如何工作的。以及如何修改它以产生不同的波形,如锯齿形,三角形和方形。 – user1197773 2012-02-08 17:38:32

回答

2

实际正弦波样本和被填充下面

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除以您的采样率。

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

如果你想生成比正弦波其他的东西,你只需更换一些其他功能,下面一行:

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

即比方说,例如,您想要无限傅立叶级数中的前三项收敛到三角波;那么你可能有替代以下...

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

有没有一种基于波形类型的知识来创建新频率的方法。 – user1197773 2012-02-08 17:56:34

+0

我不太确定你在这里问什么 - 你的意思是正弦频率的反馈控制?如果是这样,那很大程度上取决于其他软件(和硬件)的实现...... 否则,它看起来像信号的频率是由你的'ToneGeneratorViewController'的'frequency'成员变量决定的。我会开始在那里查看,看看是否有一个setter可以用来在运行时处理这个值。 – hatboyzero 2012-02-08 17:59:33

+1

对不起,我的意思是:是否有一种方法来创建一个新的波型,从知道波型的样子。所以我可以看到一个三角波,然后了解如何创建一个。 – user1197773 2012-02-08 18:00:47

0

要生成所需的波形,你需要产生所需波形的函数来代替罪()函数。

您可能可以通过图形化示例在函数表中找到该函数,或者您可能需要创建函数。创建函数近似的方法很多,包括多项式,傅里叶级数,带或不带插值的表查找,递归等等。但这是一个很大的课题(许多教科书等)

+0

它不会创造一系列的冲动,伙计 – 2014-05-13 02:18:24