Re: multiple track synthesizer problem
Re: multiple track synthesizer problem
- Subject: Re: multiple track synthesizer problem
- From: Zak Stone <email@hidden>
- Date: Mon, 6 Jan 2003 15:33:23 -0500
Hello,
Has anyone gotten a multiple-track synthesizer to work using sampled
sounds? I still haven't gotten the modified version of AUViewTest below
to work properly, so I'm limited to using multiple MIDI channels in one
track to produce the correct output.
Thanks,
Zak
From: Zak Stone <email@hidden>
Date: Mon Dec 30, 2002 5:09:01 PM US/Eastern
To: email@hidden
Subject: Re: multiple track synthesizer problem
Thanks for the help! I've implemented multiple synth tracks in a
modified version of AUViewTest, but the sound the program produces
isn't correct. The program should load a custom SoundFont and play
three pairs of simultaneous notes, where each pair has one note on
instrument 1 and the other on instrument 2. The code below loads the
custom SoundFont from an FSSpec without a problem, but the first pair
of notes plays staggered incorrectly (though with each note on a
different instrument as desired). The notes in the second two pairs
play simultaneously, but both incorrectly use sounds from instrument
2. I don't think the custom SoundFont is causing a problem, though,
because I've implemented the same idea using separate MIDI channels in
a single track and the notes always play simultaneously on the correct
instruments. What's going wrong in this multiple track implementation?
These are the relevant functions I've changed in AUViewTest:
void AUViewTest::BuildGraph()
{
RequireNoErr(NewAUGraph(&mGraph));
// Two DLS synths -> mixer -> output
AUNode synthNode, synthNode2, mixerNode, outputNode;
ComponentDescription desc;
// create nodes
desc.componentType = kAudioUnitComponentType;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
// DLS MusicDevice
desc.componentSubType = kAudioUnitSubType_MusicDevice;
desc.componentManufacturer = kAudioUnitID_DLSSynth;
RequireNoErr(AUGraphNewNode(mGraph, &desc, 0, NULL, &synthNode));
RequireNoErr(AUGraphNewNode(mGraph, &desc, 0, NULL, &synthNode2));
//mixer
desc.componentSubType = kAudioUnitSubType_Mixer;
desc.componentManufacturer = kAudioUnitID_StereoMixer;
RequireNoErr(AUGraphNewNode(mGraph, &desc, 0, NULL,
&mixerNode));
// default output unit
desc.componentSubType = kAudioUnitSubType_Output;
desc.componentManufacturer = kAudioUnitID_DefaultOutput;
RequireNoErr(AUGraphNewNode(mGraph, &desc, 0, NULL, &outputNode));
// connect nodes, using synth output 1 since reverb will occupy
output 0 below
RequireNoErr(AUGraphConnectNodeInput(mGraph, synthNode, 1, mixerNode,
0 ));
RequireNoErr(AUGraphConnectNodeInput(mGraph, synthNode2, 1,
mixerNode, 1 ));
RequireNoErr(AUGraphConnectNodeInput(mGraph, mixerNode, 0,
outputNode, 0 ));
RequireNoErr(AUGraphOpen(mGraph));
RequireNoErr(AUGraphInitialize(mGraph));
AudioUnit theSynth, theSynth2, theMixer, theOutput;
RequireNoErr(AUGraphGetNodeInfo(mGraph, synthNode, NULL, NULL, NULL,
&theSynth));
RequireNoErr(AUGraphGetNodeInfo(mGraph, synthNode2, NULL,
NULL, NULL, &theSynth2));
RequireNoErr(AUGraphGetNodeInfo(mGraph, mixerNode, NULL, NULL,
NULL, &theMixer));
RequireNoErr(AUGraphGetNodeInfo(mGraph, outputNode, NULL, NULL, NULL,
&theOutput));
mSynth = theSynth;
mSynthNode = synthNode;
mSynthNode2 = synthNode2;
mMixerNode = mixerNode;
UInt32 reverb = 0;
// set both synth units to my custom soundbank
AudioUnitSetProperty(theSynth,
kMusicDeviceProperty_SoundBankFSSpec,
kAudioUnitScope_Global, 0, &fss, sizeof(FSSpec));
AudioUnitSetProperty(theSynth2,
kMusicDeviceProperty_SoundBankFSSpec,
kAudioUnitScope_Global, 0, &fss, sizeof(FSSpec));
// turn off internal reverb
AudioUnitSetProperty(theSynth,
kMusicDeviceProperty_UsesInternalReverb,
kAudioUnitScope_Global, 0, &reverb, sizeof(UInt32));
AudioUnitSetProperty(theSynth2,
kMusicDeviceProperty_UsesInternalReverb,
kAudioUnitScope_Global, 0, &reverb, sizeof(UInt32));
RequireNoErr(AUGraphStart(mGraph));
}
void AUViewTest::BuildSequence()
{
MusicSequence sequence;
MusicTrack instr1, instr2, tempoTrack;
MusicPlayer player;
Float64 beatsPerMinute = 80;
RequireNoErr(NewMusicSequence(&sequence));
RequireNoErr(MusicSequenceGetTempoTrack(sequence, &tempoTrack));
RequireNoErr(MusicTrackNewExtendedTempoEvent(tempoTrack, 0,
beatsPerMinute));
RequireNoErr(MusicSequenceNewTrack(sequence, &instr1));
RequireNoErr(MusicSequenceNewTrack(sequence, &instr2));
MusicTimeStamp t = 0;
MIDIChannelMessage chmsg;
// change to instrument index 0 (in my custom SoundFont)
chmsg.status = 0xC0;
chmsg.data1 = 0;
chmsg.data2 = 0;
chmsg.reserved = 0;
RequireNoErr(MusicTrackNewMIDIChannelEvent(instr1, t, &chmsg));
// change to instrument index 2
chmsg.status = 0xC0;
chmsg.data1 = 2;
chmsg.data2 = 0;
chmsg.reserved = 0;
RequireNoErr(MusicTrackNewMIDIChannelEvent(instr2, t, &chmsg));
float kDuration = 2.0, kInterval = 2.5;
int root = 60;
MIDINoteMessage msg;
msg.channel = 0;
msg.velocity = 96;
msg.reserved = 0;
msg.duration = kDuration;
msg.note = root;
RequireNoErr(MusicTrackNewMIDINoteEvent(instr1, t, &msg));
// sorry for the discordance, but I wanted to make sure all
notes were playing
msg.note = root + 2;
RequireNoErr(MusicTrackNewMIDINoteEvent(instr2, t, &msg));
t += kInterval;
msg.note = root + 3;
RequireNoErr(MusicTrackNewMIDINoteEvent(instr1, t, &msg));
msg.note = root + 5;
RequireNoErr(MusicTrackNewMIDINoteEvent(instr2, t, &msg));
t += kInterval;
msg.note = root;
RequireNoErr(MusicTrackNewMIDINoteEvent(instr1, t, &msg));
msg.note = root + 2;
RequireNoErr(MusicTrackNewMIDINoteEvent(instr2, t, &msg));
RequireNoErr(MusicSequenceSetAUGraph(sequence, mGraph));
RequireNoErr(MusicTrackSetDestNode(instr1, mSynthNode));
RequireNoErr(MusicTrackSetDestNode(instr2, mSynthNode2));
RequireNoErr(NewMusicPlayer(&player));
RequireNoErr(MusicPlayerSetSequence(player, sequence));
RequireNoErr(MusicPlayerPreroll(player));
RequireNoErr(MusicPlayerStart(player));
}
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.