2012-02-20 213 views
3

我只是努力从麦克风以获取样本进行处理。我有一个为输入和输出设置的音频单元,并且都有渲染回调。我的问题是关于麦克风回调的回调。kAudioUnitProperty_ShouldAllocateBuffer没有效果

我想核心音频分配在麦克风回调缓冲区我。

UInt32 shouldAllocateBuffer = 1; 
AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Global, 1, &shouldAllocateBuffer, sizeof(shouldAllocateBuffer)); 

但是,这样做总是会在回调中产生一个NULL ioData指针。我坚持分配我自己的缓冲区?

输入

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

OSStatus status; 
status = AudioUnitRender(audioUnit, 
         ioActionFlags, 
         inTimeStamp, 
         inBusNumber, 
         inNumberFrames, 
         ioData); // ioData is null here 
} 

回放

static OSStatus playbackCallback(void *inRefCon, 
            AudioUnitRenderActionFlags *ioActionFlags, 
            const AudioTimeStamp *inTimeStamp, 
            UInt32 inBusNumber, 
            UInt32 inNumberFrames, 
            AudioBufferList *ioData) {  
// ioData is not NULL here but I get silence in the headphones. 
    return noErr; 
} 

回答

4

AudioUnitRender仍然期望AudioBufferList参数(ioData)为非NULL。

如果ioData是一个指向AudioBufferList的指针,那么大多数情况下应该是ioData-> mBuffers [0] .mData的缓冲区(请参阅docs)。如果你没有分配缓冲区,缓冲区列表可能应该是一个局部变量,因为它只对回调有效。

所以,基本上使用局部变量,而不是ioData。

请注意,您还需要设置你的AudioBufferList以符合您所描述的拓扑结构。

下面是一个例子:

AudioBufferList bufferList; 
bufferList.mNumberBuffers = 1; 
bufferList.mBuffers[0].mData = NULL; 
OSStatus status; 
status = AudioUnitRender(audioUnit, 
         ioActionFlags, 
         inTimeStamp, 
         inBusNumber, 
         inNumberFrames, 
         &bufferList); // bufferList.mBuffers[0].mData is null 
// Use the input data in now valid bufferList.mBuffers[0].mData 
// note the buffer is only valid for the callback. 

请注意,如果你需要不止一个缓冲区(你可能不这样做,即使是立体声),你可以使用malloc延长mBuffers数组的大小。

+0

所以无论什么时候你在录​​音回调需要什么来分配自己的缓冲区?另外如果我想在回放回调中使用这个捕获的音频,我应该将本地缓冲区数据复制到其他自我管理的缓冲区以复制回放回调ioData? – dubbeat 2012-02-20 21:22:35

+0

mData为NULL,因此AudioUnit正在为您分配和提供。这与提供自己的不同 - 如果您提供自己的缓冲区,则需要先将它们malloc并稍后释放它们。如果您想捕获它以备后用,可以将其复制到另一个缓冲区,但效率不高 - 在这种情况下,您可能应该提供自己的缓冲区。 – 2012-02-20 21:29:59

+0

抓22.如果你不提供自己的缓冲区,并且想要的数据,你需要将数据无论如何复制到自己的缓冲区(一个或多个)。 – hotpaw2 2012-02-21 07:09:48