2015-04-07 18 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

相關問題