首页 > 解决方案 > Core Audio MIDI Synth AU & MusicPlayer - Cannot be pulled by AudioUnitRender programmatically

问题描述

I have an AUGraph with AudioUnits. My MIDI Synth AudioUnit was created by this:

    AudioComponentDescription midiSynthDesc;
    midiSynthDesc.componentType = kAudioUnitType_MusicDevice;
    midiSynthDesc.componentSubType = kAudioUnitSubType_MIDISynth;

Then I load the SF2 File into the MIDI AudioUnit:

    NSURL *bankURL = [[NSBundle mainBundle] URLForResource:@"Combined" withExtension:@"sf2"];
    AudioUnitSetProperty(midiSynthUnit,
                         kMusicDeviceProperty_SoundBankURL,
                         kAudioUnitScope_Global,
                         0,
                         &bankURL,
                         sizeof(bankURL));

I have this SF2 loaded MIDI-Synth AudioUnit connected to Remote-IO AudioUnit, then I added MusicPlayer to this AUGraph to play:

    MusicPlayerSetSequence(musicPlayer, musicSequence);
    NewMusicSequence(&musicSequence);
    MusicSequenceFileLoad(musicSequence, (__bridge CFURLRef)midiFileURL, 0, 0)
    MusicSequenceSetAUGraph(musicSequence, processingGraph);
    MusicPlayerPreroll(musicPlayer);
    MusicPlayerStart(musicPlayer);

And it works with the Remote-IO, I can hear the MIDI file playing.

However, if I pull the MIDI Synth Audio Unit programmatically, trying to render the MIDI File into Raw Audio Data and then write into m4a file:

    OSStatus err = noErr;
    err = AudioUnitRender(midiSynthUnit, &flags, &inTimeStamp, busNumber, numberFrames, bufferList);

No audio data can be read ( bufferList's mData == 0 Always). No matter how many times I call AudioUnitRender, MusicPlayerGetTime always tells me that the current beat of the Music Player is 0:

    Float64 currentBeat;
    MusicPlayerGetTime(musicPlayer, &currentBeat);

Can anybody tell me why? Any suggestion how to read the MIDI File with SF2 soundfont file and convert into raw audio data / render MIDI into m4a file?

Thanks

标签: core-audiomidiaudiounitcoremidisoundfont

解决方案


我没有对此进行测试,但也许您可以尝试另一个 SO question & answer 作为灵感。

无论如何,我对 AudioToolbox 的 MusicPlayer 的了解是它只能实时工作。如果 MIDI 序列长度为两分钟,则渲染音频文件至少需要两分钟。如果您更喜欢批处理,其中渲染速度仅受系统速度、CPU、内存和 IO 的限制,那么我建议您使用FLuidSynth 之类的替代方案


推荐阅读