This is Bark.m in view mode; [Download] [Up]
/* The following files must be imported. */ #ifndef UNITGENERATORS_H #define UNITGENERATORS_H #import <musickit/musickit.h> #import <musickit/unitgenerators/Add2UGxxx.h> #import <musickit/unitgenerators/Add2UGyyy.h> #import <musickit/unitgenerators/AsympUGy.h> #import <musickit/unitgenerators/DelayUGyxx.h> #import <musickit/unitgenerators/Mul2UGyyy.h> #import <musickit/unitgenerators/OscgUGyy.h> #import <musickit/unitgenerators/OscgafiUGxyyy.h> #import <musickit/unitgenerators/Out1aUGx.h> #import <musickit/unitgenerators/Out1bUGy.h> #define MK_OSCFREQSCALE 256.0 /* Used by Oscg and Oscgaf */ #endif UNITGENERATORS_H #import "Bark.h" @implementation Bark:SynthPatch { id LoochWave; } static int i = 0; /* A static integer is created for each synthElement. */ static int osc[2], /* wave UG */ ampEnvUG, /* amplitude envelope UG */ ampPatchpoint, /* amplitude patch point */ freqOscUG[2], /* frequency vibrato UG */ vibDeviateUG[2], /* base deviation of note */ vibMulUG[2], /* vibrato increment calculator */ vibMulIn1[2], /* vib oscil input patch point */ vibMulIn2[2], /* vib base input patch point */ vibBaseUG[2], /* base frequency of note */ freqEnvUG[2], /* frequency of note adder */ freqEnvIn1[2], /* freq adder input 1 */ freqEnvIn2[2], /* freq adder input 2 */ freqPatchpoint[2], /* frequency patch point */ oscOutPatchpoint[2], /* output of the two oscil chains */ oscSum, /* add the two oscil chains */ delayUG, /* digital delay unit generator */ delayIn, /* delay line input patch point */ delayOut, /* delay line output patch point */ stereoOutA, /* sound output UG for channel 0 */ stereoOutB, /* sound output UG for channel 1 */ outPatchpointA, /* SynthData */ outPatchpointB, /* SynthData -- whatever */ DelayLine; /* SynthData memory for delay */ + patchTemplateFor:aNote /* The argument is ignored in this implementation. */ { int DelayLength,j; /* Step 1: Create an instance of the PatchTemplate class. */ static id theTemplate = nil; // I took this out to give me four different templates for 4 delay lines // if (theTemplate) // return theTemplate; theTemplate = [PatchTemplate new]; /* Step 2: Add synthElement specifications to the PatchTemplate. */ ampEnvUG = [theTemplate addUnitGenerator:[AsympUGy class]]; for (j = 0; j < 2; j++) { vibBaseUG[j] = [theTemplate addUnitGenerator:[AsympUGy class]]; vibDeviateUG[j] = [theTemplate addUnitGenerator:[AsympUGy class]]; freqOscUG[j] = [theTemplate addUnitGenerator:[OscgUGyy class]]; vibMulUG[j] = [theTemplate addUnitGenerator:[Mul2UGyyy class]]; freqEnvUG[j] = [theTemplate addUnitGenerator:[Add2UGyyy class]]; osc[j] = [theTemplate addUnitGenerator:[OscgafiUGxyyy class]]; } oscSum = [theTemplate addUnitGenerator:[Add2UGxxx class]]; delayUG = [theTemplate addUnitGenerator:[DelayUGyxx class]]; stereoOutA = [theTemplate addUnitGenerator:[Out1aUGx class]]; stereoOutB = [theTemplate addUnitGenerator:[Out1bUGy class]]; switch(i) { case 0: DelayLength = 500; break; case 1: DelayLength = 85; break; case 2: DelayLength = 40; break; case 3: DelayLength = 5; break; default: fprintf(stderr,"DelayLength problems!\n"); DelayLength = 1; } DelayLine = [theTemplate addSynthData:MK_xData length:DelayLength]; ampPatchpoint = [theTemplate addPatchpoint:MK_yPatch]; for (j = 0; j < 2; j++) { vibMulIn1[j] = [theTemplate addPatchpoint:MK_yPatch]; vibMulIn2[j] = [theTemplate addPatchpoint:MK_yPatch]; freqEnvIn1[j] = [theTemplate addPatchpoint:MK_yPatch]; freqEnvIn2[j] = [theTemplate addPatchpoint:MK_yPatch]; freqPatchpoint[j] = [theTemplate addPatchpoint:MK_yPatch]; oscOutPatchpoint[j] = [theTemplate addPatchpoint:MK_xPatch]; } delayIn = [theTemplate addPatchpoint:MK_xPatch]; delayOut = [theTemplate addPatchpoint:MK_yPatch]; outPatchpointA = [theTemplate addPatchpoint:MK_xPatch]; outPatchpointB = [theTemplate addPatchpoint:MK_yPatch]; /* Step 3: Specify the connections between synthElements. */ [theTemplate to:ampEnvUG sel:@selector(setOutput:) arg:ampPatchpoint]; for (j = 0; j < 2; j++) { [theTemplate to:freqOscUG[j] sel:@selector(setOutput:) arg:vibMulIn1[j]]; [theTemplate to:vibDeviateUG[j] sel:@selector(setOutput:) arg:vibMulIn2[j]]; [theTemplate to:vibMulUG[j] sel:@selector(setInput1:) arg:vibMulIn1[j]]; [theTemplate to:vibMulUG[j] sel:@selector(setInput2:) arg:vibMulIn2[j]]; [theTemplate to:vibMulUG[j] sel:@selector(setOutput:) arg:freqEnvIn1[j]]; [theTemplate to:vibBaseUG[j] sel:@selector(setOutput:) arg:freqEnvIn2[j]]; [theTemplate to:freqEnvUG[j] sel:@selector(setInput1:) arg:freqEnvIn1[j]]; [theTemplate to:freqEnvUG[j] sel:@selector(setInput2:) arg:freqEnvIn2[j]]; [theTemplate to:freqEnvUG[j] sel:@selector(setOutput:) arg:freqPatchpoint[j]]; [theTemplate to:osc[j] sel:@selector(setAmpInput:) arg:ampPatchpoint]; [theTemplate to:osc[j] sel:@selector(setIncInput:) arg:freqPatchpoint[j]]; [theTemplate to:osc[j] sel:@selector(setOutput:) arg:oscOutPatchpoint[j]]; } [theTemplate to:oscSum sel:@selector(setInput1:) arg:oscOutPatchpoint[0]]; [theTemplate to:oscSum sel:@selector(setInput2:) arg:oscOutPatchpoint[1]]; [theTemplate to:oscSum sel:@selector(setOutput:) arg:outPatchpointA]; [theTemplate to:stereoOutA sel:@selector(setInput:) arg:outPatchpointA]; [theTemplate to:delayUG sel:@selector(setInput:) arg:outPatchpointA]; [theTemplate to:delayUG sel:@selector(setOutput:) arg:outPatchpointB]; [theTemplate to:stereoOutB sel:@selector(setInput:) arg:outPatchpointB]; [theTemplate to:delayUG sel:@selector(setDelayMemory:) arg:DelayLine]; /* Always return the PatchTemplate. */ return theTemplate; } - applyParameters:aNote /* This is a private method to the Envy class. It is used internally only. */ { /* Retrieve and store the parameters. */ double myFreq0 = [aNote parAsDouble:MK_freq0]; double myFreq1 = [aNote parAsDouble:MK_freq1]; double FreqInc; double myAmp = [aNote parAsDouble:MK_amp]; // double myBearing = [aNote parAsDouble:MK_bearing]; double myVibFreq0 = [aNote parAsDouble:MK_svibFreq]; double myVibAmp0 = [aNote parAsDouble:MK_svibAmp]; double myVibFreq1 = [aNote parAsDouble:MK_rvibFreq]; double myVibAmp1 = [aNote parAsDouble:MK_rvibAmp]; double FreqIncHi; LoochWave = [aNote parAsWaveTable:MK_waveform]; /* set wavetable if present */ if (LoochWave != nil) { [[self synthElementAt:osc[0]] setTable:LoochWave length:64 defaultToSineROM:YES]; [[self synthElementAt:osc[1]] setTable:LoochWave length:64 defaultToSineROM:YES]; } /* Apply frequency if present. */ if (myFreq0 != MAXDOUBLE) { FreqInc = [[self synthElementAt:osc[0]] incAtFreq:myFreq0]; [[self synthElementAt:vibBaseUG[0]] setConstant:FreqInc]; } if (myFreq1 != MAXDOUBLE) { FreqInc = [[self synthElementAt:osc[1]] incAtFreq:myFreq1]; [[self synthElementAt:vibBaseUG[1]] setConstant:FreqInc]; } /* Apply vibrato freq if present */ if (myVibFreq0 != MAXDOUBLE) { [[self synthElementAt:freqOscUG[0]] setFreq:myVibFreq0]; } if (myVibFreq1 != MAXDOUBLE) { [[self synthElementAt:freqOscUG[1]] setFreq:myVibFreq1]; } /* Apply vibrato amplitude if present (amp in Hz) */ if (myVibAmp0 != MAXDOUBLE) { FreqInc = [[self synthElementAt:osc[0]] incAtFreq:myFreq0]; FreqIncHi = [[self synthElementAt:osc[0]] incAtFreq:(myFreq0+myVibAmp0)]; [[self synthElementAt:vibDeviateUG[0]] setConstant:(FreqIncHi-FreqInc)]; } if (myVibAmp1 != MAXDOUBLE) { FreqInc = [[self synthElementAt:osc[1]] incAtFreq:myFreq1]; FreqIncHi = [[self synthElementAt:osc[1]] incAtFreq:(myFreq1+myVibAmp1)]; [[self synthElementAt:vibDeviateUG[1]] setConstant:(FreqIncHi-FreqInc)]; } /* Apply amplitude if present. */ if (myAmp != MAXDOUBLE) [[self synthElementAt:ampEnvUG] setTarget:myAmp]; // /* Apply bearing if present. */ // if (myBearing != MAXDOUBLE) // [[self synthElementAt:stereoOut] setBearing:myBearing]; } - noteOnSelf:aNote { /* Step 1: Read the parameters in the Note and apply them to the patch. */ [self applyParameters:aNote]; [[self synthElementAt:ampEnvUG] setCurVal:0.0]; [[self synthElementAt:ampEnvUG] setT60:[aNote parAsDouble:MK_ampAtt]]; /* Step 2: Turn on the patch by connecting the Out2sumUGx object to the patchpoint and sending the run message to all the synthElements. */ [[self synthElementAt:stereoOutA] setInput:[self synthElementAt:outPatchpointA]]; [[self synthElementAt:stereoOutB] setInput:[self synthElementAt:outPatchpointB]]; [synthElements makeObjectsPerform:@selector(run)]; return self; } - noteUpdateSelf:aNote { [self applyParameters:aNote]; return self; } - (double)noteOffSelf:aNote { [self applyParameters:aNote]; [[self synthElementAt:ampEnvUG] setTarget:0.0]; [[self synthElementAt:ampEnvUG] setT60:[aNote parAsDouble:MK_ampRel]]; return 0.0; } - noteEndSelf { /* Deactivate the SynthPatch by idling the output. */ [[self synthElementAt:stereoOutA] idle]; [[self synthElementAt:stereoOutB] idle]; return self; } - initialize { /* Initialize is automatically sent once when an instance is created, after it's patch has been loaded. */ [[self synthElementAt:osc[0]] setTable:nil defaultToSineROM:YES]; /* full output for vibrato */ [[self synthElementAt:freqOscUG[0]] setAmp:1.0]; [[self synthElementAt:osc[1]] setTable:nil defaultToSineROM:YES]; /* full output for vibrato */ [[self synthElementAt:freqOscUG[1]] setAmp:1.0]; return self; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.