(8.D.2.4) MATLAB Function Reference
This page describes Audio Weaver's MATLAB functions related to module generation. Audio Weaver makes heavy use of MATLAB’s object oriented features. An object in MATLAB is a data structure with associated functions or methods. Each type of object is referred to as a class, and Audio Weaver uses separate classes to represent variable, modules, and subsystems. The class functions are stored in directories that start with the “@” symbol. Under <AWE>\matlab\ are 3 class directories:
@awe_variable\
@awe_module\
@awe_subsystem\
It is important to understand how to use and manipulate these classes in order to properly use all of the features of Audio Weaver. We begin by describing each class and then document additional MATLAB commands used for constructing modules.
@awe_variable
A variable in Audio Weaver represents a single scalar or array variable on the target processor. Even if you are not developing modules, it is good to understand the @awe_variable object so that you can fully utilize variables.
A new scalar variable is created by the call:
awe_variable(NAME, TYPE, VALUE, USAGE, DESCRIPTION, ISHIDDEN, ISCOMPLEX)
Scalar is a mathematical term and refers to a variable containing only a single value, not to be confused with Audio Weaver scaler modules.
Variables in Audio Weaver have a close correspondence to variables in the C language. The arguments are:
NAME — name of the variable as a string.
TYPE — C type of the variable as a string. For example, ‘int’ or ‘float’.
VALUE — initial value of the variable.
USAGE — a string specifying how the variable is used in Audio Weaver. Possible values are:
‘const’ — the variable is initialized when the module is allocated and does not change thereafter.
‘parameter’ — the variable can be changed at run-time and is exposed as a control.
‘derived' — similar to a parameter, but the value of the variable is computed based on other parameters in the module. Derived variables are not exposed as controls.
‘state’ — the variable is set at run-time by the processing function.
DESCRIPTION — a string describing the function of the variable.
ISHIDDEN — an optional Boolean indicating whether the variable is visible in the module’s Properties panel (ISHIDDEN=0) or hidden (ISHIDDEN=1). By default, ISHIDDEN=0.
ISCOMPLEX — an optional Boolean indicating whether the variable is real-valued (ISCOMPLEX=0) or complex (ISCOMPLEX=1). By default, ISCOMPLEX=0. Note, Audio Weaver only supports complex valued arrays, not scalars.
The awe_variable.m function is typically not used directly. Rather, the function is automatically called when you add variables to modules or subsystems using the add_variable.m or add_array.m functions.
Only 32-bit data types are supported. Allowable types are: 'float', 'int', 'uint', 'and 'fract32'.
We now look carefully at one of the variables in the agc_example.m system. At the MATLAB prompt, type:
SYS=agc_example;
struct(get_variable(SYS.agc.core, 'targetLevel'))
The get_variable.m
command extracts a single variable from a module and returns the @awe_module object. (If you instead try to access SYS.agc.core.targetLevel you'll only get the value of the variable, not the actual structure.) The MATLAB struct.m command turns an object into a data structure revealing each of its internal fields. You'll see:
name: 'targetLevel'
hierarchyName: 'agc.core.targetLevel'
value: -20
size: [1 1]
type: 'float'
isComplex: 0
range: [-50 50 0.1000]
isVolatile: 0
usage: 'parameter'
description: 'Target audio level.'
arrayHeap: 'AWE_HEAP_FAST2SLOW'
memorySegment: 'AWE_MOD_FAST_ANY_DATA'
arraySizeConstructor: ''
constructorCode: ''
guiInfo: [1x1 struct]
format: '%g'
units: 'dB'
isLive: 1
isHidden: 0
presets: [1x1 struct]
isArray: 0
targetInfo: [1x1 struct]
isLocked: 1
isPtr: 0
ptrExpr: ''
isRangeEditable: 1
isTuningSymbol: 0
isTextLabel: 1
isPreset: 1
isDisplayed: 1
classVersion: 29341
class: 'awe_variable'
fieldNames: {32x1 cell}
Many of the fields are set when the variable is added to the module or at build time. Some of them can be set after a module has been built.
name — string indicating the name of the variable. This is set when the variable is added to the module. Not user editable.
hierarchyName — hierarchical location of the variable in the overall system. Initially empty and then set by build.m. Not user editable.
value — current value of the variable. Although it can be read and written by the user, it is easier to access the value simply by referencing
SYS.agc.core.targetLevel
size — 1x2 element vector used to represent the size of matrices, [rows columns]. For scalars, this is always [1 1]. Set when the variable is added to the module or by the prebuild function. Not user editable.
type — string specifying the underlying data type of the variable. Allowable values are 'float', 'fract32', 'int', and 'uint'. Set when the variable is added to the module. Not user editable.
isComplex — Boolean indicating whether the variable contains complex data. Set when the variable is added to the module. Only arrays can be complex, not individual scalar variables. Not user editable.
range — a vector or matrix specifying the allowable range of the variable. This is used to validate variable updates and also to draw knobs and sliders. This vector uses the same format as the pin type described in Section 3.4. User editable.
usage — a string specifying how the variable is used in Audio Weaver. Set when the variable is added to the module. Not user editable. Possible values are:
‘const’ — the variable is initialized when the module is allocated and does not change thereafter.
‘parameter’ — the variable can be changed at run-time and is exposed as a control.
‘derived' — similar to a parameter, but the value of the variable is computed based on other parameters in the module. Derived variables are not exposed as controls.
‘state’ — the variable is set at run-time by the processing function.
description - a string describing the purpose or usage of the variable. User editable.
arrayHeap — used to specify array allocation information to the code generator. User editable.
memorySegment - used to specify array allocation information to the code generator. User editable.
arraySizeConstructor - used to specify array allocation information to the code generator. User editable.
constructorCode - specifies variable initialization when a module exists within a subsystem and is used by the code generator. User editable.
guiInfo — structure used to hold GUI related information. Some fields are user settable. Refer to the chapter in the Audio Weaver MATLAB API that discusses creating custom inspector interfaces.
format - C formatting string used by when displaying values in the MATLAB output window. Follows the formatting convention of the printf function. User editable.
units - a string containing the underlying units of the variable. For example, ‘dB’ or ‘Hz’. This is used by documentation and on user interface panels. User editable.
isLive — Boolean variable indicating whether the variable is residing on the target (isLive = 1), or if it has not yet been built (isLive=0). This starts out at 0 when the module is instantiated and is set to 1 by build.m. Not user editable.
isVolatile — Boolean indicating whether the variable is changed outside of MATLAB and needs to be read from the target each time. Reading of variables from the target only occurs when isLive=1. By default, only 'const' variables have isVolatile set to 0; all others are set to 1. User editable.
isHidden — Boolean indicating whether a variable is hidden. Hidden variables are not shown when a subsystem is displayed in the MATLAB output window. However, hidden variables may still be referenced. User editable.
isPreset — Boolean indicating whether the variable is included in presets. Used by the create_preset.m function. User editable.
isArray — Boolean indicating whether the variable is a scalar or an array. Scalar values occur in the instance data structure. Arrays have pointers in the instance data structure. This field is set when the variable is first instantiated and should not be changed thereafter.
targetInfo — internal data structure used when tuning the variable at run-time. Not user editable.
fieldNames — internal cell array of field names (actually the names of the fields in this data structure). It is used to accelerate references. Not user editable.
isLocked — internal field used to accelerate references. Not user editable.
isPtr — Boolean indicating whether the variable is a pointer of type ptrExpr.
ptrExpr — string specifying the pointer type of the variable.
isRangeEditable — Boolean indicating whether the variable range is editable or not.
isTuningSymbol — Boolean indicating whether the variable is real-time tunable or not.
classVersion — internal field indicating the SVN version number.
class — string specifying the underlying object class. This is always 'awe_variable'. Not user editable.
The .isHidden field can be used to hide any variable that the user typically does not need to know about. For example, allocate a 2nd order Biquad filter:
>> M=biquad_module('filter')
filter = Biquad // 2nd order IIR filter
b0: 1 // First numerator coefficient
b1: 0 // Second numerator coefficient
b2: 0 // Third numerator coefficient
a1: 0 // Second denominator coefficient
a2: 0 // Third denominator coefficient
All 5 of the tunable filter coefficients are shown. After the filter is built, state variables are added. You can see them by typing:
Of course, this assumes that you know that this module has a variable named .state. To show all hidden variables in the MATLAB output window, set
AWE_INFO.displayControl.showHidden=1;
Then, looking at the Biquad filter, the hidden .state variable will be shown as well:
@awe_module
This class represents a single primitive audio processing function on the target. A module consists of the following components: a set of names, input and output pins, variables, and functions. All of these items exist in MATLAB and many of them have duals on the target itself.
Class Object
To create an audio module object, call the function M=awe_module(CLASSNAME, DESCRIPTION)
The first argument, CLASSNAME, is a string specifying the class of the module. Each module must have a unique class name, and modules on the Server are instantiated by referencing their class name. The second argument, DESCRIPTION, is a short description of the function of the module. The DESCRIPTION string is used when displaying the module or requesting help.
Note: The function classid_lookup.m
can be used to determine if a class name is already in use. Refer to Specifying Class IDs for more information.
After the module class is created, set the particular name of the module:
M.name='moduleName';
Note that there is a distinction between the CLASSNAME and the .name of a module. The CLASSNAME is the unique identifier for the type of the module. For example, there are different class names for scalers and biquad filters. The .name identifies the module within a system and must be unique within the current level of hierarchy in the system. At this point, we have a bare module without inputs, outputs, variables, or associated functions. These must each be added.
We'll now look more closely at the fields within the @awe_module object. Instead of looking at a bare module as returned by awe_module.m, we'll look at a module that is part of a system and has already been built. We'll choose the Automatic Gain Control Core module:
struct(agc_core_module)
MATLAB displays the following:
The above fields correspond to the following:
name — name of the module within the subsystem. This is specified when the module is instantiated and cannot be changed thereafter. Not user editable.
className — name of the underlying module class. This is specified when the module is instantiated and cannot be changed thereafter. Not user editable.
description — short comment indicating what the module does. User editable.
classID — unique integer which identifies the module class on the target. This value is set by the code generator and is normally blank. Not user editable.
constructorArgument — list of the arguments to be passed to the module. Module must be called with all arguments while generating the code.
defaultName — Fixed default name of the module.
moduleVersion — Version of the module.
classVersion — Version of the module class.
isDeprecated — Boolean indicates whether the module is deprecated in the current version of AWE Designer.
isInterpreted — Boolean indicates whether the module is Interpreted or not.
mfilePath — full path to the m-file which instantiated the module (the one containing the call to @awe_module). Used by the code generator. Not user editable.
mfileDirectory — the directory portion of mfilePath. Not user editable.
mfileName — the file name portion of mfilePath. Not user editable.
mode — string indicating the current module status. This can be either 'Active', 'Bypassed', 'Muted', or 'Inactive'. Used internally and is not user editable. Use the functions awe_setstatus.m and awe_getstatus.m to manipulate the module status.
clockDivider — integer indicating how often the module will be run within the layout. This is currently always set to 1 (meaning run every time). This is reserved for new Audio Weaver functionality planned in the future. Not user editable.
inputPin — cell array of input pin information. This information is set by the add_pin.m function and should not be changed. You'll frequently access this to determine the properties of the input pins. Each cell value contains a data structure such as:
outputPin — similar to inputPin. It is a cell array describing the output pins.
scratchPin - similar to inputPin. It is a cell array describing the scratch pins.
variable — a cell array of @awe_variable objects corresponding to the variables in this module. This array is updated by the add_variable.m function. Not user editable.
variableName — a cell array of strings, one for each variable in the module. This cell array is used to speed up variable accesses. This array is updated by the add_variable.m command. Not user editable.
control — holds internal information related to the inspector. Not user editable.
wireAllocation — a string specifying how wires should be allocated for the module. Possibilites are 'across' and 'distinct'.
getFunc — optional MATLAB function pointer specifying the module's get function. This function is called whenever a variable in the module is queried. Used very rarely. Normally this is set to the empty matrix.
setFunc — optional MATLAB function pointer specifying the module's set (or control) function.
processFunc — optional MATLAB function pointer specifying the module's processing function. The processing function is a MATLAB implementation of the audio processing performed by the module.
bypassFunc — optional MATLAB function pointer specifying the module's bypass behavior.
muteFunc — optional MATLAB function pointer specifying the module’s mute behavior.
preBuildFunc — optional MATLAB function pointer specifying the module's prebuild functionality. The prebuild function is called prior to building the module or generating code and resolves pin types and array sizes.
postBuildFunc — optional MATLAB function pointer specifying the module’s postbuild functionality. Generally most of the module will have this field as empty.
testHarnessFunc — optional MATLAB function pointer specifying the module’s test harness script.
profileFunc — optional MATLAB function pointer specifying the module’s profile function.
isHidden — Boolean specifying whether the module should be shown when part of a subsystem. Similar to the .isHidden field of @awe_variable objects. User editable.
isPreset — Boolean that indicates whether the module will be included in generated presets. By default, this is set to 1. User editable.
isMeta — Boolean specifying whether this is a meta-module which switches out at build time.
metaFuncName — optional string specifying the name of the underlying module to instantiate if this is a meta module.
requiredClasses — This is the list of classes required for the current instantiation of the
module. For meta modules it could be a subset of requiredClassesBrowser.
consArgPatchFunc — Custom function to matchup older version of system with new module.
moduleBrowser — This is the information for displaying the module in AWE Designer GUI. It includes the image of the module in the designer module tree, search tag, name of the module in browser etc. Look for .moduleBrowser for more information.
textLabelFunc — Function for generating a text lablel when drawn in the AWE Designer GUI. Look at the .textLablelFunc for more information.
textInfo — Text label properties information.
shapeInfo — Is a structure which holds shape information of the module in the AWE Designer GUI. It includes the name of the SVG image used to draw on the layout, size of the module, shape of the module etc. Look at .shapeInfo for more information. Default shape information is Rectangle box with Solid lines with Black color. This can be overwritten by initializing fields in this structure.
freqRespFunc — Optional MATLAB function pointer for computing the frequency response of the module.
bypassFreqRespFunc — Frequency response function of the module in bypass mode.
prepareToSaveFunc — Function for clearing out internal pointers or other state that is not needed when the module is saved.
copyVarFunc — optional MATLAB function pointer that is called when a module’s variables need to be copied. User can over right the default generic copy variables function.
inspectFunc — optional MATLAB function for drawing custom inspector.
inspectHandle — Figure handle of the custom inspector, internal to the Audio Weaver.
inspectPosition — Position, [x y], of the custom inspector in MATLAB coordinates used by the “inspect” function of the Audio Weaver.
inspectUserData — Custom inspector persisted information.
numericInspectHandle — Numeric inspector handle of the module for AWE Designer.
numericInspectPosition — Position, [x y], of the numeric inspector of the module in MATLAB coordinates for designer.
freqRespHandle — Module’s frequency response handle.
freqRespPosition — Position, [x y], of the frequency response to be drawn in MATLAB coordinates for designer.
isTunable — Boolean indicating whether the variables in the module are real time tunable or not in designer.
View — Structure of various fields internal to Audio Weaver holds the view settings in the designer.
isLive —Boolean indicating whether the module has been built and is running on the target. When a module is first instantiated, this is set to 0 and then changed to 1 by the build process. Not user editable.
hierarchyName — hierarchical name of the module within the subsystem. This is filled in during the build process. Not user editable.
hasFired — Boolean field that is used internally by the routing algorithm. Not user editable.
targetInfo — data structure holding target specific information. This is filled in by the build process and is used internally for tuning. Not user editable.
codeMarker — a cell array holding all of the code markers. Code markers are used for module generation and described in Section 5.2. Not user editable.
isTopLevel — Boolean set by the buid process. A value of 1 indicates that a module is the highest level item in a system. All modules have .isTopLevel=0; only the top-level subsystem has .isTopLevel=1. Not user editable.
guiInfo — data structure used for drawing inspectors. Some fields are user editable. See Overriding Default GUI Settings for information about creating custom inspector interfaces.
drawInfo — data structure used internally when creating drawings of subsystems and modules. Not user editable.
docInfo — data structure containing documentation information. This is set in the module's m-file and is used by the automated documentation generator. Some user editable fields. Refer to the Section 6.
isLocked — internal field used to accelerate references. Not user editable.
class — string specifying the underlying object class. This is always 'awe_module'. Not user editable.
fieldNames — internal cell array of field names (actually the names of the fields in this data structure). It is used to accelerate references. Not user editable.
MATLAB Functions for Constructing Modules
The following functions are commonly used for constructing audio modules. They are briefly mentioned here and are documented later in this guide.
add_variable.m — adds a scalar variable to an audio module object.
add_array.m — adds an indirect array to an audio module object.
add_pin.m — adds an input, output, or scratch pin to an audio module object.
add_codemarker.m — adds information related to code generation.
add_control.m — exposes a single control on the inspector.
set_variable.m — replaces an existing module variable.
get_variable.m — extracts a variable from a module and returns an @awe_variable object.
Internal Module Functions
Every module in Audio Weaver has an associated MATLAB function file that constructs an @awe_module object describing the module. Audio Weaver uses the convention that these module constructor functions end in "_module.m". In addition to configuring the module’s input and output pins, and defining instance variables, the constructor function also assigns a number of method functions, and these functions are typically contained as sub-functions in the constructor file.
There is a close coupling between the module related C functions the module subfunctions on the target processor. The table below gives a brief description of the functions available.
MATLAB Function Name | Target Function Name | Purpose |
*_module.m | *_Constructor() | Constructs an instance of a module class. The function allocates memory for the base instance structure. The MATLAB function sets default values while on the target default values are passed into the constructor. Required. |
.processFunc | *_Process() | Real-time processing function. Required for C code. Optional for MATLAB. |
.setFunc | *_Set() | Implements the module's control functionality. The function converts high-level interface parameters to lower-level derived values. This function should be called whenever a variable in a module is modified. Optional. |
.getFunc | *_Get() | The counterpart to the _Set() function but is used when module variables are read. Most modules do not use this function. When a module instance variable is read, this function is first called and then the instance variable is returned. It could be used, for example, to convert a measurement from energy to dB. |
.bypassFunc | *_Bypass() | Implements the module's bypass functionality. This is an optional function; when it is empty, a generic bypass function is used instead. |
.preBuildFunc | N/A | This function exists only in MATLAB and it is called as part of the build procedure. The prebuild function propagates pin information and may update array sizes. The prebuild function is useful for setting variable values that depend upon the pin type. The prebuild function is optional; if it doesn't exist, the pin type information from the module's first input pin is propagated to the output. |
.freqRespFunc
| N/A | This optional function exists only in MATLAB and it computes the frequency response of the module. |
.profileFunc
| N/A | This optional function exists only in MATLAB and it profiles the module for various settings like different block size and etc. |
.textLabelFunc
| N/A | This optional function exists only in MATLAB and it draws the text label for the AWE Designer GUI. |
MATLAB Module M-File
The MATLAB m-file associated with an audio module creates and returns an instance of the module. The typical function signature for a module m-file is
function M=new_module(NAME, ARG1, ARG2,...)
where NAME is a string module name and ARG1, ARG2, are optional arguments. Good practice is to set default values for all arguments except NAME. For example:
The main difference between the MATLAB instantiation function and the C constructor is that the C constructor is responsible for all memory allocation. MATLAB, on the other hand, has the option of doing memory allocation in the prebuild function.
.processFunc
This function provides a MATLAB implementation of the module's processing function. The function signature is:
function [M, WIRE_OUT]=new_process(M, WIRE_IN)
where:
M — the @awe_module object.
WIRE_IN — a cell array of corresponding to the input data to be processed by the module.
Note that M serves as both an input argument and output result of the function. The function modifies the state variables within M and then returns the updated object. WIRE_OUT is a cell array containing the output data.
Each element within the WIRE_IN cell array is an MxN matrix representing the input data at a particular pin. Each column of the input data represents a different channel. The audio data is processed and the result written to WIRE_OUT. For example, the processing function for the scaler_module.m computes
One difference between MATLAB and C is that the wires in MATLAB serve only to pass data in and out of the processing function. Pin information is determined in MATLAB from fields in the audio module structure. For example, to determine the sample rate of the first input, use
M.inputPin{1}.type.sampleRate
whereas in C, you would use
SR = (float) ClassWire_GetSampleRate(pWires[0]);
.setFunc
Implements the main control functional for a module. This function is called whenever a variable within the audio module is updated. The function signature is:
function M=new_set(M)
where:
M — the @awe_module object.
Note that the MATLAB set function does not have a MASK argument indicating which variable changed.
.getFunc
Implements secondary control functionality. This function is called when a variable in the module is read. The function signature is identical to the .setFunc
function M=new_get(M)
where:
M — the @awe_module object.
.bypassFunc
Provides a custom bypass function for a module. The function signature is identical to the .processFunc
function [M, WIRE_OUT]=new_bypass(M, WIRE_IN)
where:
M — the @awe_module object.
WIRE_IN — a cell array of corresponding to the input data to be processed by the module.
.preBuildFunc
This function is called when a system is built for execution on a target. The function updates any internal variables which depend upon the sample rate, block size, or number of channels. The function also implements non-standard pin propagation functionality. The function signature is:
function M=new_prebuild(M)
where:
M — the @awe_module object.
The function updates and returns the module object M.
.freqRespFunc
This function computes the frequency response of the system. The function signature is:
function H_OUT=new_freq_response(M, H_IN, W)
where:
M — the @awe_module object.
H_IN — a cell array of corresponding to the input data.
W — vector of frequencies at which frequency response to be computed.
H_OUT — a cell array of frequency response output of corresponding input data.
.textLabelFunc
This is an optional function which returns text labels to be displayed in AWE Designer. The function signature is:
Function L=sof40_cascade_text_label(M)
where:
M — the @awe_module object.
L — a cell array of strings with desired text labels in AWE Designer
@awe_subsystem
This class represents both systems and subsystems; they are equivalent and no distinction is made in Audio Weaver. A subsystem has all of the characteristics of an audio module: a class name, input and output pins, variables, and associated sub-functions. In addition, a subsystem contains two other items:
Internal modules.
Connections between the modules and the subsystem input and output pins.
Key subsystem functions are described next.
ClassObject
The call to create a new empty subsystem is similar to the call to create a new module described in Class Object.
SYS=awe_subsystem(CLASSNAME, DESCRIPTION);
You have to provide a unique class name and a short description of the function of the subsystem. (To be precise, the CLASSNAME only has to be unique if you are generating C code using the new subsystem class. Then, the CLASSNAME has to be unique among all of the subsystems and audio modules.)
After the subsystem is created, set the particular name of the subsystem:
SYS.name='subsystemName';
At this point, we have an empty subsystem; no modules, pins, variables, or connections.
As before, we'll look at the internal fields of a subsystem and we'll use a running subsystem as an example. The @awe_subsystem object is derived from an @awe_module object. In fact, the first 36 fields of a subsystem are identical to a module object. The only new fields are:
isPrebuilt — a Boolean specifying where the system has already been through the prebuild process. This is used internally and is not user editable.
preProcessFunc — pointer to a MATLAB function which is called prior to the subsystem being executed. It is the MATLAB dual to the 'preProcessFunc' code marker and is used for simulating subsystems in MATLAB.
postProcessFunc — pointer to a MATLAB function which is called after the subsystem has executed. It is the MATLAB dual to the 'postProcessFunc' code marker and is used for simulating subsystems in MATLAB.
buildFunc — pointer to a MATLAB function which builds the subsystem on the target. This is empty except for top level systems.
drawFunc — pointer to a MATLAB function which overrides drawing of the module in figure windows. This is not yet used and is provided for future enhancements.
module — cell array of the internal modules used by the subsystem. Not user editable.
moduleName — cell array of internal module names. This is used to accelerate references. Not user editator.
connection — cell array describing all of the connections in the subsystem. This array is populated by calls to connect.m. Not user editable.
flattenOnBuild — a Boolean describing how this subsystem is treated during code generation and building. When creating new module classes out of subsystems, set .flattenOnBuild = 1. See Section 7.3 for an example.
targetSpecificInfo — a data structure populated by the build process. It is used to enable real-time tuning on a target. Not user editable.
MATLAB Functions for Constructing Subsystems
All of the functions listed in Section 3.2.2 which are used to construct modules also apply to subsystems. Additional commands for constructing subsystems are:
connect.m — creates a wiring connection between two pins in a subsystem.
get_module.m — extracts a module from a subsystem and returns the @awe_module object.
These commands are documented in (8.D.2.4) MATLAB Scripting API.
Internal Subsystem Functions
Each subsystem has a set of subfunctions that mirror the module functions described in 3.2.3. Fortunately, for most subsystems, generic or generated versions of the functions can be used. The table below describes the operation of each of the functions in the context of generated code.
MATLAB Function Name | Target Function Name | Purpose |
*_module.m | *_Constructor() | This MATLAB code must be manually written as described above. Modules are manually added, configured, and connected. The C code version of this function is automatically generated. The function calls the base module constructor function and then calls the _Constructor() function for all internal modules. The internal modules parameters are set according to their values at build time. |
.processFunc | *_Process() | Audio Weaver automatically generates the MATLAB and C versions of these functions. |
.setFunc | *_Set() | In all cases, this must be manually written. |
.getFunc | *_Get() | In all cases, this must be manually written. |
.bypassFunc | *_Bypass() | The generic function utilized by modules can also be used here. |
.preBuildFunc | N/A | Not needed. The existing pin propagation function can propagate the information through subsystems. |
Top-Level Systems
Thus far, we have been using the terms system and subsystem interchangeably. There is a slight difference, though, that you need to be aware of. The highest level system object that is passed to the build command must be a top-level system created by the function:
SYS=target_system(CLASSNAME, DESCRIPTION, RT)
The top-level system is still an @awe_subsystem object but it is treated differently by the build process. The main difference is how the output pin properties are handled. In a top-level system, the output pins properties are explicitly specified and not derived from pin propagation. As an added check, the pin propagation algorithm verifies that the wires attached to a top-level system's output pins match the properties of each output pin. In contrast, internal subsystems are created by calls to
SYS=awe_subsystem(CLASSNAME, DESCRIPTION)
and the type information for output pins is determined by pin propagation.
new_pin_type.m
This function returns a data structure representing a pin. The internal structure of a pin can be seen by examining the pin data structure. At the MATLAB command prompt type:
new_pin_type
Be sure to leave off the trailing semicolon — this causes MATLAB to display the result of the function call. We see:
The first 5 fields of the data structure specify the current settings of the pin; the last 5 fields represent the allowable ranges of the settings. The range information is encoded using the following convention:
[] — the empty matrix indicates that there are no constraints placed on the range.
[M] — a single value indicates that the variable can only take on one value.
[M N] — a 1x2 row vector indicates that the variable has to be in the range M <=x <= N.
[M N step] — a 1x3 row vector indicates that the variable has to be in range M<=x<=N and that it also has to increment by step. In MATLAB notation, the set of allowable values is [M:step:N].
By default, the new_pin_type.m
function returns a pin with no constraints on the sampleRate, blockSize, and numChannels. The dataType is floating-point and the data real.
Additional flexibility is built into the range information. Instead of just a row vector, the range can have a matrix of values. Each row is interpreted as a separate allowable range. For example, suppose that a module can only operate at the sample rates 32 kHz, 44.1 kHz, and 48 kHz. To enforce this, set the sampleRateRange
to [32000; 44100; 48000]. Note the semicolons which place each sample rate constraint on a new row.
Audio Weaver also interprets NaN’s in the matrix as if they were blank. For example, suppose a module can operate at exactly 32 kHz or in the range 44.1 to 48 kHz. To encode this, set sampleRateRange=[32000 NaN; 44100 48000]
.
The new_pin_type.m function accepts a number of optional arguments:
new_pin_type(NUMCHANNELS, BLOCKSIZE, SAMPLERATE, DATATYPE, ISCOMPLEX);
These optional arguments allow you to properties of the pin. For example, the call
new_pin_type(2, 32, 48000)
returns the pin
This corresponds to exactly 2 channels with 32 samples each at 48 kHz. Note, that the pin type is represented using a standard MATLAB structure. You can always change the type information after new_pin_type.m is called. For example,
The current values and ranges of values are both provided in Audio Weaver for a number of reasons. First, the range information allows an algorithm to represent and validate the information in a consistent manner. Second, the pin information is available to the module at design time, allocation time, and at run-time. For example, the sample rate can be used to compute filter coefficients given a cutoff frequency in Hz. Third, most modules in Audio Weaver are designed to operate on an arbitrary number of channels. The module's run-time function interrogates its pins to determine the number of channels and block size, and processes the appropriate number of samples.
Consider the look ahead limiter subsystem introduced in Specifying Module Constructor Arguments in Subsystems. It can be connected to mono, stereo, or 5.1 channel signals and all of the wiring and buffer allocation will be automatically handled. This generality allows you to design algorithms which operate on an arbitrary number of channels with little added complexity.
Usage of new_pin_type.m
is slightly more complicated than described above. In fact, the 5 arguments passed to the function actually specify the ranges of the pin properties and the current values are taken as the first item in each range. For example, consider a module that can operate on even block sizes in the range from 32 to 64. This is specified as:
Note that the first argument, the number of channels, is empty. An empty matrix places no constraints on the item. Notice also that the current blockSize
equals the first value, 32, in the range of allowable block sizes. Additional examples highlight other ways to use this function.
You can also specify that a pin can hold either floating-point or fract32 data. Pass in a cell array of strings as the 4th argument to new_pin_type:
Some modules do nothing more than move data around. Examples include the interleave_module.m and the delay_module.m. These modules do not care about the data type, only that it is 32-bits wide. The new_pin_type.m
function uses the shorthand '*32' to represent all 32-bit data type. This currently includes 'float', 'fract32', and 'int':
add_pin.m
Pins are added to a module by the add_pin.m
function. Each pin has an associated Pin Type as described in new_pin_type.m. After creating the Pin Type, call the function
add_pin(M, USAGE, NAME, DESCRIPTION, TYPE, numPinArray)
for each input, output, or scratch pin you want to add.
The arguments are as follows:
M — @awe_module object.
USAGE — string specifying whether the pin is an ‘input’, ‘output’, or 'scratch'.
NAME — short name which is used as a label for the pin.
DESCRIPTION — description of the purpose or function of the pin.
TYPE — Pin Type structure.
numPinArray — Distinguish between a scalar pin and a pin array. For scalar pin this value will be 0 and for pin array this value will be size of the pin array.
M.inputPin
, M.outputPin
, and M.scratchPin
are cell arrays that describe the pins. Each call to add_pin.m
adds an entry to one of these arrays, depending upon whether it is an input, output, or scratch pin. For example, to determine the number of input pins that a module has, use
length(M.inputPin)
or to print out all of the names of the output pins
Some processing functions require temporary memory storage. This memory is only needed while processing is active and does not need to be persisted between calls. (On the other hand, memory that needs to be persisted by a module between calls to the processing function appears in the instance structure and has usage "state".) Allocating temporary memory and sharing it between modules is accomplished by scratch pins. Scratch pins are added to a module via add_pin.m
with the USAGE argument set to 'scratch'. Scratch pins are typically not used by audio modules, but are often required by subsystems. For subsystems, the routing algorithm automatically determines scratch pins at build time.
In some cases, you want to add a pin to a subsystem that is of the same type as an internal module. For example, the Hilbert subsystem uses the same pin type as the Biquad filter. This can be achieved programmatically:
Rules to add_pin.m:
Pins of the same direction should have no duplicate names.
If the module has number of pins depends on the argument then the number of pins must be passed as last argument to add_pin(). For example,
interleave_module.m
has input pins depends on argument, NUMIN. Input pins must be added as below:add_pin(M, 'input', 'in', 'Input signal', PT, NUMIN);
The module will display input pins as in1, in2 …. in<NUMIN> in the designer. Here ‘in’ is the base name.If the module has scalar pin along with pin array, then the scalar pin name must not match the bas name of a pin array.
add_variable.m
M=add_variable(M, VAR)
Adds a single scalar variable to an @awe_module or @awe_subsystem object and returns the updated object.
The arguments are as follows:
M — @awe_module or @awe_subsystem object to which to add the variable
VAR — @awe_variable object returned by
awe_variable.m
Alternatively, you can construct the variable on the fly as:
M=add_variable(M, ARGS...)
where ARGS are arguments which get passed to @awe_variable. In this case, the arguments are ordered as:
When called with no output arguments, as in
add_variable(M, VAR);
the input module M is updated in the calling environment.
After adding a variable to an audio module, it is a good idea to also specify its range and units. The range field is used when drawing inspectors (sliders and knobs, in particular) and also for validating variable assignments. The units string reminds the user of what units the variable represents. You set these as:
Note that after a variable is added to a module, it appears as a field within the module’s structure and the name of the field equals the name of the variable. Attributes of an individual variable are referenced using the “.” structure notation. Refer to Audio Module Instance Structure to see the correspondence between variables in the MATLAB object and variables in the C type definition.
add_argument.m
M = add_argument(M, VAR, varargin)
Adds an input argument descriptor to the module/subsystem object. These are not accessible via the . operator, but are kept in the constructorArguments container. Arguments are variables used at construction time for operations such as: sizing internal arrays based on something other than channels / blockSize and disabling or enabling additional pins. For constructor arguments to be available in the structure they should be tracked by an additional ‘const’ module variable added using add_variable()
.
The arguments are as follows:
M — @awe_module or @awe_subsystem object to which to add the argument
VAR — @awe_variable object that describes the input parameter, OR use the second through N arguments to create the variable as described in the previous section.
add_array.m
M=add_array(M, VAR)
Adds an array to an @awe_module or @awe_subsystem object and returns the updated object.
The arguments are as follows:
M — @awe_module or @awe_subsystem object to which to add the array
VAR — @awe_variable object.
Alternatively, you can construct the array on the fly as:
M=add_array(M, ARGS...)
where ARGS are arguments which get passed to @awe_variable. In this case, the arguments are ordered as:
The size of the array is specified when it is first added. You can also subsequently change the array size in the module's prebuild function. When doing so, you need to change the .size
field of the variable and then the data itself. For example, the state variables used by the Biquad module are stored in a matrix of size 2 x numChannels.
However, numChannels
is not known until the module is built and therefore code within the Biquad prebuild function is used to update the array size:
Audio Weaver supports 1- and 2-dimensional arrays. The 2 dimensional array representation is maintained in MATLAB. On the target, however, a 2-dimensional array is flattened into a 1-dimensional array on a column-by-column basis. Both scalar and array variables are represented as @awe_variable objects.
Array variables appear as pointers in the module instance structure. For example, an FIR filter has separate arrays for coefficients and state variables:
The C type definition for this FIR filter is found in the file ModFIR.h:
Using indirect arrays enables arrays to have variable length and also to be placed in distinct memory banks. This is last time is useful, for example, on the SHARC processor to enable simultaneous memory reads.
add_pointer.m
add_pointer(M, NAME, CTYPE, [USAGE], [DESCRIPTION], [ISHIDDEN]))
Adds a pointer variable to an Audio Weaver module. A pointer variable is used to point to a data structure which is defined outside of the module itself. Use pointers, for example, to point a data structure used by a third party algorithm. When you add a pointer to an Audio Weaver module, the pointer variable is added to the module’s instance structure but memory for it is not allocated. You must separately allocate memory for the pointer using custom code in the module’s constructor function.
The arguments are as follows:
M - @awe_module object to which to add the pointer variable.
NAME — name of the pointer variable. Must be a valid C variable name.
CTYPE — type definition which will be used by the variable. For example, ‘void *’ or ‘SparseItem *’. This string is used directly as the pointer type in the instance structure.
USAGE — how the variable is used. As before, this can be ‘parameter’, ‘state’, ‘derived’, or ‘const’.
DESCRIPTION — optional short description string.
ISHIDDEN — optional Boolean which hides the variable from standard MATLAB usage.
Note: you will not be able to examine the contents of pointer variables from MATLAB, since is unaware of the data type of the variable.
add_module.m
Modules are added to subsystems one at a time using the function
add_module(SYS, MOD)
The first argument is the subsystem while the second argument is the module (or subsystem) to add. Once a module is added to a subsystem, it appears as a field within the object SYS. The name of the field is determined by the module's name. Modules can be added to subsystems in any order. The run-time execution order is determined by the routing algorithm.
As modules are added to the subsystem, they are appended to the .module field. You can use standard MATLAB programming syntax to access this information. For example, to determine the number of modules in a subsystem:
count=length(SYS.module);
Or, to print out the names of all of the modules in a subsystem:
connect.m
Creates a connection between two pins in a subsystem. The general form is:
connect(SYS, SRCPIN, DSTPIN);
where SRCPIN
and DSTPIN
specify the source and destination pins, respectively. Pins are specified as strings to the connect.m command using the syntax:
moduleName.pinName
Consider the system shown below and contained within multiplexor_example.m.
To connect the output of the sine generator1 to the second input of the multiplexor, use the command:
connect(SYS, 'sine1.out', 'mult.in2');
The module names "sine1" and "mult" are obvious because they were specified when the modules were created. The pins names may not be obvious since they appear within the module's constructor function. To determine the names of a module's pins, you can either utilize the detailed help function awe_help (recommended)
awe_help multiplexor_smoothed_module
or have MATLAB draw the module
Several shortcuts exists to simplify use of the connect.m
command:
If the module has only a single input or output pin, then you need only specify the module name; the pin name is assumed. Since the sine wave generator module in the multiplexor example has only a single output pin, the example above reduces to:
connect(SYS, 'sine1', 'mult.in2');
Inputs and outputs to the subsystem are specified by the empty string. Thus,
connect(SYS, '', 'mult.in1');
connects the input of the system to the first input of the multiplexor. Similarly,connect(SYS, 'mult', '');
connects the output of the multiplexor to the output of the system.By default, the connect command performs rudimentary error checking. The function verifies that the named modules and pins exist within the subsystem. At build time, however, exhaustive checking of all connections is done. Audio Weaver verifies that all connections are made to compatible input and output pins (using the range information within the pin type). You can enable this exhaustive checking when a connection is made by supplying a 4th argument:
connect(SYS, 'mult', '', 1)
This is useful when debugging wiring failures that are revealed at build time.
Output pins are permitted to fan out to an arbitrary number of input pins. Input pins, however, can only have a single connection.
Audio Weaver is set up to handle several special cases of connections at build time. First, if an input pin has no connections, Audio Weaver inserts a source module and connects it to the unconnected input. Either a source_module.m (float) or source_fract32_module.m is added based on the first input to the system (Audio Weaver is guessing at the type of pin that needs to be connected). If a module has an output pin without a connection, Audio Weaver inserts a sink module based on the data type of the unconnected pin. This is always correct since the pin type is inherited from the module's output pin.
If the subsystem has a direct connection from an input pin to an output pin, then a copier_module is inserted. If a module output fans out to N outputs of the subsystem, then N-1 copier modules are inserted. This is required since each output of the subsystem is stored in a separate buffer.
get_variable.m and set_variable.m
Extract and assign individual @awe_variable objects within an audio module. This is needed because of the object-oriented nature of the Audio Weaver interface. When accessing a variable "var" within a module "M", as in:
M.var
Audio Weaver returns the value of the variable, not the variable object itself. If you wish to gain access to the actual variable object, use the call:
V=get_variable(M, NAME)
where:
M — the @awe_module object.
NAME — a string specifying the name of the variable.
The function returns an @awe_variable object. For example, the following code gets the underlying @awe_variable object for the "gain" variable of a smoothed scaler module:
Similary, the set_variable.m
command can be used to replace an existing variable with a given @awe_variable object. "Replace" is used because the variable must already exist within the audio module. The syntax for this command is:
M=set_variable(M, NAME, VAR)
where:
M — the @awe_module object.
NAME — a string specifying the name of the variable.
VAR - @awe_variable object.
The get_variable.m
and set_variable.m
functions are rarely used in practice. You can always access the internal fields of a @awe_variable object even when it is part of an audio module. For example, to access the "range" field of the variable "gain", use:
range=M.gain.range;
Module for AWE Designer
This section focus on the module browser information related to AWE Designer. Every module must initialize the moduleBrowser and shapeInfo structure of the MATLAB module object. Below is the example settings of downsampler_example_module.m module. Refer the section 3.2 for complete information of these structures.
.path — is the folder name in the AWE Designer browser tree.
.image — is the module browser image file to be used to display the module in AWE Designer browser tree. If no image file is empty, then the default image file will be used by the Designer.
.searchTags — is the string to search in the Designer search filed to find the module.
.svgImage — is the module shape image file to be used by the designer to draw the shape in the layout area when the module is drag and dropped in the layout area. If this field is empty then the default rectangle shape is used by the Designer. If an invalid SVG image is provided, an error will be logged in the Bin/Assets/logs/general.log file. See the Audio Weaver Logging Guide for details.
.size — is the shape size in the Designer layout area.
When the module is generated by executing the make script, for example make_examples.m, the XML file is generated which is used by the AWE Designer. XML file holds the complete information about the module to AWE Designer, like browser image file path, svg image file path for module shape, help document path, module arguments and other settings for AWE Designer. The information in XML file is extracted from the module file from the moduleBrowser and shapeInfo fields. Below is the example XML file of downsampler_example_module.m module.
Every module must be instantiated in the make script with complete arguments. Otherwise the arguments related information will not be extracted in to XML file and AWE Designer won’t have access to arguments. For example downsampler_example_module.m require two arguments, NAME and D (decimation factor). It must be instantiated as
MM{end+1}=downsampler_example_module('temp', 2); % 100% instantiation
in the make_example.m script. Here ‘temp’ is the name and 2 is the default decimation factor. Similarly lah_limiter_example_module.m require two arguments, NAME and MAXDELAY. This must be instantiated as
MM{end+1}=lah_limiter_example_module('temp', 5); % 100% instantiation
Here ‘temp’ is the name and 5 is the default max delay time.