2012-10-27 70 views
0

我正在爲客戶端做一些音頻編程,而且遇到了一個我只是不理解的問題。Objective C變量值未被保存

我有一個由CoreAudio重複調用的渲染回調函數。這裏面回調我有以下幾點:

// Get the audio sample data 
AudioSampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData; 

Float32 data; 

// Loop over the samples 
for (UInt32 frame = 0; frame < inNumberFrames; frame++) { 

    // Convert from SInt16 to Float32 just to prove it's possible 
    data = (Float32) outA[frame]/(Float32) 32768; 

    // Convert back to SInt16 to show that everything works as expected 
    outA[frame] = (SInt16) round(next * 32768); 

} 

可正常工作,顯示沒有任何意外的舍入誤差。

我想要做的下一件事是添加一個小的延遲。我一個全局變量添加到類:

即@implementation行

Float32 last = 0; 

然後我使用這個變量來獲得一幀延遲如下:

// Get the audio sample data 
AudioSampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData; 

Float32 data; 
Float32 next; 

// Loop over the samples 
for (UInt32 frame = 0; frame < inNumberFrames; frame++) { 

    // Convert from SInt16 to Float32 just to prove it's possible 
    data = (Float32) outA[frame]/(Float32) 32768; 

    next = last; 
    last = data; 


    // Convert back to SInt16 to show that everything works as expected 
    outA[frame] = (SInt16) round(next * 32768); 

} 

這一次有一個信號上奇怪的音頻失真。

我只是不能看到我做錯了什麼!任何建議將不勝感激。

+0

我認爲這是一個音頻問題,而不是C問題。嘗試記錄所有變量的值並查看是否有幫助。在跳到結論之前總是記錄日誌。 – Linuxios

+1

這可能是一個線程問題。檢查您的代碼是否始終在同一個線程上運行。即NSLog(@「thread:%@」,[NSThread currentThread]);.如果沒有,你需要用鎖/互斥鎖來保護你的全局。 – EricS

回答

2

看來你所做的是在音頻上引入了無意的phaser效應。

這是因爲您只拖延了音頻的一個通道,所以結果是您的左聲道被延遲了一個幀後面的右聲道。這會導致一些奇怪的頻率取消/放大,以適應您對「奇怪的音頻失真」的描述。

嘗試應用效果兩個通道:

AudioSampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData; 
AudioSampleType *outB = (AudioSampleType *)ioData->mBuffers[1].mData; 
// apply the same effect to outB as you did to outA 

這是假設您正在使用立體聲音頻(即ioData->mNumberBuffers == 2

作爲一個風格問題的工作,它(IMO)是一個壞主意在渲染回調中使用全局變量,如last變量。使用inRefCon傳遞適當的上下文(如果需要,可以作爲單個變量或結構體)。雖然這可能與您遇到的問題無關。

+0

+1在房子裏有一個音頻傢伙。優秀的答案! –

+0

感謝您的回答。我實際上使用的是單聲道流格式(用於iPad),這就是爲什麼我只使用頻道。問題原來,音頻是一個SInt32而不是一個SInt16。因此,我無意中將SInt16作爲SInt32投入使用。這似乎導致了一些隨機的數據徘徊。道德 - 非常小心使用哪種變量!我嚴格使用全局變量來進行測試。實際上,我正在編寫合唱效果,因此inRefCon包含很多變量和緩衝區。 –