2014-01-24 20 views
3

我創建了一個連接到AUGraph的簡單波形發生器。我重用了來自蘋果的一些示例代碼來設置AudioStreamBasicDescription這樣iOS波形發生器通過AUGraph連接

void SetCanonical(UInt32 nChannels, bool interleaved) 
      // note: leaves sample rate untouched 
{ 
    mFormatID = kAudioFormatLinearPCM; 
    int sampleSize = SizeOf32(AudioSampleType); 
    mFormatFlags = kAudioFormatFlagsCanonical; 
    mBitsPerChannel = 8 * sampleSize; 
    mChannelsPerFrame = nChannels; 
    mFramesPerPacket = 1; 
    if (interleaved) 
     mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize; 
    else { 
     mBytesPerPacket = mBytesPerFrame = sampleSize; 
     mFormatFlags |= kAudioFormatFlagIsNonInterleaved; 
    } 
} 

在我的課堂我調用這個函數

mClientFormat.SetCanonical(2, true); 
mClientFormat.mSampleRate = kSampleRate; 

而採樣率是

#define kSampleRate  44100.0f; 

其他的設置採取來自示例代碼以及

// output unit 
CAComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple); 

// iPodEQ unit 
CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple); 

// multichannel mixer unit 
CAComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple); 

一切工作正常,但問題是,我沒有得到立體聲和我的回調函數失敗(壞訪問)當我試圖達到第二緩衝

Float32 *bufferLeft = (Float32 *)ioData->mBuffers[0].mData; 
Float32 *bufferRight = (Float32 *)ioData->mBuffers[1].mData; 

// Generate the samples 
for (UInt32 frame = 0; frame < inNumberFrames; frame++) 
{ 
    switch (generator.soundType) { 

     case 0: //Sine 

      bufferLeft[frame] = sinf(thetaLeft) * amplitude; 
      bufferRight[frame] = sinf(thetaRight) * amplitude; 
      break; 

這樣看來我得到單代替的立體聲。指針bufferRight是空的,但不知道爲什麼。 任何幫助將不勝感激。

+0

只是巧合我在瀏覽器中打開了這兩個選項卡:[SCWaveformView](https://github.com/rFlex/SCWaveformView)。也許別人偶然發現了你的問題,只想把一個工作波形圖作爲一個庫;) – 2014-02-08 13:12:08

回答

0

我可以看到兩個可能的錯誤。首先,由於@invalidname指出,以立體聲錄製可能不適用於iPhone等單聲道設備。好吧,它可能會起作用,但如果是這樣的話,您只需要返回雙單聲道立體聲流,那麼爲什麼要麻煩呢?你也可以配置你的數據流在單聲道工作,並節省CPU的開銷。

第二個問題可能是聲音失真的根源。你流描述格式的標誌應該是:

kAudioFormatFlagIsSignedInteger | 
kAudioFormatFlagsNativeEndian | 
kAudioFormatFlagIsPacked 

另外,不要忘記將mReserved標誌設置爲0,雖然可能被忽略這個標誌的價值,它不會傷害到明確將其設置爲0只是爲了確保。

編輯:在iPhone上調試音頻的另一個更爲通用的提示 - 如果您正在獲取失真,剪輯或其他奇怪效果,請從手機中獲取數據有效載荷,然後在波形編輯器中查看錄製內容。能夠縮小並查看單個樣本會爲您提供很多關於錯誤的線索。要做到這一點,你需要打開「Organizer」窗口,點擊你的手機,然後展開你的應用程序旁邊的小箭頭(在你通常會卸載它的地方)。現在你會看到一個向下的箭頭,如果你點擊它,Xcode會將你的應用中的數據有效載荷複製到硬盤上的某個地方。如果您將錄製內容轉儲到磁盤,則會在此處找到解壓縮的文件。從link

+0

我需要立體聲,因爲我爲每個聲道都加入了不同的頻率。我可以用「AudioComponentInstance」來做到這一點,但到那時我最需要建立自己的均衡器,這可以通過AUGraph更容易完成。 – Vanya

0

我猜問題

引用是你指定一個交錯格式,但隨後訪問該緩衝區,如果他們在你的IO回調非交錯。 ioData-> mBuffers [1]無效,因爲左側和右側的所有數據都在ioData-> mBuffers [0] .mData中交錯。檢查ioData-> mNumberBuffers。我的猜測是它被設置爲1.另外,驗證ioData-> mBuffers [0] .mNumberChannels設置爲2,這將表示交錯數據。

還檢查了核心音頻公共實用程序類來幫助設置格式的東西。使其變得如此簡單。你的設置格式的代碼可以減少到一行,你會更加確信它是正確的(儘管你的格式看起來設置正確 - 如果你想要的是交錯的16位int):

CAStreamBasicDescription myFormat(44100.0, 2, CAStreamBasicDescription::kPCMFormatInt16, true) 

蘋果使用已安裝在Xcode的SDK打包這些類,但現在你需要從這裏下載:https://developer.apple.com/library/mac/samplecode/CoreAudioUtilityClasses/Introduction/Intro.html

不管怎麼說,它看起來像最簡單的解決對你來說只是改變格式非交錯。所以在你的代碼中:mClientFormat.SetCanonical(2,false);

+0

我試過了,它似乎沒有工作。但是,無論如何。 – Vanya