Plugin Reference

This page offers a detailed look at the structure and syntax of Nyquist Plugins. It is intended for people who wish to write their own plugins.

Overview

Nyquist is a superset of the XLISP programming language, (a dialect of LISP and supports both a LISP syntax and an alternative syntax called SAL. A general introduction to Nyquist is given on the main Nyquist page.

The Audacity Nyquist Interface is implemented in the following files in the Audacity source code:

  • audacity/src/effects/nyquist/Nyquist.cpp

  • audacity/lib-src/libnyquist/nyx.c

Nyquist is in many ways a separate program from Audacity (and is also available as a standalone programming language). Nyquist is embedded in Audacity as a software library that may be called from the main Audacity application to provide additional functionality, most notably as "plugins".

When a Nyquist plugin is selected from one of Audacity's menus, Audacity locates the plugin script (the ".NY" file), starts a Nyquist session and passes the Nyquist code to be interpreted by the Nyquist library. Nyquist then attempts to run the program. The result of running the Nyquist script is returned to Audacity.

Nyquist Plugin Header

As in most other computer languages, Nyquist supports code comments. Any line beginning with a semi-colon (;) is entirely ignored by Nyquist. Comments may also be placed at the end of a line of code by beginning the comment with a semi-colon. Nyquist ignores everything from the semi-colon to the end of the line.

In Audacity, special comments are used in Nyquist plugins to pass information to Audacity. As with other code comments, these are ignored entirely by Nyquist, but provide instructions to tell Audacity how to create the plugin.

Plugin Header Example

In this example (derived from the High-Pass Filter effect), the first four lines make up the essential headers that are required in all Nyquist plugins.

  • ;nyquist plug-in This header tells Audacity that this file is a Nyquist plugin.

  • ;version 4 This header specifies that this is a "4th generation" plugin.

  • ;type process This header defines the plugin as a "process" (Effect) type.

  • ;name "High-Pass Filter" This header tells Audacity the name of the plugin.

;nyquist plug-in
;version 4
;type process
;name "High-Pass Filter"
;preview linear
;manpage "High-Pass_Filter"
;debugbutton disabled
;action "Performing High-Pass Filter..."
;author "Dominic Mazzoni"
;release 3.0.2
;copyright "Released under terms of the GNU General Public License version 2 or later."

;control frequency "Frequency (Hz)" float-text "" 1000 0 nil

The other headers enable various options and properties, including the plugin's controls.

Full descriptions of all plugin headers are provide on the Nyquist Plugin Headers page.

Nyquist Plugin Widgets

Nyquist plugins support a range of "widgets", which are control elements for a graphical user interface (GUI). These elements are unique to Nyquist in Audacity.

The GUI is created by Audacity when a plugin contains one or more widget header commands.

As with other plugin headers, they begin with a semicolon (;) and are ignored by Nyquist, except that the variable name of the widget is initialized with a value and made available to Nyquist. This means that Nyquist can access the value that has been set in the widget as the value of the variable specified in the widget header.

Note: The "Text widget" is an exception to the above at it is for display purposes only and does not set a value.

Each widget begins with ";control", and is followed by a number of parameters, one of which defines the type of widget. There are currently nine widget types, though not all of them are available for old versions of Audacity.

When a plugin is launched, Audacity searches the plugin .NY file for valid headers. Every ";control" line that is found gets parsed by Audacity into several tokens, where each token is separated by spaces. If the tokens match one of the defined patterns, then Audacity adds the widget to the GUI, otherwise they are ignored.

Syntax for widgets

;controlvar-nametext-leftwidget-typetext-rightinitial-valueminimummaximum

;control

symbol

string

int

string

integer

integer

integer

;control

symbol

string

float (real)

string

float

float

float

;control

symbol

string

int-text

string

integer

integer / NIL

integer / NIL

;control

symbol

string

float-text

string

float

float / NIL

float / NIL

;control

symbol

string

string

string

string

-

-

;control

symbol

string

choice

string

integer

-

-

;control

symbol

string

time

string

float

float / NIL

float / NIL

;control

symbol

string

file

string

string

string

string

;control

-

-

text

string

-

-

-

Note: "real" (deprecated) is an alternative name for "float" and is provided as legacy support for old plugins. It should not be used in new code.

Italic words in the table denote data types. Because tokens are separated by whitepace, strings containing whitespace must be written within quotation marks.

Note: Older versions of Audacity may not support all of these controls, which may lead to an "unbound symbol" error. Plugin users are encouraged to use the current version of Audacity, to ensure that they can benefit from all of the latest features.

The following code may be run in the Nyquist Prompt of Audacity 2.3.1 or later, and produces the GUI shown above:

;version 4
;name "Plugin Widgets"

;control filename "File Button widget" file "" "" "" "open"
;control number-sw "Slider widget" float "(float)" 50 0 100
;control integer-sw "Slider widget" int "(integer)" 50 0 100
;control number-nt "Numeric Text widget" float-text "(float)" 50 0 100
;control integer-nt "Numeric Text widget" int-text "(integer)" 50 0 100
;control string-var "String widget" string "text right" "default string"
;control text "Text widget [string]"
;control duration "Time widget" time "text right" 30 nil nil

(format nil
        "File Selected: ~s~%~
        Floating point slider: ~s~%~
        Integer slider: ~s~%~
        Floating point text: ~s~%~
        Integer text: ~s~%~
        String: ~s~%~
        (Text widget does not return a value)~%~
        Duration: ~s (seconds)"
        filename
        number-sw
        integer-sw
        number-nt
        integer-nt
        string-var
        duration)

The detailed syntax for each widget type is described on the Nyquist Plugins Widgets page.

Tracks and Selections

Audacity passes information about the current Audacity session to the Nyquist interpreter, along with the Nyquist code. Typically, when the code runs, it acts on data that has been passed from Audacity, which often includes the selected audio data, and returns data back to Audacity. Here we shall look at the ways that audio data is passed from Audacity to Nyquist, and from Nyquist back to Audacity.

Passing Selected Audio to Nyquist

For process and analyze type plugins, Nyquist runs the plugin code on each selected track in turn. The audio data is passed from Audacity to Nyquist as a variable called *TRACK* (the asterisks are part of the name).

  • For mono tracks, the value of *TRACK* is a "sound" (which is a Nyquist data type).

  • For stereo tracks, the value of *TRACK* is an "array". An array is a special kind of ordered list. The array has two elements, both of which are "sounds". The first element holds audio data from the left channel, and the second element hold data from the right channel.

The selected audio is only available to "process" and "analyze" type plugins (including the compound types "tool process" and "tool analyze").

Time and Durations

The way that time and durations are handled depends on the type of plugin.

For process and analyze type plugins, the start time of the selection is seen as "time = 0", and the length of the selection is seen as one unit of time. The absolute length of the sound in seconds can be computed one of the following ways:

;Lisp
 (/ len *sound-srate*)
(get-duration 1)

;SAL
 len / *sound-srate*
get-duration(1)

NOTE: get-duration answers the question: "If a behavior has a nominal duration of 1, how long will it be after warping it according to the Nyquist environment?" Since many built-in behaviors like OSC and LFO have nominal durations of 1, In process effects, Audacity sets up the environment (including warp) to stretch them by the selection's duration. Otherwise, if you wrote (OSC C4), the result would have a duration of one second instead of the duration of the selection.

In 'generate' effects, this does not happen, so the length specified by the effect is the length that is produced. For example, if you write (OSC C4 3.5), a generate type effect will produce a tone of duration 3.5 seconds.

For generate type plugins, the length of the selection (if there is a selection) is usually ignored by Nyquist. However, if for some reason the length of the selection needs to be known, then *SELECTION* START and END properties may be used (version 4 plugins or later).

When generating sounds with a 'generate' type plugin, durations in Nyquist represent seconds. For example, to generate a 2.5 second sine tone, you could write:

;type generate
(osc 60 2.5)

but if the same code is used in a 'process' type plugin, the generated tone will be 2.5 x the duration of the track selection:

;type process
(osc 60 2.5)

If a duration in seconds is required in a 'process' type plugin, this may be done using the ABS-ENV command:

;type process
(abs-env (osc 60 2.5))

The above examples may be run in the Nyquist Prompt.

Global Variables and Reserved Variable Names

In addition to the standard global variables defined in the Nyquist Reference Manual, Nyquist in Audacity also has global variables that relate specifically to Audacity. Listed here are a few common standard Nyquist globals, and global variables that are relevant to Nyquist in Audacity.

  • *CONTROL-SRATE* : [float] The sample frequency of the control signals (such as those created by piecewise approximations. By default 1/20 of the sample rate of the track.

  • *DECIMAL-SEPARATOR* : [char] A comma character (#\') or dot character (#\.) depending on the language selected in Audacity's Preferences.

  • *FILE-SEPARATOR* : [char] The character that separates directories in a path, e.g. "/" (#\/) for Unix, ":" (#\:) for Mac, and "\" (#\\) for Win32.

  • LEN : [int] The number of samples contained in the selected Audacity sound.

  • *LOCALE* : [list] This is variable name is reserved for translation strings.

  • *PREVIEWP* : [bool] True when previewing an effect, otherwise false.

  • *RUNTIME-PATH* : [string] Path to Nyquist .lsp files.

  • *PROJECT* : A variable with a list of properties relating to the current Audacity project.

  • S (obsolete) : [sound or array of two sounds] Prior to version 4 plugins, in process and analyze type plugins this was the Audacity sound [the selected part of the Audacity audio track]. In generate type plugins "S" is the Adagio notation for a quarter note (float value 0.25).

  • S : Adagio notation. [float] A quarter note (float value 0.25).

  • *SCRATCH* : [any] a symbol whose value and property list are preserved from one effect invocation to the next.

  • *SELECTION* : A variable with a list of properties relating to the current selection.

  • *SOUND-SRATE* : [float] The sample frequency of the selected track audio.

  • *SYSTEM-DIR* : A variable with a list of properties relating to the file system.

  • *SYSTEM-TIME* : A variable with a list of properties relating to the system time/date.

  • *TRACK* : [sound or array of sounds] The Audacity sound [the selected part of the Audacity audio track]. The *TRACK* variable also has a list of "properties" that pass additional information to Nyquist.

  • *WARP* : information that communicates start-time and duration to Nyquist functions. In Audacity, the start-time is always considered to be zero (regardless of the actual start time of the selection) and the duration indicates the duration of the selection. *warp* should not normally be accessed directly.

Other global variables provided by Nyquist can be found in the Nyquist manual index.

Global Property Lists

Property lists are defined for the global variables *AUDACITY*, *PROJECT*, *SELECTION*, *SYSTEM-DIR*, *SYSTEM-TIME*, and *TRACK*.

For examples using property lists, see the Nyquist Property List Tutorial.

*AUDACITY*

This property list was added in Audacity version 2.1.0

Value: Unbound (not defined).

  • LANGUAGE : [string] The country code for the language set in Audacity Preferences. Example - when Audacity's locale setting is for English, (print (get '*audacity* 'language))will print en.

  • VERSION : [integer list] A list in the form (Audacity_version Audacity_release Audacity_revision) Example: Print the full Audacity version for Audacity 2.1.3 (let ((version-list (get '*audacity*' version))) (format nil "Audacity version ~a.~a.~a" (first version-list)(second version-list)(third version-list))) Prints: Audacity version 2.1.3

*PROJECT*

Value: Unbound (not defined).

  • LABELTRACKS : [integer] The number of label tracks in the project.

  • MIDITRACKS : [integer] The number of note tracks in the project.

  • NAME : [string] The name of the current project. A project that has not been named (not yet saved) returns an empty string.

  • PREVIEW-DURATION : [float] The Effects Preview Length set in Audacity preferences.

  • PROJECTS : [integer] The number of open projects.

  • RATE : [integer] The project rate in the project.

  • TIMETRACKS : [integer] The number of time tracks in the project.

  • TRACKS : [integer] The number of tracks in the project.

  • WAVETRACKS : [integer] The number of audio tracks in the project.

*SELECTION*

Value: Unbound (not defined).

  • BANDWIDTH : [float] The bandwidth of the frequency selection in octaves (Spectrogram or Spectrogram (log f) track view).

  • CENTER-HZ : [float] The centre frequency selection in Hz (Spectrogram or Spectrogram (log f) track view).

  • CHANNELS : [integer] The number of selected audio channels.

  • END : [float] The end of the selection in seconds.

  • HIGH-HZ : [float] The high frequency selection Hz (Spectrogram or Spectrogram (log f) track view).

  • LOW-HZ : [float] The low frequency selection Hz (Spectrogram or Spectrogram (log f) track view).

  • RMS : [float or array] For mono tracks, the RMS amplitude (linear scale). For stereo tracks, an array containing the RMS for each channel.

  • PEAK : [float or array] For mono tracks, the absolute peak level (linear scale). For stereo tracks, an array containing the absolute peak level for each channel. Returns 'NIL' if peak level is infinite or NaN.

  • PEAK-LEVEL : [float] The absolute peak level (linear scale). Returns 'NIL' if peak level is infinite or NaN.

  • START : [float] The start of the selection in seconds.

  • TRACKS : [integer list] A list of track numbers of selected audio tracks.

*SYSTEM-DIR*

Value: Unbound (not defined).

  • BASE : [string] The Audacity installation directory.

  • DATA : [string] The Audacity data directory. This is where the audacity.cfg, pluginregistry.cfg and EQCurves.xml files are located.

  • DOCUMENTS [string] The system default documents directory.

  • HELP : [string] The installation directory for the Audacity Manual (note that the Manual may not exist).

  • HOME : [string] The current user's "home" directory.

  • PLUG-IN : [string list] The Nyquist plugin search path. This includes the directories where Audacity looks for Nyquist plugins, and other Nyquist related files. Not all directories are currently used and some are for legacy support only.

  • SYS-TEMP : [string] The system temp directory.

  • TEMP : [string] The Audacity temp directory. This is where unsaved project data is temporarily stored.

  • USER-PLUG-IN : [string] The default path for user plugins.

*SYSTEM-TIME*

This property list was added in Audacity version 2.1.1.

Value: A list in the form '(year, day, hours, minutes, seconds), where each list item is an integer.

Example: 5 minutes past 2pm January 1st 2022 would be the list: 2022, 1, 14, 5, 0.

Note that "day" is a number in the range 1 to 366, counted from the start of the year.

This is the time that the Nyquist code is parsed, NOT the time it is executed. It cannot therefore be used for timing events that occur while the code is running. Possible uses for *SYSTEM-TIME* could include automatic naming of files written to disk, or for "seeding" random processes.

  • DATE : [string] The date formatted according to the current locale. Example: "dd/mm/yy".

  • DAY : [integer] Day of the month.

  • DAY-NAME : [string] The name of the day (Example: "Monday").

  • ISO-DATE : [string] The date represented in the ISO 8601 format "YYYY-MM-DD".

  • ISO-TIME : [string] The time represented in the ISO 8601 format "HH:MM:SS".

  • MONTH : [integer] The month (as an integer).

  • MONTH-NAME : [string] The name of the month (Example: "January").

  • TIME : [string] The time formatted according to the current locale. Example: "hh:mm:ss".

  • YEAR : [integer] The year (as an integer).

*TRACK*

Value: The sound from a selected mono audio track, or an array of two sounds from a selected stereo track (see the Nyquist Stereo Track Tutorial).

Properties of *TRACK* all relate to the track that is being processed. Currently Nyquist only processes audio tracks. When multiple tracks are selected, Nyquist processes each audio track in turn (top to bottom).

  • CHANNELS : [integer] The number of channels in the track (mono = 1, stereo = 2).

  • CLIPS : [list or array] For mono tracks, a list of start and end time of each audio clip. For stereo tracks, an array containing a list of clips for each channel. Due to a limitation in Nyquist, the "clips" property can hold a maximum of 1000 start / end times. If an audio channel contains more than 1000 clips, the first 1000 will be listed, and the 1001th item will be NIL. See AUD-GET-INFO for an alternative way to get clip times that will work with 1000's of clips.

  • END-TIME : [float] The track end time.

  • FORMAT : [integer or float] The track sample format. One of (Integer) 16, (Integer) 24, or (float) 32.

  • GAIN : [float] The value of the track Gain slider.

  • INDEX : [integer] A counter that increments for each track processed. On processing the first track, the value is "1".

  • NAME : [string] The name of the track.

  • PAN : [float] The value of the track Pan slider.

  • RATE : [float] The track sample rate.

  • SPECTRAL-EDIT-ENABLED : [bool] Returns 'T' (true) if spectral editing is enabled, otherwise 'NIL'. Note that this is irrespective of the track view and will return 'T' if the spectral editing option for the track is enabled even if the track is not displaying a spectrogram.

  • START-TIME : [float] The track start time (note that this will often be different from the selection start time.)

  • TYPE : [string] The type of track. One of: "wave", "midi", "label", "time". Currently only "wave" (audio tracks) are processed by Nyquist plugins.

  • VIEW : [string or list] The track view. Only applies to audio tracks. * A single track view returns one of "Waveform", "Spectrogram" or NIL. Multi-View returns a list of strings or NIL. * Multi-view returns the upper view as the first element, and the lower view as the second (either "Waveform" or "Spectrogram"). Both normal "Waveform" and "Waveform (dB)" return the string "Waveform". * Prior to Audacity 2.4.x : [string] One of: "Waveform", "Waveform (dB)", "Spectrogram" or NIL.

The VIEW property may change in future versions of Audacity, so is not recommended for public release plugins. During Preview, audio tracks are copied to temporary tracks which are not visible, so the returned "VIEW" value is NIL.

Return Values

Nyquist supports many "data types", including "numbers" (integer or floating-point), "characters" (such as the letter "A", the number "4", or any other ASCII character), "strings" (text), "list" (a list of data), "array" (special kind of indexed list), and "sounds" (a sound / digital signal).

The result of the last computation within the plugin code will be given back from Nyquist to Audacity. According to the data type of the returned value one of the following actions will be invoked in Audacity:

Mono Sound

If a "sound" is returned, the sound will be re-inserted into the selected part of the Audacity track, (or a new track for "generate" type plugins). If the returned sound is shorter or longer than the original sound, the selection will be reduced or augmented. If a mono sound is returned to a stereo track, the same mono sound will be inserted into both channels of the stereo track.

Multi-Channel / Stereo Sound

Nyquist handles multi-channel sounds as an array of sounds. The first element of the array is the left channel, and the second element is the right channel. Audacity currently supports a maximum of two channels in a track (stereo).

Returning an array of sounds to a mono track is an error.To return a stereo sound without error, a stereo track must be selected before running the Nyquist code.

For more information about stereo tracks, see the Nyquist Stereo Track Tutorial.

String / Text

When the return value is a character or string, a dialog window will appear with the data displayed as text.

Number

A dialog window will appear with the number displayed as text.

Labels

If an appropriately formatted list is returned to Audacity, a label track will be created below the audio track(s).

For point labels the format is:

((number ``"string") (number ``"string") ... )

The list to create a label track must contain one or more lists, each of which must have:

  • number - (an integer or float) is the time in seconds from the beginning of the Audacity selection, where the label will appear.

  • "string" - a string to be displayed in the label's text field.

For region labels, each label list must contain two int-or-float elements, one for the start and one for the end of the label region.

((number````number ``"string") (number````number ``"string") ... )

Audacity will always place returned audio or labels relative to the start of the selection and not the start of the Timeline.

Empty String

An empty string may be used as a "null return", which means that the plugin returns nothing, and no error. An example use would be if you wish to process only the first selected track.

;; Example: Apply a function "process" to
;; the first selected track only.

(if (= (get '*track* 'index) 1)
    (process *track*)
    "")

Playing sounds with Nyquist

When using the Nyquist Prompt or (most) Nyquist plugins that have a GUI, if the plugin returns a sound, it may be previewed using the Preview button. In addition to this, it is also possible to play sounds directly from Nyquist, using the PLAY function. The PLAY function will be executed when the plugin code runs.

The PLAY function is described in the Nyquist manual. The information here describes aspects that are specific to Nyquist in Audacity.

Note that the Nyquist PLAY command does not use Audacity's audio device settings. Nyquist uses the system default device for playback, and has a default buffer of 100 ms. The buffer setting may be changed with the SND-SET-LATENCY command. The actual latency values are dependent on the computer sound system and may differ from those requested by Nyquist.

To see the list of available devices when Nyquist plays, set *snd-list-device* to "true" before the play command, then use Debug button to see the output.

(setf *snd-list-devices* t) (play *track*)

To select a specific output device, set *snd-device* to the index number of the device you wish to use (not all devices are valid). For example, if ALSA hw(0,0) is device 0, select it with:

(setf *snd-device* 0) (setf *snd-list-devices* t) (play *track*)

It is not possible to interrupt Nyquist playback. The sound will continue playing until it reaches the end, and other Audacity functions are disabled until Nyquist playback has finished.

To limit the amount of audio that will play, the length of the sound must be defined before starting playback. For example, to play the first 1 second of a selection, you could write (LISP syntax):

(play (extract-abs 0 1 *track*))

Note also that if a plugin uses Nyquist PLAY command, using Previewwill cause an error on some machines because Audacity may not be able to access the audio device while it is being used by Nyquist. For "own use" plugins, if you have more than one sound card, a possible workaround to enable Preview and Nyquist PLAY simultaneously, is to set the Nyquist playback device to a different device to that which Audacity uses. For public release plugins the Preview button should normally be disabled if Nyquist PLAY is used.

Plugin Translations

Nyquist plugins provide two mechanisms for translation into the language specified in Audacity's preferences.

One method is exclusively for plugins that are shipped by default with Audacity and requires compiling Audacity from source, plus several other steps involving gettext. Unfortunately this method is not documented, so only a brief description is provided here.

The other method may be used by plugin developers for their "third party" plugins, but can be used only for returned strings and not for the main plugin interface.

Translation for shipped effects

Header comments in translated plugins begin with a dollar "$" character rather than the usual semicolon ";" character. The strings to be translated are then wrapped in a function that has a one character name "_" (underscore).

Example: In the Adjustable Fade effect, the Name header is changed from:

;name "Adjustable Fade"

to:

$name (_ "Adjustable Fade")

;control lines become $control. As with other translated headers, the $ symbol replaces the normal semicolon. The line is ignored by Nyquist as a comment, but is visible to Audacity for translation and for creating a widget.

The options in Multiple-choice widgets may be translated. For example:

;control var (_ "Translated left text") choice ((_ "Yes") (_ "No")) 0

The above example is not safe to use. See the "Limitations" section below.

Macros and portability: To allow portability of settings and macros, choices may include a non-translated form of each choice. The non-translated form is used by Macros but is not normally visible to users.

;control var (_ "Translated left text") choice (("Label1" (_ "Translated Label 1")) ("Label2" (_ "Translated Label 2"))) 0

Other user visible strings: Other strings that are visible to users are marked for translation using the "underscore" function. An example from the Adjustable Fade plugin:

(format nil (_ "~aPercentage values cannot be negative.") err)

Limitations

Control characters like (new line), (tab) are not supported. The workaround is to use Lisp format directives instead:

  • Bad (does not work correctly):

(print (_ "Line one.\nLine two."))

  • Good:

(print (format nil (_ "Line one.~%Line two.")))

Note that translations may contain Unicode characters that are not supported by Nyquist. It is therefore important that any translated strings that need to be machine readable (such as Multiple-Choice widget options) should also have a non-translated form.

;control var (_ "Translated left text") choice (("Label1" (_ "Translated Label 1")) ("Label2" (_ "Translated Label 2"))) 0

Translation for third party effects

It is not currently possible to provide translations for a third party plugin's main interface, unless the name is the same as a translated Nyquist plugin that is already shipped with Audacity. It is highly recommended to NOT reuse the same name as a shipped plugin for a third party plugin.

Translations may be provided for return value messages and debug messages. To do this, the string must be marked for translation by wrapping it in the "underscore" function. The translation must also be provided in a specially formatted list variable *locale*.

The format for the *locale* list is: (LIST (language-list) [(language-list) ...])

where "language-list" is a list in the form: (LIST country-code (translations))

and the "translations" are list in the form: (LIST (List "string" "translation") [(List "string" "translation")...])

  • The *locale* list may contain any number of "language-list" elements, where each language-list is a list of two strings.

  • The first element of each "language-list" is the country code (for example "en" or "fr"),

  • The second item of each "language-list" is a list of translation pairs.

  • A "translation pair" is a list containing the default string (usually in English) and the translated string (in the language specified by the country code).

A working example may be found in the RMS effect.

See Also

Last updated