MusicKit  0.0.0
AsympUG.h
00001 /*
00002   $Id$
00003   
00004   Defined In: The MusicKit
00005   Description:
00006     Add2UG  - from dsp macro /usr/lib/dsp/ugsrc/add2.asm (see source for details).
00007     Outputs the sum of two input signals. 
00008 
00009   Original Author: David A. Jaffe
00010 
00011   Copyright (c) 1988-1992, NeXT Computer, Inc.
00012   Portions Copyright (c) 1994 NeXT Computer, Inc. and reproduced under license from NeXT
00013   Portions Copyright (c) 1994 Stanford University.
00014   Portions Copyright (c) 1999-2001, The MusicKit Project.
00015 */
00016 /* 
00017         How Envelopes Are Used in the MusicKit SynthPatch Library 
00018 
00019 In the MusicKit SynthPatch library, envelopes are specified in the
00020 parameter list as some combination of an MKEnvelope object (a list of
00021 time, value, and optional smoothing values), up to two value-modifying
00022 numbers, and up to two time-scaling numbers.  See
00023 <MKUnitGenerators/AsympUG.h> for details about the smoothing values in
00024 an MKEnvelope.  The parameter names all begin with something descriptive
00025 of their use, such as "amp" or "freq".  The MKEnvelope parameter has the
00026 suffix "Env", e.g., "freqEnv".  The value-modifying parameters have
00027 the suffixes "0" and "1", e.g., "freq0" and "freq1". The time-scaling
00028 parameters have the suffixes "Att" and "Rel", e.g., "freqAtt" and
00029 "freqRel".  In addition, just the descriptive part of the name may be
00030 substituted for the "1"-suffix parameter, e.g. "freq" = "freq1".
00031 
00032         The MKEnvelope and Value-modifying Parameters
00033 
00034 The synthpatches have been designed to allow several alternative ways
00035 to use Envelopes, depending on the precise combination of these three
00036 parameters. In the following paragraphs, the term "val0" stands for
00037 any "0"-suffix numeric parameter, "val1" stands for any "1"-suffix
00038 numeric parameter, "valAtt" stands for any "Att"-suffix parameter, and
00039 "valRel" stands for any "Rel"-suffix parameter.
00040 
00041 If no MKEnvelope is supplied, the desired value is specified in the
00042 "val" field, (e.g. "freq") and the result is this value applied as a
00043 constant. If an MKEnvelope is supplied but no "val0" or "val1" numbers
00044 (e.g. "freqEnv" is supplied, but no "freq0" nor "freq1"), the MKEnvelope
00045 values are used directly.  If only an MKEnvelope and "val0" are supplied,
00046 the Envelope's y values are used after being added to "val0".  If only
00047 an MKEnvelope and "val1" are supplied, the Envelope's y values are used
00048 after being multipled by "val1".  If an MKEnvelope and both "val0" and "val1"
00049 are supplied, the values used are "val0" plus the difference of "val1" and
00050 "val0" multiplied by the MKEnvelope values.  In other words, the MKEnvelope
00051 specifies the interpolation between the two numeric values.  "Val0"
00052 specifies the value when the MKEnvelope is 0, and "val1" specifies the
00053 value when the MKEnvelope is 1.
00054 
00055 In mathematical terms, the formula for an MKEnvelope parameter val is then:
00056       
00057     DSP Value(t) = val0 + (val1 - val0) * valEnv(t)
00058        
00059 where "val0" defaults to 0, "val1" defaults to 1, and "valEnv" defaults to a
00060 constant value of 1 when only "val1" is supplied, and 0 otherwise.
00061 
00062         The MKEnvelope and Time-scaling Parameters
00063 
00064 The "valAtt" and "valDec" numeric parameters directly affect the
00065 "attack" and "decay" portions of an envelope, which are considered to
00066 be the portions before and after the stickpoint, respectively.  When
00067 supplied, the relevant portion of the envelope is scaled so that the
00068 total time of that portion is the time specified in the parameter in
00069 seconds.  For example, if valAtt is set to .5, the segments of the
00070 portion of the envelope before the stick point will be proportionally
00071 scaled so that the total time is .5 seconds.  The smoothing values are
00072 also scaled proportionally so that the behavior of time-scaled
00073 envelopes remains consistent.
00074 
00075 ValAtt can only be set when an envelope is also supplied in the same note.
00076 However, valDec may be set independently, e.g., in a noteOff where an
00077 envelope was supplied in the preceeding noteOn.
00078 
00079         Phrases 
00080 
00081 The MusicKit supports continuity between notes in a phrase.  When two
00082 notes are part of the same phrase (they have the same time tag) or a
00083 sounding note is updated by a noteUpdate, the envelope of the latter
00084 note does not simply interrupt that of the earlier note.  Rather, the
00085 first point of the latter envelope is ignored, and the envelope
00086 proceeds directly to the second point, starting from wherever the
00087 earlier envelope happens to be when the new noteOn occurs.  The time
00088 it takes to do this is, by default, the time of the first segment of
00089 the latter envelope, possibly affected by its "valAtt" parameter.
00090 However, the "portamento" parameter may be used to specify the time
00091 (in seconds) for the transition should take.  All of the x (time)
00092 values of the envelope, except the first, are increased by the amount
00093 needed to make the first segment take the desired amount of time. In
00094 addition, the smoothing value for the first segment is adjusted
00095 appropriately. 
00096 
00097 The single "portamento" parameter affects all envelopes which the synthpatch
00098 may be using.
00099 
00100 MKUpdateAsymp() may be called with any of its arguments of type double 
00101 "unset". "unset" is indicated by the value MAXDOUBLE. 
00102 
00103 Caveat concerning FM:
00104   With the current (2.0) implementation of the FM family of MKSynthPatches, the
00105   amount of modulation (peak frequency deviation) is computed from freq1.
00106   That means that if you use the convention of putting the frequencies in the
00107   envelope itself and setting freq1 to 1, the index values will have to be 
00108   boosted by the fundamental frequency. 
00109 */
00110 // classgroup Envelope Handlers and Followers
00206 #ifndef __MK_AsympUG_H___
00207 #define __MK_AsympUG_H___
00208 
00209 #import <MusicKit/MusicKit.h>
00210 
00211 @interface AsympUG: MKUnitGenerator
00212 {
00213     id anEnv;
00214     double (*scalingFunc)();
00215     int envelopeStatus;           
00216     int arrivalStatus;            
00217     double timeScale;             
00218     double releaseTimeScale;      
00219     double yScale;                
00220     double yOffset;               
00221     double targetX;               
00222     char useInitialValue;         
00223     int curPt;                    
00224     double _reservedAsymp1;
00225     MKMsgStruct * _reservedAsymp2;
00226     double _reservedAsymp3;
00227     double _reservedAsymp4;
00228     double _reservedAsymp5;
00229     double _reservedAsymp6;
00230     double _reservedAsymp7;
00231     DSPDatum _reservedAsymp8;
00232 }
00233 
00246 - (MKEnvStatus) envelopeStatus;
00247 
00253 - setOutput: (id) aPatchPoint;
00254 
00264 - setTargetVal: (double) target;
00265 
00275 - setCurVal: (double) value;
00276 
00295 - setRate: (double) rate;
00296 
00304 - setT60: (double) seconds;
00305 
00315 - setT48: (double) seconds;
00316 
00327 - preemptEnvelope;
00328 
00364 - setEnvelope: (id) anEnvelope
00365        yScale: (double) yScaleValue
00366       yOffset: (double) yOffsetValue
00367        xScale: (double) xScaleValue
00368 releaseXScale: (double) releaseXScaleValue
00369       funcPtr: (double (*)()) yScaleFunction;
00370       
00393 -resetEnvelope: (id) anEnvelope
00394         yScale: (double) yScaleValue
00395        yOffset: (double) yOffsetValue
00396         xScale: (double) xScaleValue
00397  releaseXScale: (double) releaseXScaleValue
00398        funcPtr: (double (*)()) yScaleFunction
00399 transitionTime: (double) transitionTime;
00400 
00413 - useInitialValue: (BOOL) yesOrNo;
00414 
00423 - setYScale: (double) yScaleValue yOffset: (double) yOffsetValue;
00424 
00435 - setReleaseXScale: (double) releaseXScaleValue;
00436 
00441 - envelope;
00442 
00450 - runSelf;
00451 
00452 - abortSelf;
00453 
00464 - idleSelf;
00465 
00479 - (double) finishSelf;
00480 
00486 + (BOOL) shouldOptimize: (unsigned) arg;
00487 
00495 - abortEnvelope;
00496 
00506 - setConstant: (double) aVal;
00507 
00508 extern id MKAsympUGxClass(void);
00509 extern id MKAsympUGyClass(void);
00510 extern void MKUpdateAsymp(id asymp, id envelope, double val0, double val1,
00511                 double attDur, double relDur, double portamentoTime,
00512                 MKPhraseStatus status);
00513 
00514 @end
00515 
00516 #endif