/******************************************/ /* Simple Voice Manager (Mangler) */ /* for ToolKit96, 1996 Perry R. Cook */ /* Princeton University */ /* */ /* Make one of these by telling it the */ /* maximum number of voices you'll want, */ /* and also what flavor instrument */ /* group it will be mangling. Pipe TSIDI*/ /* messages into it and it will return */ /* the mixed channel signal each tick. */ /* For multi-channel (multi-timbral), */ /* make one for each channel and mix */ /* their outputs. */ /* */ /* Each note on returns a unique tag, */ /* (credits to the NeXT MusicKit here), */ /* so you can send control changes to */ /* unique instances of instruments */ /* within an ensemble. */ /* */ /* TSIDI (ToolKit Synthesis Instrument */ /* Digital Interfaceis like MIDI, but */ /* allows for floating point control */ /* changes, note numbers, etc. Example: */ /* noteOn(1,60.01,111.132) plays a sharp */ /* middle C with a velocity of 111.132 */ /* */ /******************************************/ #include "VoicMang.h" #include "Marimba.h" #include "Vibraphn.h" #include "AgogoBel.h" #include "Plucked.h" #include "Mandolin.h" #include "Clarinet.h" #include "Flute.h" #include "Brass.h" #include "Bowed.h" #include "Rhodey.h" #include "Wurley.h" #include "TubeBell.h" #include "HeavyMtl.h" #include "PercFlut.h" #include "BeeThree.h" #include "Moog1.h" VoicMang :: VoicMang(int maxVoices, char *instrType) { int i; max_voices = maxVoices; if (max_voices > __VMang_MAX_) { printf("You ask for too many voices, setting to %i\n",__VMang_MAX_); max_voices = __VMang_MAX_; } if (!strcmp(instrType,"Marimba")) { for (i=0;inoteOn(temp,amp); } #define ONE_OVER_12 0.083333 long VoicMang :: noteOn(MY_FLOAT note_num, MY_FLOAT amp) { int i,gotOne; int temp1; long temp2; MY_FLOAT temp3,temp4; MY_FLOAT freq; freq = 220.0*pow(2.0,(note_num-57.0) * ONE_OVER_12); gotOne = 0; for (i=0;inoteOn(freq,amp*NORM_7); frequencies[i] = freq; gotOne = 1; i = max_voices; } } if (!gotOne) { /* if can't find a free one */ return -1; /* report back */ } return newTag-1; } long VoicMang :: oldestVoice() { int i; long temp,temp2,gotOne; temp = newTag; gotOne = -1; for (i=0;i 0 && temp2 < newTag) { temp = temp2; gotOne = temp2; } } return gotOne; } int VoicMang :: noteOffN(int note_num, MY_FLOAT amp) { int i,gotOne; MY_FLOAT temp; gotOne = -1; for (i=0;inoteOff(amp*NORM_7); voicesOn[i] = -mute_time; gotOne = 1; } } return gotOne; } void VoicMang :: noteOff(long tag, MY_FLOAT amp) { int i; for (i=0;inoteOff(amp*NORM_7); voicesOn[i] = -mute_time; } } } void VoicMang :: kill(long tag) { int i; for (i=0;inoteOff(1.0); voicesOn[i] = 0; notesOn[i] = -1; } } } void VoicMang :: pitchBend(MY_FLOAT value) { int i; pitch_bend = value; for (i=0;isetFreq(freqBases[i]*frequencies[i]); } } void VoicMang :: pitchBend(long tag, MY_FLOAT value) { int i; for (i=0;isetFreq(freqBases[i]*frequencies[i]); i = max_voices; } } } MY_FLOAT VoicMang :: tick() { int i,j; MY_FLOAT temp; temp = 0.0; for (i=0;itick(); } if (voicesOn[i] < 0) { voicesOn[i] += 1; if (voicesOn[i] == 0) { notesOn[i] = -1; frequencies[i] = 0.0; freqBases[i] = 1.0; } } } return temp; } void VoicMang :: controlChange(int number, MY_FLOAT value) { int i; for (i=0;icontrolChange(number,value); } } void VoicMang :: controlChange(long tag, int number, MY_FLOAT value) { int i; for (i=0;icontrolChange(number,value); i = max_voices; } } }