2013-03-01 62 views
0

取样类似的项目MixerHost,我想混合输出流写入到文件而不是到speakers.So我用kAudioUnitSubType_GenericOutput,并呼吁:呼叫AudioUnitRender之外呈现回调方法

CheckError(AudioUnitInitialize(mixerUnit), "AudioUnitInitialize mixerUnit"); 
CheckError(AudioUnitInitialize(ioUnit), "AudioUnitInitialize iOUnit"); 
CheckError(AudioOutputUnitStart(ioUnit), "AudioOutputUnitStart iOUnit"); 

AudioUnitRenderActionFlags ioActionFlags = 0; 
AudioTimeStamp inTimeStamp; 
memset(&inTimeStamp, 0, sizeof(AudioTimeStamp)); 
inTimeStamp.mFlags = kAudioTimeStampSampleTimeValid; 
UInt32 inOutputBusNumber = 0; 
UInt32 inNumberFrames = 100; 
AudioBuffer buffer; 
buffer.mNumberChannels = 2; 
buffer.mDataByteSize = inNumberFrames*2; 
buffer.mData = malloc(inNumberFrames*2); 
AudioBufferList ioData; 
ioData.mNumberBuffers = 1; 
ioData.mBuffers[0] = buffer; 
CheckError(AudioUnitRender(ioUnit, 
          &ioActionFlags, 
          &inTimeStamp, 
          inOutputBusNumber, 
          inNumberFrames, 
          &ioData), 
      "AudioUnitRender"); 

错误:AudioUnitRender(-50),请告诉我正确的方法来调用AudioUnitRender()

iluvcapra是正确的,我改变了它的工作原理:

AudioUnitRenderActionFlags flags = 0; 
AudioTimeStamp inTimeStamp; 
memset(&inTimeStamp, 0, sizeof(AudioTimeStamp)); 
inTimeStamp.mFlags = kAudioTimeStampSampleTimeValid; 
UInt32 busNumber = 0; 
UInt32 numberFrames = 100; 

int channelCount = 2; 
AudioBufferList *bufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList)+sizeof(AudioBuffer)*(channelCount-1)); 
bufferList->mNumberBuffers = channelCount; 
for (int i=0; i<channelCount; i++) { 
    AudioBuffer buffer = {0}; 
    buffer.mNumberChannels = 1; 
    buffer.mDataByteSize = numberFrames*sizeof(AudioUnitSampleType); 
    buffer.mData = calloc(numberFrames, sizeof(AudioUnitSampleType)); 

    bufferList->mBuffers[i] = buffer; 

} 
CheckError(AudioUnitRender(ioUnit, 
          &flags, 
          &inTimeStamp, 
          busNumber, 
          numberFrames, 
          bufferList), 
      "AudioUnitRender ioUnit"); 
+0

iluvcapra是正确的, – user2122490 2013-03-03 15:11:43

回答

0

两件事情,虽然没有看到更多的我不能说,如果这是所有这是错误的:

  • 你的采样时间是无效的,你要增加这为绘制的每个循环。

  • 您的AudioBuffer和AudioBufferList没有正确设置,调音台的输出数据格式通常会将频道拆分为单独的AudioBuffer而不是交错。无论哪种方式,你没有分配足够的空间,你应该是calloc ing,而你正在分配样本大小的对象,而不是字节大小的对象。

AudioBufferList分配应该看起来更像这个(MixerHost年代后):

AudioBufferList *ioData = (AudioBufferList *) malloc (
     sizeof (AudioBufferList) + sizeof (AudioBuffer) * (channelCount - 1) 
    ); 


    ioData->mNumberBuffers = channelCount; 

    int i; 
    for (i = 0; i < channelCount; i++) { 
     ioData->mBuffers[i] = {0}; 
     ioData->mBuffers[i].mNumberChannels = 1; 
     ioData->mBuffers[i].mDataByteSize = BUFFER_SIZE_IN_SAMPLES * 
      sizeof (AudioUnitSampleType); 
     ioData->mBuffers[i].mData = calloc(BUFFER_SIZE_IN_SAMPLES, 
      sizeof(AudioUnitSampleType); 
    } 
+0

非常感谢您!你能告诉我哪里是反复调用AudioUnitRender的适当位置,我应该在新线程中调用它吗? – user2122490 2013-03-03 15:26:13

+0

你可以在这里或从一个新线程调用它,只是从不从两个不同的线程调用Render。你也可以考虑把它包装在一个AUGraph中,让它为你做所有的背景;你可以从*它的* render回调中获得AUGraph的输出。 – iluvcapra 2013-03-04 17:11:05

+0

我在考虑使用AUGraph,你的意思是使用AUGraphAddRenderNotify来获得AUGraph的输出吗?以及第一次调用Render的位置,因为我称之为AUGraphStart后没有任何反应。 – user2122490 2013-03-06 10:04:02