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
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?