...
Each audio module has an associated header file ModClassName.h containing a class definition, and a source file ModClassName.c containing the associated class structure and functions. The header and source files are generated by MATLAB, but it is important to understand their contents and how all of the pieces fit together.
Data types and Structure Definitions
Let's begin by looking at the class definition for the smoothly varying scaler found in ModScalerSmoothedExample.h:
...
Framework.h contains the primary data types and definitions used by Audio Weaver. Most of the definitions are used internally by the Server, but a few apply to audio modules.
Module Instance Structure
Following the instance header are all of the module specific variables. Only 8 types of module variables are currently supported:
...
ClassModule_GetWires(S) — returns a pointer to the array of wires associated with the module. The wires are ordered as input wires, output wires, and then scratch wires.
ClassModule_GetNInWires(S) — returns the number of input wires.
ClassModule_GetNOutWires(S) — returns the number of output wires
ClassModule_GetNScratchWires(S) — returns the number of scratch wires
ClassModule_GetModuleState(S) — returns the module's run-time state. ACTIVE=0, BYPASSED=1, MUTED=2, and INACTIVE=3.
Pins and Wires
A wire in Audio Weaver contains more than just audio samples. A wire is defined as:
...
You'll note that the pin descriptor does not specify the type of data (float, int, or fract32) contained in the wire. This allows a wire containing floating-point data to be reused for integer data as long as the number of channels, block size, and sample rate are identical.
Examples
The absolute value module has a single input and output pin, and can handle an arbitrary number of channels, block size, and sample rate. S is a pointer to the module instance. The processing code is:
...
Both of the module examples use a set of "vector" functions to perform the actual computation. It is possible to perform the computation within the module's processing function – many modules do this. For some modules, however, we have chosen to use vector functions since smaller functions may be more easily optimized in assembly and a single function may be reused by multiple modules. For example, Vec_Scale() is used by the scaler_module.m, scalern_module.m, and scaler_db_module.m. Thus, by optimizing a single function vector for a target processor we obtain 3 optimized modules.
Class Object and Constructor Functions
The module constructor function is called in response to a create_module command sent from the Server to the target. A module's constructor function is called once per module instance and is responsible for allocating memory for the module and copying arguments from the create_module command into the instance structure.
...
The Biquad module was used as an example to illustrate the constructor function because it requires an array to be allocated. If the Constructor function pointer in the module's class structure is set to NULL, then the generic module constructor is called. The generic constructor simply calls BaseClassModule_Constructor()
and is sufficient for modules that do not require additional memory allocation outside of the instance structure or other custom initialization. The generic constructor is sufficient for a large number of modules and reduces the code size of the target executable.
Memory Allocation using awe_fwMalloc()
Dynamic memory allocation is accomplished in Audio Weaver by the function awe_fwMalloc(). To avoid memory fragmentation, memory can only be allocated but never individually freed. You can only free all memory completely using the destroy command and then start again.
...
Most modules supplied with Audio Weaver take advantage of this overflow behavior to smoothly transition from internal to external memory once the heaps have filled up.
Module Function Details
Anchor | ||||
---|---|---|---|---|
|
Each audio module has a set of 5 functions associated with it. This section describes the arguments to each of the functions.
Constructor Function
Anchor | ||||
---|---|---|---|---|
|
This function is usually generated by MATLAB but at times it needs to be hand written – especially if the module does more than just allocate memory. Audio Weaver names the constructor function using the convention
...
Info |
---|
There is no need to manually call the Set function within the Constructor. The framework takes care of this. |
Processing Function
Anchor | ||||
---|---|---|---|---|
|
The processing function has the signature
...
The processing function does not return an error code. If you need to track error conditions, do this by adding an error code to the instance structure and then tracking it in the inspector.
Set Function
Anchor | ||||
---|---|---|---|---|
|
This function implements a module's control functionality and typically converts high-level variables to low-level variables. The PeakHold module has the function signature
...
A few more things to keep in mind regarding masks. When an array variable is set, the bit mask corresponding to the array is set as expected. However, the Set function is not told which portion of the array has been changed. Finally, since the mask is only 32 bits in length, it is possible to run out of unique bits if the instance structure is very long. The high bit of the mask, bit 31, has special meaning. When this bit is set, it indicates that at least one of the high order instance variables has changed. However, you don't know precisely which one.
Get Function
Anchor | ||||
---|---|---|---|---|
|
This function is rarely used in practice and translates low-level variables to higher-level variables. This function has the same signature as the Set function
...
When called, the function should update instance variables and can use the mask argument to determine which variables should be updated.
BypassFunction
Anchor | ||||
---|---|---|---|---|
|
This function implements a module's bypass functionality. The function signature is identical to the processing function
...