#import <MKUnitGenerator.h>
Public Member Functions | |
(id) | - moved |
You never invoke this method. | |
(id) | - init |
Invoke this method when the receiver is is created, after its code is loaded. | |
(id) | - run |
Starts the receiver by sending [self runSelf] and then sets its status to MK_running. | |
(id) | - runSelf |
Subclass implementation of this method provides instructions for making the object's DSP code usable (as defined by the subclass). | |
(double) | - finish |
Finishes the receiver's activity by sending finishSelf and then sets its status to MK_finishing. | |
(double) | - finishSelf |
A subclass may override this method to provide instructions for finishing. | |
(id) | - idle |
Idles the receiver by sending [self idleSelf] and then sets its status to MK_idle. | |
(id) | - idleSelf |
A subclass may override this method to provide instructions for idling. | |
(int) | - status |
Returns the receiver's status, one of MK_idle, MK_running, and MK_finishing. | |
(MKOrchMemStruct *) | - relocation |
Returns a pointer to the structure that describes the receiver's location on the DSP. | |
(BOOL) | - runsAfter: |
Returns YES if the receiver is executed after aUnitGenerator. | |
(unsigned int) | - argCount |
Returns the number of memory arguments in the receiver's DSP code. | |
(MKLeafUGStruct *) | - classInfo |
Returns a pointer to the receiver's leaf structure. | |
(MKOrchMemStruct *) | - resources |
Return a pointer to the structure that describes the receiver's memory requirements. | |
(id) | - orchestra |
Returns the receiver's MKOrchestra object. | |
(BOOL) | - isFreeable |
Invoked by the MKOrchestra to determine whether the receiver may be freed. | |
(id) | - synthPatch |
Returns the MKSynthPatch that the receiver is part of, if any. | |
(BOOL) | - isAllocated |
Returns YES if the receiver has been allocated (by its MKOrchestra), NO if it hasn't. | |
(id) | - setDatumArg:to: |
Sets the datum-valued argument argNum to val. | |
(id) | - setDatumArg:toLong: |
Sets the datum-valued argument argNum to val. | |
(id) | - setAddressArg:to: |
Sets the addresst-valued argument argNum to memoryObj. | |
(id) | - setAddressArg:toInt: |
Sets the addresst-valued argument argNum to address. | |
(id) | - setAddressArgToSink: |
Sets the address-valued argument argNum to the sink patchpoint. | |
(id) | - setAddressArgToZero: |
Sets the address-valued argument argNum to a zero patchpoint. | |
(id) | - freeSelf |
You never invoke this method directly, it's invoked from free. | |
(int) | - referenceCount |
If this object is installed in its MKOrchestra's shared table, returns the number of objects that have allocated it. | |
(id) | - MKSetUGDatumArg |
Set DSP unit generator arguments. | |
(id) | - MKSetUGDatumArgLong |
Set DSP unit generator arguments. | |
(id) | - MKSetUGAddressArg |
Set DSP unit generator arguments. | |
(id) | - MKSetUGAddressArgToInt |
Set DSP unit generator arguments. | |
(id) | - writeSymbolsToStream: |
Writes the MKUnitGenerator as a portion of a DSP .lod file. | |
(int) | - instanceNumber |
Returns a low integer that uniquely identifies this MKUnitGenerator. | |
Static Public Member Functions | |
(MKMasterUGStruct *) | + masterUGPtr |
Returns the receiver's master structure. | |
(MKLeafUGStruct *) | + classInfo |
Returns the receiver's leaf structure. | |
(unsigned int) | + argCount |
Returns the number of memory arguments in the receiver's DSP code. | |
(BOOL) | + shouldOptimize: |
A subclass can override this method to reduce the command stream on an argument-by-argument basis, returning YES if arg should be optimized, NO if it shouldn't. | |
(NSString *) | + argName: |
Returns the name of the receiver's argNum'th DSP code argument, as declared in the DSP unit generator source code. | |
(id) | + orchestraClass |
This method always returns the MKOrchestra class. | |
(DSPMemorySpace) | + argSpace: |
Returns the memory space to or from which the address-valued argument argNum reads or writes. | |
(id) | + enableErrorChecking: |
Sets whether various error checks are done, such as verifying that MKUnitGenerator arguments and MKSynthData memory spaces are correct. |
Each MKUnitGenerator subclass represents a modular DSP program (a unit generator) that provides a particular synthesis operation, such as waveform generation, filtering, and mixing. Sound is synthesized by downloading unit generators to the DSP, interconnecting them, and making them run.
To download a copy of a particular unit generator to the DSP, you send the allocUnitGenerator: message to an open MKOrchestra object, passing the class of the MKUnitGenerator that represents the unit generator. For example, to download a copy of the unoise unit generator (which generates white noise), you allocate an instance of the UnoiseUG class:
// Create an MKOrchestra and a variable for the MKUnitGenerator.
MKOrchestra *anOrch = [MKOrchestra new]; id aNoise; // Open the MKOrchestra; check for failure. if (![anOrch open]) . . .
// The MKUnitGenerator object is created at the same time that the // unit generator program is download to the DSP.
aNoise = [anOrch allocateUnitGenerator: [UnoiseUGx class]];
Notice that the receiver of the class message in the final line of the example is UnoiseUGx. The “x” is explained later in this class description.
To connect two MKUnitGenerators together, you allocate a patchpoint through which they can communicate. A patchpoint is a type of MKSynthData object that's designed to be used for just this purpose, to communicate data from the output of one MKUnitGenerator to the input of another. For example, to connect our UnoiseUGx object to a sound-output MKUnitGenerator, such as Out1aUGx, a patchpoint must be allocated and then passed as the argument in an invocation of UnoiseUGx's setOutput: method and Out1aUGx's setInput: method. But in order to do this, you have to understand a little bit about DSP memory spaces:
The DSP's memory is divided into three sections, P, X, and Y: P memory holds program data; X and Y contain data. Unit generator programs are always downloaded to P memory; the memory represented by a MKSynthData object is allocated in either X or Y, as the argument to MKOrchestra's allocSynthData: method is MK_xData or MK_yData. In general, there's no difference between the two data memory spaces (the one difference is mentioned below); dividing data memory into two partitions allows the DSP to be used more efficiently (although it presents some complications to the programmer, which you're living through right now). Most of the methods defined in the MKUnitGenerator class are subclass responsiblities or are provided to help define the functionality of a subclass. The most important of these are runSelf, idleSelf, and finishSelf. These methods implement the behavior of the object in response to the run, finish, and idle messages, respectively.
In addition to implementing the subclass responsibility methods, you should also provide methods for poking values into the memory arguments of the DSP unit generator that the MKUnitGenerator represents. For example, an oscillator MKUnitGenerator would provide a setFreq: method to set the frequency of the unit generator that's running on the DSP.
MKUnitGenerator subclasses are created from DSP macro code. The utility dspwrap turns a DSP macro into a MKUnitGenerator master class, implementing some of the subclass responsibility methods.
It also creates a number of classes that inherit from your MKUnitGenerator subclass; these are called leaf classes. A leaf class represents a specific memory space configuration on the DSP. For example, OnePoleUG is a one-pole filter MKUnitGenerator master class provided by the Music Kit. It has an input and an output argument that refer to either the x or the y memory spaces on the DSP. To provide for all memory space configurations, dspwrap creates the leaf classes OnePoleUGxx, OnePoleUGxy, OnePoleUGyx, and OnePoleUGyy.
You can modify a master class - for example, the setFreq: method mentioned above would be implemented in a master class - but you never create an instance of one. MKUnitGenerator objects are always instances of leaf classes.
+ (MKMasterUGStruct *) masterUGPtr |
Returns the receiver's master structure.
A subclass responsibility, this method is automatically generated by dspwrap.
+ (MKLeafUGStruct *) classInfo |
Returns the receiver's leaf structure.
A subclass responsibility, this method is automatically generated by dspwrap.
+ (unsigned int) argCount |
Returns the number of memory arguments in the receiver's DSP code.
- (id) moved |
You never invoke this method.
It's invoked by the MKOrchestra if it had to move the receiver during compaction. A subclass can override this method to perform special behavior. The default does nothing. The return value is ignored.
+ (BOOL) shouldOptimize: | (unsigned) | arg |
A subclass can override this method to reduce the command stream on an argument-by-argument basis, returning YES if arg should be optimized, NO if it shouldn't.
The default implementation always returns NO.
Optimization of means that if the argument it's set to the same value twice, the second setting is supressed. You should never optimize an argument that the receiver's DSP code itself might change.
Argument optimization applies to the entire class - all instances of the MKUnitGenerators leaf classes inherit an argument's optimization - and it can't be changed during a performance.
arg | is an unsigned. |
Reimplemented in AsympenvUG, AsympUG, BiquadUG, DelayqpUG, DelayUG, In1aUG, In1bUG, OscgafUGs, OscgUG, Out1aUG, Out1bUG, Out1nUG, Out2sumUG, and TablookiUG.
- (id) init |
Invoke this method when the receiver is is created, after its code is loaded.
If this method returns nil, the receiver is automatically freed by the MKOrchestra. A subclass implementation should send [super init] before doing its own initialization and should immediately return nil if [super init] returns nil. The default implementation returns self.
Reimplemented in EnvFollowUG, and In1qpUG.
- (id) run |
Starts the receiver by sending [self runSelf] and then sets its status to MK_running.
You never subclass this method; runSelf provides subclass runtime instructions. A MKUnitGenerator must be sent run before it can be used.
- (id) runSelf |
Subclass implementation of this method provides instructions for making the object's DSP code usable (as defined by the subclass).
You never invoke this method directly, it's invoked automatically by the run method. The default does nothing and returns the receiver.
Reimplemented in AsympenvUG, AsympUG, DelayqpUG, DelayUG, EnvFollowUG, In1aUG, In1bUG, In1qpUG, OscgafUGs, OscgUG, Out1aUG, Out1bUG, Out1nUG, and Out2sumUG.
- (double) finish |
Finishes the receiver's activity by sending finishSelf and then sets its status to MK_finishing.
You never subclass this method; finishSelf provides subclass finishing instructions. Returns the value of [self finishSelf], which is taken as the amount of time, in seconds, before the receiver can be idled.
- (double) finishSelf |
A subclass may override this method to provide instructions for finishing.
Returns the amount of time needed to finish; The default returns 0.0.
Reimplemented in AsympenvUG, and AsympUG.
- (id) idle |
Idles the receiver by sending [self idleSelf] and then sets its status to MK_idle.
You never subclass this method; idleSelf provides subclass idle instructions. The idle state is defined as the MKUnitGenerator's producing no output.
- (id) idleSelf |
A subclass may override this method to provide instructions for idling.
The default does nothing and returns the receiver. Most MKUnitGenerator subclasses implement idleSelf to patch their outputs to sink, a location that, by convention, nobody reads. MKUnitGenerators that have inputs, such as Out2sumUG, implement idleSelf to patch their inputs to zero, a location that always holds the value 0.0.
Reimplemented in AsympenvUG, AsympUG, DelayqpUG, DelayUG, EnvFollowUG, In1qpUG, OscgafUGs, OscgUG, Out2sumUG, and TablookiUG.
- (int) status |
Returns the receiver's status, one of MK_idle, MK_running, and MK_finishing.
- (MKOrchMemStruct *) relocation |
Returns a pointer to the structure that describes the receiver's location on the DSP.
You can access the fields of the structure without caching it first, for example:
[aUnitGenerator relocation]->pLoop
returns the starting location of the receiver's pLoop code.
- (BOOL) runsAfter: | (MKUnitGenerator *) | aUnitGenerator |
Returns YES if the receiver is executed after aUnitGenerator.
Execution order is determined by comparing the objects' pLoop addresses.
aUnitGenerator | is an id. |
- (unsigned int) argCount |
Returns the number of memory arguments in the receiver's DSP code.
The same value is returned by the argCount class method.
- (MKLeafUGStruct *) classInfo |
Returns a pointer to the receiver's leaf structure.
The same structure pointer is returned by the classInfo class method.
- (MKOrchMemStruct *) resources |
Return a pointer to the structure that describes the receiver's memory requirements.
Each field of the structure represents a particular MKOrchestra memory segment; its value represents the number of words that the segment requires.
+ (NSString *) argName: | (unsigned) | argNum |
Returns the name of the receiver's argNum'th DSP code argument, as declared in the DSP unit generator source code.
The name isn't copied.
argNum | is an unsigned. |
+ (id) orchestraClass |
This method always returns the MKOrchestra class.
It's provided for applications that extend the MusicKit to use other synthesis hardware. If you're using more than one type of hardware, you should create a subclass of MKUnitGenerator for each. The default hardware is that represented by MKOrchestra, the DSP56001.
- (id) orchestra |
- (BOOL) isFreeable |
Invoked by the MKOrchestra to determine whether the receiver may be freed.
Returns YES if it can, NO if it can't. (A MKUnitGenerator can be freed if it isn't currently allocated or its MKSynthPatch can be freed).
- (id) synthPatch |
- (BOOL) isAllocated |
Returns YES if the receiver has been allocated (by its MKOrchestra), NO if it hasn't.
- (id) setDatumArg: | (unsigned) | argNum | ||
to: | (DSPDatum) | val | ||
Sets the datum-valued argument argNum to val.
If argNum is an L-space argument (two 24-bit words), its high-order word is set to val and its low-order word is cleared. If argNum (as an index) is out of bounds, an error is generated and nil is returned. Otherwise returns the receiver. This is ordinarily invoked by a subclass.
argNum | is an unsigned. | |
val | is a DSPDatum. |
- (id) setDatumArg: | (unsigned) | argNum | ||
toLong: | (DSPLongDatum *) | val | ||
Sets the datum-valued argument argNum to val.
If argNum isn't an L-space argument (it can't accommodate a 48-bit value) its value is set to the high 24-bits of val. If argNum (as an index) is out of bounds, an error is generated and nil is returned. Otherwise returns the receiver. This is ordinarily only invoked by a subclass.
argNum | is an unsigned. | |
val | is a DSPLongDatum *. |
- (id) setAddressArg: | (unsigned) | argNum | ||
to: | (id) | memoryObj | ||
Sets the addresst-valued argument argNum to memoryObj.
If argNum (as an index) is out of bounds, an error is generated and nil is returned. Otherwise returns the receiver. This is ordinarily only invoked by a subclass.
argNum | is an unsigned. | |
memoryObj | is an id. |
- (id) setAddressArg: | (unsigned) | argNum | ||
toInt: | (DSPAddress) | address | ||
Sets the addresst-valued argument argNum to address.
If argNum (as an index) is out of bounds, an error is generated and nil is returned. Otherwise returns the receiver. This is ordinarily only invoked by a subclass.
argNum | is an unsigned. | |
address | is a DSPAddress. |
- (id) setAddressArgToSink: | (unsigned) | argNum |
Sets the address-valued argument argNum to the sink patchpoint.
(Sink is a location which, by convention, is never read.) If argNum (as an index) is out of bounds, an error is generated and nil is returned. Otherwise returns the receiver. This is ordinarily only invoked by a subclass.
argNum | is an unsigned. |
- (id) setAddressArgToZero: | (unsigned) | argNum |
Sets the address-valued argument argNum to a zero patchpoint.
(A zero patchpoint is a location with a constant 0 value; by convention the patchpoint is never written to.) If argNum (as an index) is out of bounds, an error is generated and nil is returned. Otherwise returns the receiver. This is ordinarily only invoked by a subclass.
argNum | is an unsigned. |
+ (DSPMemorySpace) argSpace: | (unsigned) | argNum |
Returns the memory space to or from which the address-valued argument argNum reads or writes.
If argNum isn't an address-valued argument, returns DSP_MS_N.
argNum | is an unsigned. |
- (id) freeSelf |
You never invoke this method directly, it's invoked from free.
A subclass may implement this method to provide specialized behavor before the object is freed. For example, you might want to release locally-allocated MKSynthData.
+ (id) enableErrorChecking: | (BOOL) | yesOrNo |
Sets whether various error checks are done, such as verifying that MKUnitGenerator arguments and MKSynthData memory spaces are correct.
The default is NO. You should send enableErrorChecking:YES when you are debugging MKUnitGenerators or MKSynthPatches, then disable it when your application is finished.
yesOrNo | is a BOOL. |
- (int) referenceCount |
If this object is installed in its MKOrchestra's shared table, returns the number of objects that have allocated it.
Otherwise returns 1 if it is allocated, 0 if it is not.
- (id) MKSetUGDatumArg | (MKUnitGenerator *) | ug | ||
(unsigned) | argNum | |||
(DSPDatum) | value | |||
Set DSP unit generator arguments.
These functions let you set the value of a DSP unit generator argument; they can only be called as part of the implementation of a MKUnitGenerator subclass. The arguments to all four functions are similar:
MKSetUGDatumArg and MKSetUGDatumArgLong set data-valued unit generator arguments. The former takes a DSPDatum (int) directly and sets the unit generator argument to the rightmost 24 bits of this value. The latter is used to set 48-bit DSP values; it takes, as the value argument, a pointer to a DSPLongDatum value. DSPLongDatum is defined as a DSPFix48 structure:
typedef struct _DSPFix48 { int high24; // High order 24 bits, right justified int low24; // Low order 24 bits, right justified } DSPFix48;
If the argument identifed by argNum isn't allocated in the DSP's long memory, then only the high24 field of the structure is taken as the value .
ug | is a MKUnitGenerator instance. | |
argNum | is an unsigned. | |
value | is a DSPDatum. |
- (id) MKSetUGDatumArgLong | (MKUnitGenerator *) | ug | ||
(unsigned) | argNum | |||
(DSPLongDatum *) | value | |||
Set DSP unit generator arguments.
These functions let you set the value of a DSP unit generator argument; they can only be called as part of the implementation of a MKUnitGenerator subclass. The arguments to all four functions are similar:
MKSetUGDatumArg and MKSetUGDatumArgLong set data-valued unit generator arguments. The former takes a DSPDatum (int) directly and sets the unit generator argument to the rightmost 24 bits of this value. The latter is used to set 48-bit DSP values; it takes, as the value argument, a pointer to a DSPLongDatum value. DSPLongDatum is defined as a DSPFix48 structure:
typedef struct _DSPFix48 { int high24; // High order 24 bits, right justified int low24; // Low order 24 bits, right justified } DSPFix48;
If the argument identifed by argNum isn't allocated in the DSP's long memory, then only the high24 field of the structure is taken as the value .
ug | is a MKUnitGenerator instance. | |
argNum | is an unsigned. | |
value | is a DSPLongDatum *. |
- (id) MKSetUGAddressArg | (MKUnitGenerator *) | ug | ||
(unsigned) | argNum | |||
(id) | memoryObj | |||
Set DSP unit generator arguments.
These functions let you set the value of a DSP unit generator argument; they can only be called as part of the implementation of a MKUnitGenerator subclass. The arguments to all four functions are similar:
MKSetUGAddressArg and MKSetUGAddressArgToInt are used to set address-valued unit generator arguments. The former sets the argument to the DSP address of obj, which must be a SynthData object. The latter function sets it directly as the value of its address argument. The DSPAddress data type is defined as an int.
If the argument identifed by argNum isn't allocated in the DSP's long memory, then only the high24 field of the structure is taken as the value .
ug | is a MKUnitGenerator instance. | |
argNum | is an unsigned. | |
memoryObj | is an MKSynthData. |
- (id) MKSetUGAddressArgToInt | (MKUnitGenerator *) | ug | ||
(unsigned) | argNum | |||
(DSPAddress) | address | |||
Set DSP unit generator arguments.
These functions let you set the value of a DSP unit generator argument; they can only be called as part of the implementation of a MKUnitGenerator subclass. The arguments to all four functions are similar:
MKSetUGAddressArg and MKSetUGAddressArgToInt are used to set address-valued unit generator arguments. The former sets the argument to the DSP address of obj, which must be a SynthData object. The latter function sets it directly as the value of its address argument. The DSPAddress data type is defined as an int.
If the argument identifed by argNum isn't allocated in the DSP's long memory, then only the high24 field of the structure is taken as the value .
ug | is a MKUnitGenerator instance. | |
argNum | is an unsigned. | |
address | is a DSPAddress. |
- (id) writeSymbolsToStream: | (NSMutableData *) | s |
Writes the MKUnitGenerator as a portion of a DSP .lod file.
You normally don't invoked this method. It's invoked by MKOrchestra's writeSymbolTable:.
s | is a NSMutableData. |
- (int) instanceNumber |
Returns a low integer that uniquely identifies this MKUnitGenerator.
This integer is unique for the duration of the execution of the program, unlike object id values, which may be reassigned after an object is freed.