AAX SDK  2.4.1
Avid Audio Extensions Development Kit

How to test basic functionality of AAX plug-ins using DSH test tool.

Contents

What is DSH and how it works

DigiShell is a software tool that provides a general framework for running tests on Avid audio hardware. As a command-line application, DigiShell may be driven as part of a standard, automated test suite for maximum test coverage. DSH supports loading all types of AAX plug-ins except AS, and is especially useful when running performance and cancellation tests of AAX-TI types. DigiShell is included in Pro Tools Development Builds as dsh.exe (Windows) or as dsh in the CommandLineTools directory (Mac).
After it is launched, DigiShell waits for a command name and parameters to be entered via stdin; command results are output via stdout. DigiShell parses its input as command name, followed by a single space, and then command parameters. The command parameters are expected to be a yaml-encoded string. Here are two examples of strings in compact (single-line) yaml format:

Basic set of commands of the DAE dish

DigiShell has built-in commands for getting help, creating a DigiTrace configuration and loading DigiShell modules known as "dishes". One can see the command list by running the help command without any parameters. Passing a command name as a single string parameter to the help command will give a more detailed command description.
The default installation of DigiShell includes a few dishes, including the DAE dish. This dish loads the AAE audio engine and can be used for loading and testing basic functionality of plug-ins. The DAE dish can also be used to load a plug-in for basic debugging purposes, and provides a ligher-weight debugging environment than the full Pro Tools application.
Another dish supplied with DSH, the aaxh dish, provides a lower-level hosting environment for AAX plug-ins. This dish loads a dedicated AAX host component without audio routing logic or other audio engine responsibilities. In this guide we will focus on loading and running plug-ins using the DAE dish, but we encourage you to also explore the commands available in the aaxh dish and to learn how to exercise your plug-ins in that environment.

Loading plug-ins in DSH

The following commands can be used to load and configure the DAE dish:
Loading the DAE dish into the DigiShell environment with the built-in load_dish command will extend the set of available commands. Amoung them there is a run command. The run command can be used in two ways:
You can also search for the id and spec of the specific plug-in with the findpi command, which takes a plug-in's name or part of it as an argument, and then searches through the whole list of available plug-ins using this pattern.
DSH commands for loading plug-ins
Figure 1: DSH command for loading plug-ins.
If the plug-ins was instantiated successfully, then DSH will list all its parameters, just like on the screenshot. If instantiation fails, then DSH in most cases will output the error code, although it is not always obvoius what this error code means. Here is the list or possible reasons of some failures:
-30xxx errors are dynamically-generated and can indicate different failures. Failures due to plug-ins exceeding the cycle limit of the DSP CPU will often appear as -30xxx errors. See -30xxx: Dynamically-generated error codes in the TI DSP Guide for more information.
Note
run command works for Native and DSP plug-ins, but not for the Audio Suite ones. Also it will fail for DSP Hybrid plug-ins. To be able to instantiate them, one should run acquiredeck command.
There are several DAE dish commands for operating with plug-ins' instances:

Working with HDX card from DSH

One of the benefits of the DAE dish in DigiShell is that it has direct access to the shell environment that loads DSP plug-ins. The included facilities for retrieving load error information from the DSP manager can be very helpful for debugging DSP plug-in load failures. For example, you can use the following DAE dish commands to determine what resource requirement is preventing additional instances from loading onto a single DSP:
  1. reservetidsp all
    Reserves all unused DSPs in the system
  2. unreservetidsp 0
    Frees the first DSP for plug-in allocation
  3. getlastdsploaderror
    Retrieve the text of the error that was generated when the final Effect instance attempted to load
  4. getdspinfo 0
    Returns detailed info about the DSP chip with the given index. By executing this command you can figure out whether particular chip is in use currently, which plug-ins are instantiated there, how many resources they consume and how many resources are still available.

    Info about the DSP chip with the given index Info about the DSP chip with the given index
    Figure 2: Info about the DSP chip with the given index.

DAE dish tips

Basic plug-in tests

There are some basics tests that can be performed for AAX plug-ins in DSH. Among them are instantiation test, measuring of amount of processor cycles that DSP plug-in may consume on different settings, cancellation test and so on.

Cycle count performance test

Use the DAE.cyclesshared command in the DAE dish to profile a DSP algorithm's cycle count performance. This command measures both the shared and the per-instance cycles used by a plug-in, both of which must be reported to the host. This command also includes the option to load a custom plug-in preset so that various algorithm code paths may be exercised. It is important to report the maximum possible number of cycles that the plug-in may need, so that it had enough resources, even in the worst case. Otherwise one can obtain noise and clicks in the output audio on the extreme plug-in's settings.
The full syntax of this command is as follows:
cyclesshared <index — spec — {key:value, key:value, etc.}>
index - Index of the plug-in as listed by the DAE.run command
spec - Plug-in ID triplet in array, e.g. ['AVID', 'DmGn', 'DGDT']
key:value hash options:
idx - Index of the plug-in
spec - Plug-in ID triplet array
run_cached: <true — false> - Whether to use cached code when measuring. Defaults to false.
load_preset: <filename> - Load the specified preset for each instance before measuring performance
adjust_controls: <true - false> - Randomly change the plug-in's parameter state before running the test
Examples:
Normal output of this command should look like this:
Normal cyclesshared command output
Figure 3: Normal cyclesshared command output.
Sometimes during the development process it may happen that this test fails, and the reason of such a failure can be different:
  1. Plug-in exceeded the DSP chip's memory limit

    Plug-in exceeded the memory limit
    Figure 4: Plug-in exceeded the memory limit.
  2. Plug-in exceeded the processors cycles budget
    • The number of instance and shared cycles looks acceptable, but expected number of plug-in's instances that can be instantiated on the chip/card at different sample rates is zero. Resultant cycle count can be used for calculating how much plug-in has exceeded the limit, and how much it should be optimized.

      Plug-in exceeded the processors cycles budget
      Figure 5: Plug-in exceeded the processor cycles budget.
    • If plug-in exceeds the processor's cycles budget too much, then cyclesshared test will most likely output the warning that is highlighted with orange color on the screenshot below. Also the number of both instance and shared cycles will be shown as zero or one.

      Plug-in exceeded the processors cycles budget very much
      Figure 6: Plug-in exceeded the processor cycles budget very much.
  3. Plug-in processing is not balanced.
    If some big parts of code, which do not really depend on the specific plug-in settings, are located under condition structures, and if they make plug-in to do more calculations in one case and less in another case, then that means that plug-in's processing is not balanced. This may cause some problems, because it is hard to predict when this or that condition may become true and how much the amount of processor's cycles that plug-in needs will increase. So it is better to remove such conditional blocks and to performe those calculations every time, even if their result is not really needed in particular cases.
    To indicate such situations the correlation coefficient can be used. If its value close to zero, then plug-in has the described problems.


    Plug-in processing is not balanced

    Figure 7: Plug-in processing is not balanced.

Performance profiling and test signals

Some algorithms' performance characteristics are program-dependent, and in such cases use of the the cycles command alone may not be sufficient. To route a test signal to your plug-in while measuring cycles, use of the cycles command along with the load_wav_file command in the DAE dish. The basic approach is as follows:
Example:
  1. piproctrigger manual
    set to single-buffer processing
  2. load_wav_file "testaudio_pt1.wav"
  3. load_wav_file "testaudio_pt2.wav"
  4. load_wav_file "testaudio_pt3.wav"
    load audio buffers; take note of return ...
  5. run <mypluginIndex>
  6. load_settings "mySavedSettings.tfx"
    load the settings
    OR
    control [1,24] # set controls directly
  7. cycles b1
    measure cycles while processing first file
  8. load_settings "mySavedSettings2.tfx"
    load the next settings
  9. cycles b2
    measure cycles while processing second file
    ... etc.

Cancellation test

When porting plug-ins from RTAS to AAX platform, or form 32-bit to 64-bit architecture, or from Native to DSP, it may be useful to compare output of two plug-in's versions to make sure that it is still the same and nothing has been broken. For this purpose DSH cancellation test can be used.
In the simplest case, when both plug-ins are present in the same version of Pro Tools (Native and DSP version of the same plug-in for example), then diff command can be used to perform the test:
diff [ <spec1>, <spec2>, <frames> ]

which reports the peak difference in the output amplitude of plug-ins <spec1> and <spec2> after processing <frames> frames of a 1 kHz full-scale sine wave. The maximum difference will be provided in dB.

Another way to perform the cancellation test is to process audio with each plug-in separately manually and to compare the result after that. This scenario allows you to load custom input audio file and special plug-in settings:
  1. piproctrigger manual
    This command should be run for DSP plug-ins before loading them. When this option is set, DSP plug-in will start process audio only after piproc command is called. Otherwise it will start processing right after the instatiation process.

  2. run 81
    Laoding plug-in

  3. load_settings "/Users/settings/pitch_settings.tfx"
    Loading settings file

  4. load_wav_file "/Users/audio_files/mono_file.wav"
    Wav file will be loaded in a buffer, or in several buffer if it has more than one channel. Command will output references to the buffers, like b1, b2 ...
    Note
    It is not recoomended to choose very long audio files for the DSP proceesing, since the test is very slow, and processing of 10 sec audio file may take up to 1 min depending on the complexity of the plug-in's algorithm.
  5. bclone b1
    The easiest way to create the output buffer of the same size is to copy th einput buffer. Command will also output references to the resultant buffers.

  6. piproc [b1, b2]
    Command which actually is doing passes the input audio through the current plug-in, and is recording the result to the output buffer (which is b2 here). For stereo plug-in command will look like piproc [[b1,b2],[b3,b4]]

  7. bfsave [b2, "/Users/saved_buffer"]
    Output buffer can be stored to the disk. This may be needed for the cases, when one wants to compare the output of plug-ins, which can not be loaded in the same instance of the DSH. So the output of one plug-in can be saved to disk and then loaded later in the anothe instance of DSH. Also output buffer can be saved as .wav file with save_wav_file command.

  8. bfload "/Users/saved_buffer"
    Saved buffer can be loaded again by this command. It will output the reference to the newly created buffer.

  9. bacmp [b1,b2]
    This command will compare the contents of the buffers b1 and b2. So it can compare the output buffers of two plug-ins and thus make the cancellation test.

Debugging and tracing in DSH

DSH provides a lighter-weight debugging environment than the full Pro Tools application. So it should be easier to step though the description code of the plug-in there, rather the in PT, because DSH does significantly less initialization work than PT during the loading process.
Also DSH is very useful in situations, when one wants to debug the plug-in's algorithm on a specific audio buffer. The only way to follow plug-in's algorithm work step-by-step on the certain piece of audio is to debug the piproc command.
DSH supports tracing, which is based on Avid's DigiTrace. To enable trace logs in DSH, one should create a dsh.digitrace config file for it and put it next to dsh executable file. It can be the same as .digitrace file for the Pro Tools. DSH has built-in commands to generate a DigiTrace config file. The clear_trace_config command creates (or clears if it already exists) a DigiTrace config file. The enable_trace_facility command enables logging of a specified facility/priority pair.
Note
On the Mac, DigiShell must be relaunched before a new DigiTrace configuration will take effect.

Scripting interface and batch profiling

DigiShell can be scripted using DishTestTool, a Ruby-based command line tool. More details can be found in DTT Guide.
Collaboration diagram for DSH Guide: