2012-06-26 71 views
4

所以我在這裏遇到了一些麻煩,我的AudioUnit從iOS中的麥克風/線路輸入中獲取數據。我能夠把所有東西都設置爲我認爲可以接受的狀態,並且它正在調用我的recordingCallback,但是我從緩衝區中獲取的數據不正確。它總是返回完全相同的東西,這大多是零和隨機大數。有誰知道可能是什麼原因造成的。我的代碼如下。AudioUnit輸入示例

設置音頻單元

OSStatus status; 

// Describe audio component 
AudioComponentDescription desc; 
desc.componentType = kAudioUnitType_Output; 
desc.componentSubType = kAudioUnitSubType_RemoteIO; 
desc.componentFlags = 0; 
desc.componentFlagsMask = 0; 
desc.componentManufacturer = kAudioUnitManufacturer_Apple; 

// Get component 
AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc); 
status = AudioComponentInstanceNew(inputComponent, &audioUnit); 

// Enable IO for recording 
UInt32 flag = 1; 
status = AudioUnitSetProperty(audioUnit, 
           kAudioOutputUnitProperty_EnableIO, 
           kAudioUnitScope_Input, 
           kInputBusNumber, 
           &flag, 
           sizeof(flag)); 
// Disable playback IO 
flag = 0; 
status = AudioUnitSetProperty(audioUnit, 
           kAudioOutputUnitProperty_EnableIO, 
           kAudioUnitScope_Output, 
           kOutputBusNumber, 
           &flag, 
           sizeof(flag)); 

// Describe format 
AudioStreamBasicDescription audioFormat; 
audioFormat.mSampleRate   = 44100.00; 
audioFormat.mFormatID   = kAudioFormatLinearPCM; 
audioFormat.mFormatFlags  = kAudioFormatFlagsNativeFloatPacked |kAudioFormatFlagIsNonInterleaved; 
audioFormat.mFramesPerPacket = 1; 
audioFormat.mChannelsPerFrame = 1; 
audioFormat.mBitsPerChannel  = 32; 
audioFormat.mBytesPerPacket  = 4; 
audioFormat.mBytesPerFrame  = 4; 

// Apply format 
status = AudioUnitSetProperty(audioUnit, 
           kAudioUnitProperty_StreamFormat, 
           kAudioUnitScope_Output, 
           kInputBusNumber, 
           &audioFormat, 
           sizeof(audioFormat)); 

// Set input callback 
AURenderCallbackStruct callbackStruct; 
callbackStruct.inputProc = recordingCallback; 
callbackStruct.inputProcRefCon = (__bridge void*)self; 
status = AudioUnitSetProperty(audioUnit, 
           kAudioOutputUnitProperty_SetInputCallback, 
           kAudioUnitScope_Global, 
           kInputBusNumber, 
           &callbackStruct, 
           sizeof(callbackStruct)); 
status = AudioUnitInitialize(audioUnit); 

輸入回調

static OSStatus recordingCallback(void *inRefCon, 
            AudioUnitRenderActionFlags *ioActionFlags, 
            const AudioTimeStamp *inTimeStamp, 
            UInt32 inBusNumber, 
            UInt32 inNumberFrames, 
            AudioBufferList *ioData) { 

    AudioBufferList bufferList; 
    bufferList.mNumberBuffers = 1; 
    bufferList.mBuffers[0].mDataByteSize = 4; 
    bufferList.mBuffers[0].mNumberChannels = 1; 
    bufferList.mBuffers[0].mData = malloc(sizeof(float)*inNumberFrames); // 
    InputAudio *input = (__bridge InputAudio*)inRefCon; 

    OSStatus status; 

    status = AudioUnitRender([input audioUnit], 
          ioActionFlags, 
          inTimeStamp, 
          inBusNumber, 
          inNumberFrames, 
          &bufferList); 

    float* result = (float*)&bufferList.mBuffers[0].mData; 

    if (input->counter == 5) { 
     for (int i = 0;i<inNumberFrames;i++) { 
      printf("%f ",result[i]); 
     } 
    } 
    input->counter++; 
    return noErr; 
} 

有誰遇到類似的問題,或者看到一些明顯的錯誤在我的代碼。預先感謝任何幫助!

我所有基礎的它關閉的Michael Tysons Core Audio RemoteIO code

+0

這是一段時間以前,但以防萬一有人看到這個並複製代碼:你不應該在時間敏感的代碼中使用malloc。在其他地方分配緩衝區。 (或懶惰地分配一次。) –

回答

2

如果我沒記錯,你在回調音頻緩衝拿到樣品不是花車,他們SInt16。嘗試鑄造的樣品是這樣的:

SInt16 *sn16AudioData= (SInt16 *)(bufferList.mBuffers[0].mData); 

而這些應該是最大值和最小值:

#define sn16_MAX_SAMPLE_VALUE 32767 
#define sn16_MIN_SAMPLE_VALUE -32768 
+0

我也這樣做,只是在這個例子中,我忘了將它改回到SInt16。它似乎不斷回報我只是廢話我根本無法使用的數據。 – MZimmerman6

0

我基本上是試圖做同樣的事情非常相似的代碼,但使用AudioGraph()。我有同樣的問題,零點從話筒我的輸出數據,並不能得到它的工作,直到我當你不使用的圖形,你將需要調用AudioUnitSetProperty()kAudioUnitProperty_MakeConnectio n和通增加了行

Status = AUGraphConnectNodeInput(graph, ioNode, 1, ioNode, 0); 

並傳遞一個完整的AudioUnitConnection結構

+0

我能否獲得您正在使用的代碼的副本?如果是這樣,讓我知道,我會給你我的電子郵件地址。 – MZimmerman6

+0

是的,我的網站是[link](http://www.zippysystems.com)轉到聯繫我們頁面。我會給你發送創建函數。 – Dan