AsympenvUG Class Reference

AsympenvUG is similar to AsympUG, except that it loads the entire envelope down to the DSP, providing better real-time performance. More...

#import <AsympenvUG.h>

Inheritance diagram for AsympenvUG:

MKUnitGenerator

List of all members.

Public Member Functions

(id) - setOutput:
 Sets the output patchpoint to aPatchPoint.
(id) - setTargetVal:
 Sets the target to target, which should be between 0.0 and 1.0.
(id) - setCurVal:
 Sets the current value of the AsympenvUG to value.
(id) - setRate:
 Sets the rate at which the AsympenvUG approaches its target, where rate is the percentage of the remaining journey that's stepped off at each sample.
(id) - setT60:
 Computes the AsympUG's rate such that the target is perceptually reached (to within -60dB of the target) in seconds seconds.
(id) - preemptEnvelope
 Causes the AsympenvUG to head for the last breakpoint in its MKEnvelope, using a rate that's computed from the value set through the MKSetPreemptDuration() function (the default preempt duration is 0.006 seconds).
(id) - setEnvelope:yScale:yOffset:xScale:releaseXScale:funcPtr:
 Associates the AsympenvUG with the given MKEnvelope and arguments.
(id) - resetEnvelope:yScale:yOffset:xScale:releaseXScale:funcPtr:transitionTime:
 This method is similar to the setEnvelope:... method but for this difference: If the AsympenvUG is running, its current value isn't reset to the new MKEnvelope's first y value; instead, the new MKEnvelope's first breakpoint is ignored and the Asymp's rate is reset such that it proceeds toward the second breakpoint.
(id) - useInitialValue:
 Controls how the MKEnvelope is handled when it is "retriggered" (i.e. run is invoked before the preceeding MKEnvelope has finished).
(id) - setYScale:yOffset:
 Has no effect.
(id) - setReleaseXScale:
 Has no effect.
(id) - envelope
 Returns the MKEnvelope that's associated with the AsympenvUG, or nil if none.
(id) - runSelf
 You never send this message.
(id) - idleSelf
 You never send this message.
(double) - finishSelf
 You never invoke this method; it's invoked automatically when the AsympenvUG receives the finish message.
(id) - abortEnvelope
 Disassociates the AsympenvUG from its MKEnvelope.
(id) - setConstant:
 Aborts any running MKEnvelope and sets the AsympenvUG to produce val as a constant value.
(void) - MKUpdateAsymp
 Apply an Envelope on the DSP.

Static Public Member Functions

(BOOL) + shouldOptimize:
 Specifies that all arguments are to be optimized if possible except the state variable.


Detailed Description

AsympenvUG is similar to AsympUG, except that it loads the entire envelope down to the DSP, providing better real-time performance.

AsympenvUG is an MKEnvelope handler that plays a MusicKit MKEnvelope on the DSP. It is very similar to AsympUG and has almost the same Objective C protocol. However, unlike AsympUG, which feeds the MKEnvelope to the DSP one segment at a time, AsympenvUG loads the entire MKEnvelope (actually, tables derived from the MKEnvelope data) into DSP memory. This means AsympenvUG is more well-suited to critical interactive real-time applications, such as playing a MIDI keyboard and hearing sound immediately. It also means that there is a limit to the length of the envelopes it can handle, since there is a limited amount of DSP memory. In practice, envelopes are not usually very long, so this restriction is usually not a problem. In short, it is usually best to use AsympenvUG if critical interactive real-time is a concern, but AsympUG is better for situations with very long MKEnvelopes or where real-time response is not an issue.

AsympenvUG objects are normally used to provide dynamic scaling of a musical attribute. To this end, the output of an AsympenvUG is typically connected to the frequency or amplitude input of an OscgafiUG object or used as input to an InterpUG, Mul2UG, ScaleUG, etc. Although typically used to convey Envelopes, AsympUG may also be used as a simple exponential ramper, without an explicit MKEnvelope object. Methods are provided that let you set the rate directly, or as a time limit (referred to as “T60”) that defines when the target will have been perceptually reached.

For each MKEnvelope segment, AsympenvUG creates an exponential signal that approaches a limit (the “target”) at a particular rate, where the rate expresses the precentage of the remaining journey that's taken with each step:

output = previousOutput + (rate * (target - previousOutput)) previousOutput = output

For example, if the rate is 0.1 and the target is 1.0, the samples generated by the AsympUG are

0.1, 0.19, 0.271, 0.343, 0.409, 0.4685, ...

Exponential envelopes have the advantage of being "self-limiting". That is, they seek their targets from any starting point. This allows for efficient implementation of long connected MKEnvelope "phrases", one of the primary advantages of the MusicKit's MKNote representation. In addition, if, for some reason, the host processor gets a little bit behind, due to time-sharing, the envelope will not continue unbounded toward disaster.

MKEnvelope data is mapped onto the exponential representation as follows:

The MKEnvelope's yArray[n] is the target, considered to be in the infinite future. The MKEnvelope's xArray[n] is the time of the right-hand side of the segment (i.e. the time to interrupt the trajectory toward yArray[n]). The MKEnvelope's smoothingArra[n] is the smoothing constant to get to yArray[n]. If smoothingArra[n] is 0, the point is reached immediately. If smoothingArra[n] is 1.0, the point is reached, within about -48dB at the time of the next update. If smoothingArra[n] is larger, the point is not reached within -48dB by the time of the next update. A value of smoothingArra[n] of infinity will cause the envelope to never change value. The first point, xArray[0], is assumed to be the right-hand side of the non-existant first segment. yArray[0] is the initial point (which may or may not be used, depending on the value of the instance variable useInitialvalue (see below)). smoothingArra[0] is ignored.

The envelope has a "stick point". When the envelope handler reaches the stick point, it does not proceed to the next point until it receives the -finish message. If there is no stick point, the -finish message is ignored. If the envelope handler has not yet reached the stick point when the -finish message is received, the envelope handler proceeds to the first point after the stick point and continues from there.

MusicKit MKEnvelopes are usually associated with a set of parameters, such as attackTime, releaseTime, etc. The C function MKUpdateAsymp (AsympenvUG) is provided to conveniently manage setting the AsympUG's attributes according to a given MKEnvelope and a set of MKNote parameters. By using MKUpdateAsymp (AsympenvUG), you need only set the AsympenvUG's output patchpoint; all other methods are invoked for you. For more information, see the Class Description for the MKEnvelope class.

As with AsympUG, you should not change the contents of a MusicKit MKEnvelope object while an AsympenvUG is using it. Furthermore, MKEnvelope data is cached on the DSP and referenced using the MKEnvelope object id for speed and efficiency. This has the advantage of allowing several AsympenvUGs to share MKEnvelope data and avoids wasting DSP memory. However, this also implies that if you change the data in an MKEnvelope object, these changes may not take effect, because the MusicKit continues to use the old representation. Therefore, if you do change an MKEnvelope's data, you should send the message +envelopeHasChanged:, passing the MKEnvelope object as the argument. Also, you should not free any MKEnvelope objects that have been used in a MusicKit performance until the MKOrchestra has been closed. Otherwise, a re-used id may cause the AsympenvUG to use an incorrect cached MKEnvelope.

There are a few other differences between AsympUG and AsympenvUG:

Memory Spaces

AsympenvUGa a output


Member Function Documentation

- (id) setOutput: (id)  aPatchPoint  

Sets the output patchpoint to aPatchPoint.

Parameters:
aPatchPoint is an id.
Returns:
Returns self, or nil if the argument isn't a patchpoint.

- (id) setTargetVal: (double)  target  

Sets the target to target, which should be between 0.0 and 1.0.

The new target is simply inserted, overriding the current target. If the object is already processing an envelope, that envelope is not interrupted.

Parameters:
target is a double.
Returns:
Returns self.

- (id) setCurVal: (double)  value  

Sets the current value of the AsympenvUG to value.

The new value overrides the previous sample as shown in the computation in the class description above. If the object is already processing an envelope, that envelope is not interrupted.

Parameters:
value is a double.
Returns:
Returns self.

- (id) setRate: (double)  rate  

Sets the rate at which the AsympenvUG approaches its target, where rate is the percentage of the remaining journey that's stepped off at each sample.

The value of rate, which should be between 0.0 and 0.125. (It should be between 0.0 and 1.0, but for historical reasons the outer limit stands at 0.125. In any case, a rate of 0.125 means that the target is virtually reached in less than two ticks, which is quite fast). More precisely, this method sets the rate of the exponential. (1-e^T/tau), where T is sampling period and tau is the time constant.If the AsympenvUG is already processing an MKEnvelope, the new rate is simply inserted, overriding the current value, and the MKEnvelope proceeds otherwise unaffected.

Parameters:
rate is a double.
Returns:
Returns self.
See also:
-- setT60:

- (id) setT60: (double)  seconds  

Computes the AsympUG's rate such that the target is perceptually reached (to within -60dB of the target) in seconds seconds.

Parameters:
seconds is a double.
Returns:
Returns self.
See also:
-- setRate:

- (id) preemptEnvelope  

Causes the AsympenvUG to head for the last breakpoint in its MKEnvelope, using a rate that's computed from the value set through the MKSetPreemptDuration() function (the default preempt duration is 0.006 seconds).

This method is invoked automatically by a MKSynthInstrument object when it preempts a MKSynthPatch that contains AsympenvUG objects.

Returns:
Returns an id.

- (id) setEnvelope: (id)  anEnvelope
yScale: (double)  yScaleValue
yOffset: (double)  yOffsetValue
xScale: (double)  xScaleValue
releaseXScale: (double)  releaseXScaleValue 

Associates the AsympenvUG with the given MKEnvelope and arguments.

When the AsympenvUG is run, it automatically schedules the breakpoints from its MKEnvelope to be fed to itself through message requests with the clockConductor. If this method is invoked while the AsympenvUG is running, the object's current value is immediately set to the (scaled and offset) y value of the first breakpoint in the new MKEnvelope. When continuity is desired with the previous invocation, use the resetEnvelope:... method instead.

The yScaleValue and yOffsetValue arguments scale and offset the AsympenvUG target values as each breakpoint is reached; xScaleValue and releaseXScaleValue modify the rate before and after the MKEnvelope's stickpoint is reached, respectively.

The yScaleFunction argument is a pointer to an optional function that performs additional, possibly dynamic, target scaling. The fuction takes two arguments, a double that gives the AsympenvUG's current value, and the object's id. The function is called once for each breakpoint.

Typically, you call the MKUpdateAsymp function rather than invoking this method. The function provides a slightly easier interface to AsympenvUG management in the context of a MKSynthPatch.

Parameters:
anEnvelope is an id.
yScaleValue is a double.
yOffsetValue is a double.
xScaleValue is a double.
releaseXScaleValue is a double.
yScaleFunction is a pointer to a function returning a double (double(*)()).
Returns:
Returns an id.

- (id) resetEnvelope: (id)  anEnvelope
yScale: (double)  yScaleValue
yOffset: (double)  yOffsetValue
xScale: (double)  xScaleValue
releaseXScale: (double)  releaseXScaleValue 

This method is similar to the setEnvelope:... method but for this difference: If the AsympenvUG is running, its current value isn't reset to the new MKEnvelope's first y value; instead, the new MKEnvelope's first breakpoint is ignored and the Asymp's rate is reset such that it proceeds toward the second breakpoint.

This affords are more graceful transition into the new MKEnvelope. transitionTimeis currently ignored. As with the setEnvelope:... method, you typically call the MKUpdateAsymp function rather than invoke this method.

Parameters:
anEnvelope is an id.
yScaleValue is a double.
yOffsetValue is a double.
xScaleValue is a double.
releaseXScaleValue is a double.
yScaleFunction is a pointer to a function returning a double.
transitionTime is a double.
Returns:
Returns an id.

- (id) useInitialValue: (BOOL)  yesOrNo  

Controls how the MKEnvelope is handled when it is "retriggered" (i.e. run is invoked before the preceeding MKEnvelope has finished).

Parameters:
yesOrNo is a BOOL.
Returns:
Returns an id. If yesOrNo, the first value of the MKEnvelope is set as the AsympenvUG's first output. Otherwise, the AsympenvUG continues from whatever its current value happens to be to the second point of the MKEnvelope. This method is rarely needed, since the same functionality is provided by resetEnvelope:yScale:yOffset:xScale:releaseXScale:funcPtr:transitionTime:. It is included as an optimization, when it is known that all parameters are the same.

- (id) setYScale: (double)  yScaleValue
yOffset: (double)  yOffsetValue 

Has no effect.

Implemented for compatibility with AsympUG.

Parameters:
yScaleValue is a double.
yOffsetValue is a double.
Returns:
Returns self.

- (id) setReleaseXScale: (double)  releaseXScaleValue  

Has no effect.

Implemented for compatability with AsympUG.

Parameters:
releaseXScaleValue is a double.
Returns:
Returns self.

- (id) envelope  

Returns the MKEnvelope that's associated with the AsympenvUG, or nil if none.

Returns:
Returns an id.

- (id) runSelf  

You never send this message.

It's invoked by sending the run message to the object. Starts the MKEnvelope, if any, on its way.

Returns:
Returns self.

Reimplemented from MKUnitGenerator.

- (id) idleSelf  

You never send this message.

It's invoked by sending the idlemessage to the object. Sets the output patchpoint to sink, thus ensuring that the object does not produce any output. Note that you must send setOutput: and run again to use the MKUnitGenerator after sending idle.

Returns:
Returns an id.

Reimplemented from MKUnitGenerator.

- (double) finishSelf  

You never invoke this method; it's invoked automatically when the AsympenvUG receives the finish message.

Returns:
Returns a double. If the object has yet to see or is waiting at its MKEnvelope's stickpoint, this causes it to head for the first breakpoint after the stickpoint, and then on the end of the MKEnvelope. If the AsympenvUG's MKEnvelope contains no stickpoint, this method has no effect. Returns the time in seconds until the MKEnvelope is expected to finish, plus a small grace time given by MKGetPreemptDuration(). This time may be changed by calling MKSetPreemptDuration().

Reimplemented from MKUnitGenerator.

+ (BOOL) shouldOptimize: (unsigned)  arg  

Specifies that all arguments are to be optimized if possible except the state variable.

Parameters:
arg is an unsigned.
Returns:
Returns an BOOL.

Reimplemented from MKUnitGenerator.

- (id) abortEnvelope  

Disassociates the AsympenvUG from its MKEnvelope.

The MKEnvelope sticks on its current value.

Returns:
Returns self.

- (id) setConstant: (double)  val  

Aborts any running MKEnvelope and sets the AsympenvUG to produce val as a constant value.

Equivalent to invoking abortEnvelope, followed by setTarget:val, followed by setCurVal:val.

Parameters:
val is a double.
Returns:
Returns an id.

- (void) MKUpdateAsymp (id)  asymp
(id)  envelope
(double)  valueAt0
(double)  valueAt1
(double)  attackDur
(double)  releaseDur
(double)  portamentoTime
(MKPhraseStatus status 

Apply an Envelope on the DSP.

This is a fairly complicated function that, simply put, does the “right thing” in applying an MKEnvelope object to a DSP-synthesized musical attribute during a Music Kit performance. It's designed to be called as part of the implementation of a MKSynthPatch subclass.

The asymp argument is an AsympUG object that will handle the MKEnvelope on the DSP; envelope is the MKEnvelope object itself. The arguments valueAt0, valueAt1, attackDur, and releaseDur scale and stretch the MKEnvelope; their values are expected to be taken from an associated group of MKNote parameters. For example, to apply an MKEnvelope to the frequency of a synthesized MKNote, the values of these arguments would be retrieved as follows:

MKEnvelope *envelope = [aNote parAsEnvelope:MK_freqEnv]; double valueAt0 = [aNote parAsDouble:MK_freq0]; double valueAt1 = [aNote parAsDouble:MK_freq1]; double attackDur = [aNote parAsDouble:MK_freqAtt]; double releaseDur = [aNote parAsDouble:MK_freqRel];

The portamentoTime argument is taken as the MKNote's MK_portamentoTime value. As the name implies, it sets the portamento or “slur” between MKNotes and is only applied if the MKNote to which the MKEnvelope belongs is a noteOn that's interrupting an existing MKNote. If the note is a MKNoteUpdate, the value is changed abruptly.

The final argument, status, is used to distinguish the state of the MKSynthPatch at the time that the envelope is applied. You retrieve the phrase status through MKSynthPatch's phraseStatus method. The use of portamento, for example, is determined by the value of this argument.

The asymp and status arguments are essential; the parameter-valued arguments aren't. The function tries to be intelligent with regard to missing parameter-valued arguments; if, for example, envelope is nil, the value of valueAt1 is applied as a constant. .

MKUpdateAsymp handles all the MKEnvelope breakpoint scheduling - keep in mind that the breakpoint data in an MKEnvelope object isn't transferred to the DSP as a unit but, instead, the breakpoints are fed to the DSP through message requests scheduled with a MKConductor. The function always schedules MKEnvelope breakpoint messages with the clockConductor.

Parameters:
asymp is a AsympUG instance.
envelope is an MKEnvelope instance.
valueAt0 is a double.
valueAt1 is a double.
attackDur is a double.
releaseDur is a double.
portamentoTime is a double.
status is a MKPhraseStatus.
Returns:
Returns a void.


The documentation for this class was generated from the following file:

Generated on Sat Dec 5 17:01:14 2009 for MusicKit by  doxygen 1.5.6