To support noteUpdates, you merely supply a
noteUpdateSelf: method. It is up to
you what parameters you want to allow to change in a
noteUpdate. Example:
+ noteUpdateSelf: aNote
{
[OSC setFreq: [aNote freq]];
[OSC setAmp: [aNote parAsDouble: MK_amp]];
[OUT setBearing: [aNote parAsDouble: MK_bearing]];
return self;
}
|
To relax the restriction that all
MKNotes need to have every parameter
present, you can set the parameter in noteOnSelf: and noteUpdateSelf: only when it is
present, store its value in an instance variable, and set it
back to a default value in noteEnd.
E.g., if there is an instance variable
freq.
+ noteOnSelf: aNote
{
if ([aNote isParPresent: MK_freq])
freq = [aNote freq];
[OSC setFreq: freq];
. . .
}
+ noteEndSelf
{
freq = 440;
[OSC setAmp: 0.0];
return self;
}
|
To add an amplitude envelope, we need to use an
AsympUG MKUnitGenerator to
create the envelope, write it to a patch point and use an oscillator
that is capable of reading its amplitude from a patchpoint. The
OscgafiUG supports reading both its amplitude
and its frequency from a patchpoint. The C function
MKUpdateAsymp() makes it easy to apply an
envelope with AsympUG and supports attack and
release times, scaling values, and phrase transitions:
MKUpdateAsymp(
AsympUG *anAsymp, // asymp instance
MKEnvelope *ampEnv, // the envelope
double amp0, // value when env at 0
double amp1, // value when env at 1
double ampAtt, // attack time
double ampRel, // release time
double portamento, // transition time on rearticulation
MKPhraseStatus phraseStatus); // see below
|
Any argument may be omitted. For double arguments, omitting the
argument means supplying the special value
MK_NODVAL (which stands for “No Double
Value”).
Phrase status is obtained by sending [self phraseStatus];