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.