2012-02-08 71 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