ios - mixing midi files, each with own sound font

后端 未结 3 1353
半阙折子戏
半阙折子戏 2021-01-01 05:12

I\'m looking for a way to mix 2 or more midi files, each with their own sound font files. I\'ve found the following code for one file and tried to do multiple music players

3条回答
  •  北海茫月
    2021-01-01 05:41

    So i tried setting the nodes for each track, but that didn't change anything. The soundfont gets only set for the first samplerUnit. Here's how i set up the graph:

    AudioComponentDescription MixerUnitDescription;
    MixerUnitDescription.componentType          = kAudioUnitType_Mixer;
    MixerUnitDescription.componentSubType       = kAudioUnitSubType_MultiChannelMixer;
    MixerUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
    MixerUnitDescription.componentFlags         = 0;
    MixerUnitDescription.componentFlagsMask     = 0;
    
    AudioComponentDescription cd = {};
    cd.componentManufacturer     = kAudioUnitManufacturer_Apple;
    cd.componentType = kAudioUnitType_MusicDevice; // type - music device
    cd.componentSubType = kAudioUnitSubType_Sampler; // sub type - sampler to convert our MIDI
    
    result = NewAUGraph (&_processingGraph);
    result = AUGraphAddNode(self.processingGraph, &MixerUnitDescription, &mixerNode);
    
    result = AUGraphAddNode (self.processingGraph, &cd, &samplerNode);
    
    result = AUGraphAddNode (self.processingGraph, &cd, &samplerNode2);
    
    cd.componentType = kAudioUnitType_Output;  // Output
    cd.componentSubType = kAudioUnitSubType_RemoteIO;  // Output to speakers
    
    result = AUGraphAddNode (self.processingGraph, &cd, &ioNode);
    result = AUGraphOpen (self.processingGraph);
    
    result = AUGraphConnectNodeInput (self.processingGraph, samplerNode, 0, mixerNode, 0);
    result = AUGraphConnectNodeInput (self.processingGraph, samplerNode2, 0, mixerNode, 1);
    
    result = AUGraphConnectNodeInput (self.processingGraph, mixerNode, 0, ioNode, 0);
    result = AUGraphNodeInfo (self.processingGraph, samplerNode, 0, &_samplerUnit);
    result = AUGraphNodeInfo (self.processingGraph, samplerNode2, 0, &_samplerUnit2);
    result = AUGraphNodeInfo (self.processingGraph, ioNode, 0, &_ioUnit);
    

    This is the example method from Apple Developer pages which i modified to assign a soundfont to a specific samplerUnit:

    -(OSStatus) loadFromDLSOrSoundFont: (NSURL *)bankURL withPatch: (int)presetNumber withAudioUnit:(AudioUnit)auUnit{
    
    OSStatus result = noErr;
    
    // fill out a bank preset data structure
    AUSamplerBankPresetData bpdata;
    bpdata.bankURL  = (__bridge CFURLRef) bankURL;
    bpdata.bankMSB  = kAUSampler_DefaultMelodicBankMSB;
    bpdata.bankLSB  = kAUSampler_DefaultBankLSB;
    bpdata.presetID = (UInt8) presetNumber;
    
    // set the kAUSamplerProperty_LoadPresetFromBank property
    result = AudioUnitSetProperty(auUnit,
                              kAUSamplerProperty_LoadPresetFromBank,
                              kAudioUnitScope_Global,
                              0,
                              &bpdata,
                              sizeof(bpdata));
    
    // check for errors
    NSCAssert (result == noErr,
           @"Unable to set the preset property on the Sampler. Error code:%d '%.4s'",
           (int) result,
           (const char *)&result);
    
    return result;
    }
    

    Then i did this twice to get each track into musicSequence:

    if(MusicSequenceFileLoad(tmpSequence, (__bridge CFURLRef)midiFileURL, 0, 0 != noErr)) 
    {
        [NSException raise:@"play" format:@"Can't load MusicSequence"];
    }
    
    
    MusicSequenceGetIndTrack(tmpSequence, 0, &tmpTrack);
    MusicSequenceNewTrack(musicSequence, &track);
    MusicTimeStamp trackLen = 0;
    UInt32 trackLenLen = sizeof(trackLen);
    MusicTrackGetProperty(tmpTrack, kSequenceTrackProperty_TrackLength, &trackLen, &trackLenLen);
    MusicTrackCopyInsert(tmpTrack, 0, trackLenLen, track, 0);
    

    And finally:

    MusicTrackSetDestNode(track, samplerNode);
    MusicTrackSetDestNode(track2, samplerNode2);
    

    But this won't assign the the soundfont to the samplerUnit2:

    [self loadFromDLSOrSoundFont: (NSURL *)presetURL2 withPatch: (int)0 withAudioUnit:self.samplerUnit2];
    

    Assigning to samplerUnit works fine. Any ideas what i'm missing here?

提交回复
热议问题