2015-04-07 20 views
0

我想脱机弹出一个MIDI文件,并且正如PlaySequence示例所做的那样,我正试图理解它。
我一直在不停地阅读,你需要一个回调函数在CoreAudio中做任何事情,但我在这个项目中看不到任何东西。
我粘贴包含AudioUnitRender的循环,感谢您的帮助!Apple的PlaySequence项目中的回调函数在哪里?

CAStreamBasicDescription clientFormat = CAStreamBasicDescription(); 
    size = sizeof(clientFormat); 
    FailIf ((result = AudioUnitGetProperty (outputUnit, 
               kAudioUnitProperty_StreamFormat, 
               kAudioUnitScope_Output, 0, 
               &clientFormat, &size)), fail, "AudioUnitGetProperty: kAudioUnitProperty_StreamFormat"); 
    size = sizeof(clientFormat); 
    FailIf ((result = ExtAudioFileSetProperty(outfile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat)), fail, "ExtAudioFileSetProperty: kExtAudioFileProperty_ClientDataFormat"); 

    { 
     MusicTimeStamp currentTime; 
     AUOutputBL outputBuffer (clientFormat, numFrames); 
     AudioTimeStamp tStamp; 
     memset (&tStamp, 0, sizeof(AudioTimeStamp)); 
     tStamp.mFlags = kAudioTimeStampSampleTimeValid; 
     int i = 0; 
     int numTimesFor10Secs = (int)(10./(numFrames/srate)); 
     do { 
      outputBuffer.Prepare(); 
      AudioUnitRenderActionFlags actionFlags = 0; 
      FailIf ((result = AudioUnitRender (outputUnit, &actionFlags, &tStamp, 0, numFrames, outputBuffer.ABL())), fail, "AudioUnitRender"); 

      tStamp.mSampleTime += numFrames; 

      FailIf ((result = ExtAudioFileWrite(outfile, numFrames, outputBuffer.ABL())), fail, "ExtAudioFileWrite"); 

      FailIf ((result = MusicPlayerGetTime (player, &currentTime)), fail, "MusicPlayerGetTime"); 
      if (shouldPrint && (++i % numTimesFor10Secs == 0)) 
       printf ("current time: %6.2f beats\n", currentTime); 
     } while (currentTime < sequenceLength); 
    } 

回答

1

我看了一下项目,你说得对,它没有rendercallback。渲染回调的地方是coreaudio audiounit effect processing。设置渲染调用回调看起来是这样的:

inline OSStatus  SetInputCallback (CAAudioUnit &inUnit, AURenderCallbackStruct &inInputCallback) 
{ 
    return inUnit.SetProperty (kAudioUnitProperty_SetRenderCallback, 
              kAudioUnitScope_Input, 
              0, 
              &inInputCallback, 
              sizeof(inInputCallback)); 
} 

但是这个代码只是一个大main()其中设置了序列,augraph,音乐播放器,然后在情况下,FileWriter的WriteOutputFile有一个OUTPUTFILE反弹至。

我建议你在关键方法中设置一些断点,然后遍历代码,看看它做什么并查看变量。

编辑:请注意,您在设置上的iOS rendercallback您RemoteIO(兼作输入&输出单元),获得在正确的范围&总线单元号正确的流格式在你的setProperty通话可能会非常棘手。请参阅Apple文档中的这一部分。

enter image description here

+0

谢谢ruoho。实际上,我正在使用此代码进行更为激进的“分析”,因为我将它移植到iPhone和Swift中。我已经成功设置了图形(我可以听一个正在播放的MIDI文件),但是在弹奏MIDI文件到音频文件时,我仍然遇到麻烦。一切似乎都很好,但循环无法拉取数据:MusicTimeStamp始终为0.0 – popisar

+0

好的,此代码抓取AUGraph的输出单元(kAudioUnitType_Output),并且呈现调用将样本写入到写入磁盘的缓冲区。在iOS上,RemoteIO是您的“输出单元”,RemoteIO上的rendercall(注意正确的总线= 0)会为您提供可写入磁盘的示例。有关更多详细信息,请参阅:http://stackoverflow.com/questions/8951458/how-to-write-output-of-augraph-to-a-file http://stackoverflow.com/questions/6930609/write-audio -to-disk-from-io-unit –

+0

我已经知道你给我的第一个链接,但是谁知道为什么,当你指出它时,我从另一个角度看到了它。我被AudioBufferList注意力分散了,所以我没有注意到我的ASBD是一团糟(多个,“获得”而不是“设置”......你的名字)。如果我得到它,你需要一个ASBD,你必须手动将它应用到你图中的每个单元。没有一种“反向传播”:如果我将ASBD分配给输出节点,这不会自动扩展到上游节点(在我的情况下是混音器和合成器),对吧? – popisar

相关问题