Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. For each audio module in the library

...

    1. Add code markers

...

    1. Generate the module's .c and .h files using template substitution

  1. Generate the combined schema file describing all of the modules in the library

  2. Translate the schema information into a C data structure that can be compiled and included with the DLL.

  3. Compile the generated files and create an audio module dynamic link library (DLL).

Steps 1 and 3 are automated using the awe_generate_library.m command.  Many other MATLAB functions are internally called. Only a few other functions are documented here to help you better understand the code generation process.  Step 4 is done separately in VisualStudio and described in Section 6 Generating Documentation.

...

awe_generate_library.m

awe_generate_library(MM, DIR, LIBNAME, USESDLLS, GENDOC)

...

GENDOC – integer indicating whether module documentation should be generated.  By default, GENDOC=0 and no documentation is generated.  If GENDOC=1, then a single document is created for the entire module library.  If GENDOC=2, then a separate document is created for each audio module.

...

Creating the Cell Array of Modules

The argument, MM, is a cell array populated with modules to be placed in the final library.  For example, it might contain:

...

MM{end+1}=scaler_smoothed_example_module('temp');

...

Specifying Dependencies

USESDLLS is a cell array of structures that specifies dependencies.  Each structure contains the fields:

...

ind=max(ind);

 

DIR=pathstr(1:ind-1);

...

Generated Files

Let DIR be the base directory for the audio module library and let 'Examples' be the name of the library.  awe_generate_library.m creates the following files:

...

<DIR>\xml – Module XML file for AWE Designer, explained in section 3.12.

...

SchemaBuilder.exe

You'll notice this executable within the Audio Weaver Bin directory.  This executable compiles the schema information.  That is, it takes a .sch file and compiles into a .cpp file.  The .cpp file is then included in the project for building the module DLL.  SchemaBuilder.exe is automatically called by awe_generate_library.m and there is no need to call it separately.

...

AWE_INFO.buildControl

The global variable AWE_INFO contain the structure .buildControl which controls the library generation process.  AWE_INFO.buildControl contains many fields which are used internally.  We point out the user settable values.

...

This Boolean specifies whether the source code should be formatted after generation using the executable indent.exe.  Formatting the code regularizes identing, line breaks, etc.  By default, indentSourceFiles=0.  Formatting the source code significantly slows down the module generation process.

...

Setting the Audio Module Search Path

When you are developing a custom audio module, you must add the base module directory to the Audio Weaver module search path.  It is not enough to merely modify your MATLAB path. The path can be updated in Designer using the ‘File->Set Module Path’ menu option. To add a directory to the Audio Weaver module search path programmatically, use the command

...

add_module_path(PATH, '-end');

 

 

Specifying Class IDs
Anchor
SpecifyingClassIDs
SpecifyingClassIDs

...

For each directory, the file classids.csv is opened and examined.  The function classid_lookup.m uses internal caching to speed up the search process.

...

Reordering of Render Variables

As part of the build process, Audio Weaver reorders the variables in a module or subsystem to match the manner in which modules are instantiated by the Server.  The reordering is performed by the function

...

The ordering enforces that all scalar variables, which are initialized by the base module constructor function, are located at the start of the instance structure.  Refer to Section 4.4.1 for additional details.

...

Overwriting Existing Source Files

Audio Weaver is frequently used in conjunction with a source code control system.  The awe_generate_library.m function overwrites generated files only if there is an actual change to the file.  If nothing has changed, the file is untouched.

...

The most common situation when 'across' wiring cannot be applied is when a module sits between the input and output of a system.  For routing reasons, the wires attached to the input and output of a subsystem have to be distinct.  Placing a module with .wireAllocation='across' between them will still lead to distinct buffer allocation.

1.5.12. AudioWeaverModule Tag

AudioWeaverModule Tag

The function awe_help.m displays a list of all Audio Weaver modules on the current module search path.  In order for a module m-file to be picked up, you need to add the tag AudioWeaverModule somewhere within the m-file.  This tag allows you to differentiate between actual module m-files and other MATLAB files contained in the same directories.  The tag can be placed anywhere within the file, usually in a comment as shown below:

...

where IDENTIFIER is a string.  The template substitution function is given a list of identifiers together with their replacements.  The substitutions are performed and a new output file is created.  If an identifier within a file is not defined, then it is deleted and does not appear in the output.

...

Adding Code Markers

A "code marker" is an identifier together with a replacement string.  Each module and subsystem has its own list of code markers.  The MATLAB function

...

    name: 'discussion'

    text: {1x9 cell}

...

Inserting Files

In many cases, the SUBSTITUTION string contains many lines and it is unwieldy to represent in MATLAB.  Instead, it is easier to copy the SUBSTITUTION text from another file.  If the SUBSTITUTION string has the form "Insert:filename.txt" then the text will be copied from filename.txt.  filename.txt is referenced relative to the location of the module's m-file.  You can specify subdirectories as well.  For example:

...

inserts the file InnerPeakHold_Process.c located in the subdirectory "Inner".

...

awe_lookupcodemarker.m

The MATLAB function

STR=awe_lookupcodemarker(M, IDENTIFIER)

returns the contents of a code marker.  If IDENTIFIER is not defined, then the function returns an empty string.  The returned value STR is either a string, for simple replacements, or a cell array in the case of multi-line replacements.

...

awe_deletecodemarker.m

M=awe_deletecodemarker(M, IDENTIFIER)

...

Deletes all code markers associated with a module or subsystem.

...

Template Substitution Preprocessor

The template files also contain their own preprocessor directives.  These directives are similar to those used by the C preprocessor but are handled by the template substitution function.  The directives are identified by ## and only a few variations are supported.

...

#include "$baseHFileName$"

##endif

...

Frequently Defined Code Markers

This section lists out code markers that are frequently defined when developing custom audio modules.

...

$bypassFunction$

C code which specifies the inner portion of the bypass function.  When this is defined, the bypass function is written into generated C file.

...

$bypassFunctionName$

Allows you to specify a bypass function by name.  This is typically used in conjunction with one of the predefined bypass functions listed in Section 4.4.5.  For example,

...

  1. If $bypassFunction$ is defined, then the code is placed into the generated .c file and $bypassFunctionName$ is set to awe_modClassNameBypass,

  2. If $bypassFunctionName$ is defined, then this function is used for bypass behavior.  No additional code is placed into the generated .c file.

  3. Otherwise, the default bypass function IOMatchUpModule_Bypass() is used.  No additional code is placed into the generated .c file.

...

$constructorFunction$

Specifies the inner portion of a custom constructor function.  The function must follow the calling convention outlined in Section 4.4.1.

...

Modules created out of subsystems – Audio Weaver automatically generates code for these systems.  If you need further initialization, use the $postConstructorFunction $ shown below.

1.6.6.4.             $postConstructorFunction$

$postConstructorFunction$

This code marker follows immediately after the $constructorFunction$ code marker in awe_module_template.c.  This marker allows you to add your own code in cases where Audio Weaver generates the memory allocation and instantiation code but further initialization is needed.  It is particularly useful for subsystems.

...

$discussion$

Defines the discussion section of the help documentation.  This has been grandfathered for backwards compatibility.  When writing new modules, set the M.docInfo.discussion field of the audio module instead.

...

$getFunction$

Specifies the inner portion of a module's Get function.  Follows the calling convention outlined in Section 4.4.4.

...

$setFunction$

Specifies the inner portion of a module's Set function.  Follows the calling convention outlined in Section 4.4.3.

...

$hFileDefine$

Located near the top of the template file awe_module_template.h.  Allows you to add additional preprocessor directives (or anything else) at the start of the header file.  Example,

awe_addcodemarker(M, 'hFileDefine', '#define TRUE 1');

...

$hFileInclude$

Located near the top of the template file awe_module_template.h.  Allows you to include additional header files.

awe_addcodemarker(M, 'hFileInclude', '#define <stdlib.h>');

...

$processFunction$

Specifies the inner code for the module's processing function.  This must always be defined for modules.  For subsystems, the auto-generated should be used.  Refer to Section 4.4.2 for a discussion of how to define this function.

...

$preProcessFunction$

This code marker is located immediately before the $processFunction$ marker.  It is typically used with subsystems when you want to insert your code custom code immediately prior to the auto-generated $processFunction$.

...

$postProcessFunction$

Similar to $preProcessFunction$ but the code here is inserted immediately after the $processFunction$.  It is typically used with subsystems when you want to insert your custom code immediately after the auto-generated $processFunction$.

...

$srcFileDefine$

Located near the top of the template file awe_module_template.c.  Allows you to add additional preprocessor directives (or anything else) at the start of the source file. 

...

$srcFileInclude$

Located near the top of the template file awe_module_template.c.  Allows you to specify additional includes files. 

...

$hFileTemplate$ and $srcFileTemplate$

Audio Weaver uses the default template files specified at the start of Section 5.2.  You can override the templates used by a particular module by setting these code markers.  There are separate markers for the header file, $hFileTemplate$, and the source file, $srcFileTemplate$.  It is handy to override these values if you want to change copyright information in the generated files.

...

Fine Tuning Code Generation

This section contains further instructions for fine tuning code generation.  Many of the items apply to modules generated using compiled subsystems.

...

Automatically Generated Array Initializers

In many cases, an audio module requires a custom constructor function solely for the purpose of allocating indirect arrays.  If the size of the allocated memory can be defined using existing module variables, then Audio Weaver can automatically generate a constructor function.

...

To get around this problem, Audio Weaver allows you to specify a piece of C code which overrides the default numeric initializer for an internal module variable.  The C code is written to the .constructorCode field of the variable.  For an example, refer to the look ahead limiter example of Section 0. 

...

Avoiding Wire Allocation Problems with Subsystems

This issue also applies to the case of compiling subsystems to form new module classes.  If your subsystem has .flattenOnBuild=1 (which means that it is not compiled), then you can ignore this section.  This problem arises because Audio Weaver modules can operate on an arbitrary number of channels.  In certain circumstances, the routing algorithm incorrectly allocates wire buffers during code generation such that audio processing crashes at run-time.  In these cases, you need to be careful how you specify default channel counts and block sizes within modules.  The look ahead limiter example of Section 7.4 demonstrates the problem and presents a solution.

...

unique_classes.m

C=unique_classes(SYS)

where

...

This text can be pasted directly into TargetInfo.h.

...

awe_generate_module.m

M=awe_generate_module(M, DIRECTORY, WRITEFILES)

...