Nyquist Plug-ins Reference

From Audacity Wiki
Jump to: navigation, search
Peter 28Dec16: ToDo-2 this page is a VERY long and hard read (TL;DR) it may benefit from restructuring and breaking up some, sub-pages maybe?
This page offers a detailed look at the structure and syntax of Nyquist Plug-ins. It is intended for people who wish to write their own plug-ins.
If you are looking for extra Nyquist plug-ins to use, see Nyquist Plug-ins.
 
Related article(s):


Nyquist is based on XLISP, (a dialect of LISP and supports both a LISP syntax and an alternative syntax called SAL. LISP syntax is more commonly used in Nyquist plug-ins for Audacity, though users that have experience with C-like languages may find SAL more familiar.


If you are especially interested in Nyquist in Audacity, we highly recommend subscribing to our Audacity forum, which has a section specifically for matters relating to Nyquist.
Steve 26Oct15: ToDo-2 The images on this page need updating to current Windows screenshots

Contents


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


Overview

Nyquist plug-ins are simple text files ending with the file name extension ".ny". When Audacity starts, it looks in a plug-ins directory for files and automatically adds the effects it finds there to the Audacity menus. The plug-ins can be written in either LISP or SAL syntax. When the user selects the plug-in from the menu, Audacity causes the Nyquist language runtime system (built into Audacity) to run the plug-in code to process or generate audio. You can also compute strings to display to the user or compute labels to be shown on a new label track.

Before running the plug-in, Audacity parses some of the plug-in text looking for specially formatted comments that describe "widgets" -- controls that the user can use to set parameters for the effect. For example, your plug-in can display a slider to control volume or filter frequency. Values from the widgets are passed through global variables to the plug-in.

For a full description of the plug-in language, read the Nyquist Reference Manual. There are, however, some details of how plug-in code is processed that is unique to Audacity plug-ins and therefore not covered in the Nyquist manual. The main thing to know is that the variable "*TRACK*" in version 4 or later syntax ("S" in earlier versions) is the selected sound. This is probably the main input to your effect. The second thing to know is how sound is returned from Nyquist to Audacity.

SAL syntax is inherently command oriented. A SAL plug-in should consist of a sequence of SAL commands including define commands to define variables and functions. There must be a function definition for "main". After performing the commands in sequence, Audacity calls "main" (with no parameters). The value returned from "main" is the result of the plug-in (normally this should be a sound).

One exception to this is the Nyquist Prompt... effect. Since defining "main" just to evaluate and return a simple expression is so awkward, you can simply type

 return expression

Normally, this is not a legal statement as a top-level command in SAL, but in Nyquist Prompt..., special processing embeds the return statement into a declaration of function "main", which is then called. This trick also works for regular plug-ins, but defining "main" is the preferred style.

For LISP syntax plug-ins, Lisp expressions are read and evaluated one-at-a-time. The value returned by the last expression is the result of the plug-in. The same semantics applies to the Nyquist Prompt... effect. There is only one "Nyquist Prompt" for both SAL and LISP syntax. Audacity looks for the first character that is not a space or part of a comment. If it is an open paren "(", then the code is assumed to be LISP; otherwise, SAL is assumed.

Update this in due course when 2.1.0 is obsolete

From version 2.1.1, the Nyquist Prompt effect can interpret header comments and produce a plug-in of the defined type on the fly. By default the plug-in is a process type, though other type may be created by including the appropriate header. In older versions of Audacity the "Nyquist Prompt" effect is not equivalent to plug-ins because Audacity processes the plug-in header information from plug-in files, but the "Nyquist Prompt" effect ignores them (they are just comments).

Nyquist is a superset of the XLISP programming language and as such is limited to single-byte ASCII characters. The results of using characters outside the range of ASCII 32 to 126 in Nyquist plug-ins are unspecified. While the use of characters outside of this range may work satisfactorily for personal use on some operating systems, plug-ins for public distribution must currently be written using only standard characters (ASCII characters 32 to 126). This applies to plug-in code, comments and string data.

Nyquist Plug-in Header

Important:
  • In the Nyquist plug-in header there must be only one single semicolon at the beginning of each line because these lines are parsed by Audacity.
  • Headers must be all lower-case except for quoted text (for example: "name") which may include upper-case characters.

The Nyquist Lisp interpreter as well as the Nyquist SAL compiler in contrast recognize everything after the first semicolon up to the end of the line as a comment and just simply ignores it. So in the Nyquist code, below the plug-in header, comments can also be started with several semicolons in a row.

  • Essential plug-in headers:

These headers are required in all Nyquist plug-ins.

 ;nyquist plug-in
 ;name "name"
 ;type "type"
 ;version version
  • Aditional headers:

These headers may be used to provide additional functionality.

 ;action "text"
 ;author "text"
 ;codetype type
 ;copyright "text"
 ;debugflags flags
 ;maxlen integer
 ;mergeclips integer
 ;preview option
 ;restoresplits integer
 ;control parameters
  • Deprecated headers:

These headers are no longer used by current versions of Audacity and are ignored.

 ;categories "text"
 ;info "text"


Required plug-in headers

nyquist plug-in

Tells Audacity "this is a Nyquist plug-in". This should normally be the first line as it defines the contents of the file.

 ;nyquist plug-in


name

Name of the plug-in as it will appear in the Audacity menu:

 ;name "name"

Note that for plug-ins to be used in Chains, the colon character ":" cannot be used (as it is a special character in the Chain text file).

If the plug-in has an interface, the name should end with three dots so as to indicate that additional user action is required before the plug-in is applied. Plug-ins that act immediately without additional user action should not have dots at the end of the name.


type

Only one ";type" line is needed. A plug-in cannot appear in several Audacity menus at the same time. But it is possible to write several plug-ins with the same name but with different ";type" lines, which then will appear under the same name in different Audacity menus. But please do this only if you really need it.
type analyze

Plug-in appears in the Audacity Analyze menu:

 ;type analyze
type generate

Plug-in appears in the Audacity Generate menu:

 ;type generate
type process

Plug-in appears in the Audacity Effect menu:

 ;type process


version

Use only one ";version" line. New plug-ins should use the version with the highest number so that all current features are available. The version line is required to allow Audacity to run the plug-in correctly and prevents plug-ins with new features from being loaded in an old Audacity program that is missing required features.
version 1

Only the Slider widget is supported:

 ;version 1
version 2

The Text input widget was added in Audacity 1.2:

 ;version 2
version 3

The multiple-Choice widget was added in Audacity 1.3:

 ;version 3
version 4
  • Additional global variables were added in Audacity 2.1.0 to pass additional information from Audacity to Nyquist.
  • New optional plug-in headers:

These headers are ignored by versions of Audacity that are older than the version stated.

    • ;author and ;copyright were added in Audacity 2.1.0.
    • ;preview, ;mergeclips and ;restoresplits were added in Audacity 2.1.1.
    • ;maxlen was added in Audacity 2.1.2.
 ;version 4


Aditional plug-in headers

action

Text to be displayed while the plug-in is working:

 ;action "text"


author

Name of the plug-in Author. If this line is added, its text will appear in the Audacity Effect Menu when sorted or grouped by "Publisher".

 ;author


codetype

codetype lisp

The syntax of the plug-in is Lisp. This is the default if the "codetype" line is missing:

 ;codetype lisp
codetype sal

The syntax of the plug-in is SAL. The default is "lisp".

 ;codetype sal


control

Define a plug-in widget. There can be several "control" lines in the plug-in header. Add one for each widget to appear in the dialog box -- see Nyquist Plug-in Widgets below. The ;control headers should normally be the final headers as they define variables used by the Nyquist code.

 ;control parameters


copyright

A short statement of the copyright/license terms. For plug-ins shipped with Audacity, this must be compatible with Audacity's GPL v2 license. Recommended text for GPL v2 license:

;copyright "Released under terms of the GNU General Public License version 2"

Additional copyright details may be included in the plug-in code comments, but must not conflict with the terms declared here.

 ;copyright


debugflags

See Internal Debug Options below:

 ;debugflags flags
Internal Debug Options

There is an optional "debugflags" line available, which skips the plug-in window and directly executes the plug-in code, so if a "debugflags" line is found in the plug-in header no user-interaction is possible.

Set *tracenable* to true. The plug-in behaves as if the "Debug" button was clicked by the user. This is the default:

 ;debugflags trace

Set *tracenable* to 'false'. The plug-in behaves as if the 'OK' button was clicked by the user:

 ;debugflags notrace
 	

Set *sal-compiler-debug* to true. This prints the compiler's translation of SAL to LISP before evaluating the translated code:

 ;debugflags compiler

Set *sal-compiler-debug* to 'false'. This is the default.

 ;debugflags nocompiler
In the Nyquist Workbench, the "compiler" and "nocompiler" debugflags control whether the generated Lisp code from the SAL compiler will be sent to "stdout" or to the output window in the Nyquist Workbench.


maxlen

Specifies the maximum number of samples to be processed. This can help the progress bar if length that will be processed is determined by the plug-in rather than by the length of selection. It could also be used as a fail-safe for plug-ins that are specifically designed for short selections. This example limits the number of samples to 1 million:

 ;maxlen 1000000


mergeclips

Allows Nyquist plug-ins to override Audacity's default "clip merge" behaviour. By default, when effects (including generator effects) are applied across one or more clip boundaries and the returned audio is a different length from the original selection, Audacity will add "split lines" at the ends of the returned audio. In all other cases, the returned audio is "merged" into the current audio.

This option only applies when the plug-in is applied across clip boundaries (including across "split lines").


Clip Merge Options
  • -1 Automatic clip merge behaviour (default)
 ;mergeclips -1
  • 0 Don't merge clips. Effects that are applied across clip boundaries will not be merged into the existing audio (there will be split lines at the ends of the returned audio) whether the returned audio is the same length as the original selection or not.
 ;mergeclips 0
  • 1 Always merge clips. The returned audio will always be merged into the existing audio (no split lines added).
 ;mergeclips 1
See also "restoresplits".


preview

Provides options for previewing the effect. Multiple preview options may be defined to achieve the desired behaviour.

Preview Options
  • enabled (default). Preview is enabled.
 ;preview enabled
  • true Same as "enabled".
 ;preview true
  • disabled Preview is disabled. If Audacity is unable to provide a meaningful preview, then preview should be disabled. This may be required for effects that affect specific time regions within the selection.
 ;preview disabled
  • false Same as "disabled".
 ;preview false
  • linear Provides an optimisation for previewing multiple tracks by mixing the selected tracks before applying the Nyquist code. This optimisation is disabled by default.
 ;preview linear
  • selection When previewing, the Nyquist code is applied to the entire selection (not just the length that will be previewed). Audacity's "Preview" then plays the first few seconds of the processed audio. This may be required for effects that vary over the duration of the selection.
 ;preview selection


restoresplits

Allows Nyquist plug-ins to override Audacity's default "split restore" behaviour. By default, when effects (including generator effects) are applied across one or more clip boundaries, Audacity will restore "split lines" at the position of the original clip boundaries.

This option only applies when the plug-in is applied across clip boundaries (including across "split lines").

Restore Splits Options
  • 1 Splits at clip boundaries are restored (default)
 ;restoresplits 1
  • 0 Splits at clip boundaries are not restored (clips are joined).
 ;restoresplits 0

Note: Nyquist plug-ins are not currently able to distinguish between silence and "empty space" within the selection, so gaps between audio clips will be treated as if the empty space is an additional "silent" audio clip.

See also "mergeclips".


Deprecated plug-in headers

categories

Specifies an LV2 category for the plug-in. This header is ignored by current versions of Audacity.

 ;categories "text"

info

A single line of text to be displayed at the top border of the plug-in window. For multiple lines of text, a two-character sequence "\n" bay be used within "text" to create a line break. This header is ignored by current versions of Audacity.

 ;info "text"

Nyquist Plug-in Widgets

Every ";control" line gets parsed by Audacity into several tokens, where each token is separated by one or several whitespaces:

Syntax for ;control lines
;control var-name text-left widget-type text-right initial-value minimum maximum
;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 integer
;control symbol string float-text string float float float
;control symbol string string string string - -
;control symbol string choice string integer - -


int-text and float-text were added in Audacity 2.1.2. They are ignored by earlier versions of Audacity, which may lead to an "unbound symbol" error if the plug-in is run in an old version of Audacity. These controls should not be used in plug-in versions less than version 4.
"real" (deprecated) is an alternative name for "float" and is provided as legacy support for old plug-ins.

Italic words in the table denote data types. Because tokens are separated by whitepace, strings containing whitespace must be written within quotation marks. Do not try to memorize this table, use it as a reference. The detailed syntax for each widget type is described in the following sections.

Slider Widget

Slider-widget.png

Slider widgets are supported in all Audacity Nyquist plug-in versions.

 ;control variable-name "text-left" variable-type "text-right" initial-value minimum maximum
  • variable-name - a Lisp symbol.
  • text-left - text that will appear to the left of the slider.
  • variable-type - a "number" type, either int, float or real*:
    • int - integer [FIXNUM, an XLISP whole number]
    • float (or real*) - floating point [FLONUM, an XLISP number supporting decimal places]
  • text-right - text that will appear to the right of the slider.
  • initial-value - variable value [and slider position] at the first start of the plug-in.
  • minimum - numerical variable value when the slider is moved to the left border.
  • maximum - numerical variable value when the slider is moved to the right border.

The variable value [the slider position] can be referenced by the variable name in the plug-in code.

A text input box to the left of the slider allows the user to type in a value via the keyboard. As of Audacity 2.1.1, input values are validated to only allow input between minimum and maximum values.

  • The "real" keyword is deprecated. New plug-ins should use "float" as the variable type for floating point input.

Numeric Text Widget

Steve 26Oct15: ToDo-1 Image required.

The following code will generate the required GUI:

;name "float-text widget"

;control test "text-left" float-text "text-right" 33 0 100

The numeric text widget was introduced in Audacity 2.1.2.

 ;control variable-name "text-left" variable-type "text-right" initial-value minimum maximum
  • variable-name - a Lisp symbol.
  • text-left - text that will appear to the left of the text box.
  • variable-type - a "number" type, either "int-text" or "float-text":
    • int-text - integer [FIXNUM, an XLISP whole number]
    • float-text - floating point [FLONUM, an XLISP number supporting decimal places]
  • text-right - text that will appear to the right of the text box.
  • initial-value - variable value at the first start of the plug-in.
  • minimum - numerical minimum variable value that will pass validation.
  • maximum - numerical maximum variable value that will pass validation.

Minimum and maximum may be numeric values or "NIL". The minimum / maximum is not defined when set as "NIL" and is limited only by the numeric limit for the number type. The valid range for numbers depends on the computer platform. Typically the limits for integers are -2147483648 to 2147483647. The limits for floating point numbers are very large.

Examples of undefined minimum / maximum:

 ;control pos "Positive Integer" int-text "text-right" initial-value 0 nil
 ;control neg "Negative Integer" int-text "text-right" initial-value nil 0
 ;control num "Any number" float-text "text-right" initial-value nil nil

Text Input Widget

Text-widget.png

The text input widget is supported in plug-ins version 2 or above.

 ;control variable-name "text-left" string "text-right" "initial-string"
  • variable-name - a Lisp symbol.
  • text-left - text that will appear to the left of the text input field.
  • text-right - text that will appear to the right of the text input field.
  • initial-string - the string will appear inside the text field.

The text typed in by the user in the text field of the plug-in window can be referred as a string variable from within the plug-in code. All string characters are valid, though care must be taken with escape characters if the string is to be evaluated.

Examples how to use the text input widget can be found in the source code of the Apropos Plug-in.


Multiple-Choice Widget

Choice-widget.png

The multiple choice input widget is supported in plug-ins version 3 or above.

 ;control variable-name "text-left" choice "string-1,string-2,..." initial-value
  • variable-name - a Lisp symbol.
  • text-left - text that will appear to the left of the multiple-choice list.
  • string-1,... - for every string an entry in a list to choose from will be produced.
  • initial-value - the number of the list entry that will be displayed as the default choice at the first start of the plug-in.

The list entries string-1, string-2, etc. are internally represented by integer numbers. The first, top-most list entry string-1 will be represented by the number 0. The list entry chosen by the user can be determined by the integer value of the variable from within the plug-in code.

Examples how to use the 'choice' widget can be found in the source code of the Apropos Plug-in.

Nyquist Variables

The variables given from Audacity to Nyquist are defined in the file "audacity/lib-src/libnyquist/nyx/nyx.c" in the Audacity source code.

The following variables are given from Audacity to Nyquist:

  • *TRACK* (version 4) - 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.
  • *SYSTEM-DIR* (version 4) - A variable with a list of properties relating to the file system.
  • *SYSTEM-TIME* (version 4) - A variable with a list of properties relating to the system time/date.
  • *PROJECT* (version 4) - A variable with a list of properties relating to the current Audacity project.
  • *SELECTION* (version 4) - A variable with a list of properties relating to the current selection.
  • *SCRATCH* - a symbol whose value and property list are preserved from one effect invocation to the next.
  • S (version 1, 2, 3) - In process and analyze type plug-ins this is the Audacity sound [the selected part of the Audacity audio track]. In generate type plug-ins "S" is the Adagio notation for a quarter note (float value 0.25).
  • S (version 4) - Adagio notation. A quarter note (float value 0.25).
  • LEN - the number of samples contained in the Audacity sound.
  • *SOUND-SRATE* - the sample frequency of the Audacity track.
  • *CONTROL-SRATE* - 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.
  • *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.
  • *FILE-SEPARATOR* - The character that separates directories in a path, e.g. "/" for Unix, ":" for Mac, and "\" for Win32.


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


For process and analyze type plug-ins, the length of the sound in seconds can be computed one of the following ways:

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


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 plug-ins, 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 plug-ins or later).

Variables and Property Lists

In general terms, a variable is a symbol which contains a value. The symbol can be any valid name, and its value may be changed (hence "variable"). In Nyquist, the value may be of any data type (for example, a number, a character, or even a sound) and may be changed from one data type to another. Unlike some programming languages, variables do not need to be declared before use - they can just be set, and then they exist.

Setting the value of a symbol "binds" the value to the symbol. A symbol that has no value (not even "nil") is said to be "unbound".

In addition to the value of a symbol, we can also attach properties. This is a way of associating a list of items, each with their own value, to a single variable. Each item is called a key or indicator, and we can give each key a value. This list of items is called a "property list" (or plist for short).

To get the value of a property, we use the GET command.

When getting the value of a property, we do NOT want to evaluate either the variable (symbol) or the key symbol, so we must "quote" both symbols to prevent evaluation.

 (GET 'varaiable-name 'property-name) ; Lisp syntax
 set v = get(quote(varaiable-name ), quote(property-name)) ; SAL syntax

As an example, if we have a variable called *TRACK* (which we do in version 4 plug-ins), and it has a property called NAME (which it does), then we can "get" the value of that property with:

 (GET '*TRACK* 'NAME) ; Lisp
 return get(quote(*TRACK*), quote(NAME)) ; SAL


Version 4 Property Lists

In version 4 plug-ins, property lists are defined for the global variables *TRACK*, *SELECTION*, *PROJECT* and *SYSTEM-DIR*. Version 4 plug-ins require Audacity 2.1.0 or later.

*TRACK*

Value: The sound from a selected mono audio track, or an array of two sounds from a selected stereo track (see Stereo Tracks below).

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).

  • 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.
  • TYPE : [String] The type of track. One of: "wave", "midi", "label", "time". Currently only "wave" (audio tracks) are processed by Nyquist plug-ins.
  • VIEW : [String] The track view. Only applies to audio tracks. One of: "Waveform", "Waveform (dB)", "Spectrogram" or NIL.
This property may change in future versions of Audacity, so is not recommended for public release plug-ins. During Preview, audio tracks are copied to temporary tracks which are not visible, so the returned "VIEW" value is NIL.
  • CHANNELS : [Integer] The number of channels in the track (mono = 1, stereo = 2).
  • START-TIME : [Float] The track start time (note that this will often be different from the selection start time.)
  • END-TIME : [Float] The track end time.
  • GAIN : [Float] The value of the track Gain slider.
  • PAN : [Float] The value of the track Pan slider.
  • RATE : [Float] The track sample rate.
  • FORMAT : [Integer or Float] The track sample format. One of (Integer) 16, (Integer) 24, or (float) 32.
  • CLIPS : [List or Array] For mono tracks, a list of "clips", where each clip is a list containing the start and end time of the clip. For stereo tracks, an array containing a list of clips for each channel.
 ;;Example of *TRACK* CLIP data for a mono track [Lisp]
 (setf track-clips (get '*track* 'clips))
 (print (first track-clips)) ; prints the first clip as (list start-time end-time)
 ;;Example of *TRACK* CLIP data for a stereo track [Lisp]
 (setf track-clips (get '*track* 'clips))
 (setf left-channel (aref track-clips 0)) ; the list of clips in the left channel
 (print (first left-channel)) ; prints the first clip in the left channel as (list start-time end-time)

*SELECTION*

Value: Unbound (not defined).

  • START : [float] The start of the selection in seconds.
  • END : [float] The end of the selection in seconds.
  • TRACKS : [integer list] A list of track numbers of selected audio tracks.
  • CHANNELS : [integer] The number of selected audio channels.
  • LOW-HZ : [float] The low frequency selection Hz (Spectrogram or Spectrogram (log f) track view).
  • CENTER-HZ : [float] The centre frequency selection in Hz (Spectrogram or Spectrogram (log f) track view).
  • HIGH-HZ : [float] The high frequency selection Hz (Spectrogram or Spectrogram (log f) track view).
  • BANDWIDTH : [float] The bandwidth of the frequency selection in octaves (Spectrogram or Spectrogram (log f) track view).
  • PEAK-LEVEL : [float] The absolute peak level (linear scale).

*PROJECT*

Value: Unbound (not defined).

  • RATE : [integer] The project rate in the project.
  • TRACKS : [integer] The number of tracks in the project.
  • WAVETRACKS : [integer] The number of audio tracks in the project.
  • LABELTRACKS : [integer] The number of label tracks in the project.
  • MIDITRACKS : [integer] The number of note tracks in the project.
  • TIMETRACKS : [integer] The number of time tracks in the project.

*SYSTEM-DIR*

Value: Unbound (not defined).

  • BASE : [string] The Audacity installation directory.
  • DATA : [string] The Audacity data directory. This is where the audacity.cfg, plug-inregistry.cfg and EQCurves.xml files are located.
  • HELP : [string] The installation directory for the Audacity Manual (note that the Manual may not exist).
  • TEMP : [string] The Audacity temp directory. This is where unsaved project data is temporarily stored.
  • PLUG-IN : [string list] A list of directories where Audacity looks for Nyquist plug-ins.

*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 2017 would be the list: 2017, 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".
  • TIME : [string] The time formatted according to the current locale. Example: "hh:mm:ss".
  • 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".
  • YEAR : [integer] The year (as an integer).
  • DAY : [integer] Day of the month.
  • MONTH : [integer] The month (as an integer).
  • MONTH-NAME : [string] The name of the month (Example: "January").
  • DAY-NAME : [string] The name of the day (Example: "Monday").

*AUDACITY*

This property list was added in Audacity version 2.1.0

Value: Unbound (not defined).

  • 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

The *SCRATCH* Symbol

(version 3 or above - Audacity 1.3.9 or later)

*SCRATCH* is a global symbol, which is not deleted in-between plug-in runs.

It provides a way for information to survive from one invocation of a plug-in to the next. However, you should not rely on the "value" of *SCRATCH* beyond a single invocation of a plug-in as it could be overwritten by another plug-in. It is better to use property lists of *SCRATCH*. That way, you get a whole name space rather than a single variable name, and with careful naming of the property keys, name collisions can be avoided.

To pass data from plug-in "effectX-partA" to "effectX-partB":

1. Assign a property name based on the effect name, e.g.: 'EFFECTX [or in SAL, which does not support the single-quote notation of LISP, write QUOTE(EFFECTX). ]

2. "effectX-partA" should delete any old property value:

 exec remprop(quote(*SCRATCH*), quote(effectx)) ;; in SAL
 (remprop '*SCRATCH* 'effectx) ;; in LISP

3. "effectX-partA" should compute a new property value v and save it:

 exec putprop(quote(*SCRATCH*), v, quote(effectx)) ;; in SAL
 (putprop '*SCRATCH* v 'effectx) ;; in LISP

4. "effectX-partB" should access the property using:

 set v = get(quote(*SCRATCH*), quote(effectx)) ;; in SAL
 (get '*SCRATCH* 'effectx) ;; in LISP

5. When "effectX-partB" finishes, it should remove the property:

 exec remprop(quote(*SCRATCH*), quote(effectx)) ;; in SAL
 (remprop '*SCRATCH* 'effectx) ;; in LISP

But there may be cases where you do some analysis and want to use the analysis data multiple times. You might even have multiple analysis plug-ins operating on different inputs to collect data to feed into a plug-in with multiple inputs. In this case, which might be quite common, you should not call REMPROP(), but this has the problem of leaving data on the *SCRATCH* property list indefinitely.

In cases where *SCRATCH* data is not deleted immediately after use, and where there is the potential to leave large amounts of memory there, there should be another effect, e.g. "effectX-partCleanup", that simply calls:

 exec remprop(quote(*SCRATCH*), quote(effectx)) ;; in SAL
 (remprop '*SCRATCH* 'effectx) ;; in LISP

allowing the user to explicitly free up any data stored on the 'EFFECTX property. It would be reasonable to omit the "effectX-partCleanup" effect if the data stored on the property list has a maximum size of, say, 10KB. The problem we want to avoid is properties with unbounded size getting left in the heap until Audacity is restarted.


Stereo Tracks

If a sound from an Audacity stereo track was given to Nyquist, the s variable contains an array of sounds. Because all Nyquist "snd-..." low-level functions only can process mono signals, to use such a function, the s array first must be split into single mono signals and afterwards be re-combined into an array before it is given back to Audacity.

In Sal, one could write:

 if arrayp(s) then
   return vector(snd-function(s[0]), snd-function(s[1]))
 else
   return snd-function(s)

Or in LISP, one could write:

 (if (arrayp s)
     (vector
       (snd-function (aref s 0))   ; left stereo channel
       (snd-function (aref s 1)))  ; right stereo channel
     (snd-function s))             ; mono signal
  • (arrayp s) - tests if 's' is an array
  • (vector ... ) - re-combines the two mono signals into a stereo signal. A "vector" is an one-dimensional array
  • (aref s 0) - the left stereo channel [the 0-th slot of the array]
  • (aref s 1 - the right stereo channel [the 1-st slot of the array]

Important: The Nyquist interface within Audacity can handle a maximum of two channels simultaneously [Audacity stereo tracks]. If in Audacity more than one audio track were selected, each of the selected tracks will be given sequentially, one after the other, with a maximum of two channels simultaneously [stereo] to Nyquist for processing. It is not possible with Nyquist in Audacity e.g. to copy audio signals from one Audacity track into another track [Audacity 1.3.9, November 2009].

multichan-expand

In the "nyquist.lsp" file in the Audacity "nyquist" sub-directory there is a function "multichan-expand" defined that simplifies the handling of multi-channel sounds [e.g. stereo tracks]:

 (multichan-expand function &rest arguments)

So the "arrayp" constuct from above can also be written:

 return multichan-expand(quote(snd-function), s) ;; in SAL
 (multichan-expand #'snd-function s) ;; in LISP

This looks a bit more cryptic and reads less intelligibly [to some], but it can help to clean up the code in long-winded audio processing functions.

Return Values

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

Sound: The sound will be re-inserted into the selected part of the Audacity track. 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, so in both channels of the stereo track the same mono sound will be inserted. If a stereo sound is returned to a mono track, an error message will be displayed.

String: A dialog window will appear with the string being displayed as text.

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

List: If a specially formatted list is given back 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 (Audacity 1.3) 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.

Math Functions

n-th power of x:

 power(x, n) ;; in SAL
 (power x n) ;; in LISP
 

n-th root of a number:

 power(x, 1.0 / n) ;; in SAL
 (power x (/ 1.0 n)) ;; in LISP 

n-th root of a sound s:

 return s-exp(s-log(s) * (1.0 / n)) ;; in SAL
 (s-exp (mult (s-log s) (/ 1.0 n))) ;; in LISP

n-th root with two sounds x and n:

 return s-exp(s-log(x) * s-recip(n))  ;; in SAL
 (s-exp (mult (s-log x) (s-recip n))) ;; in LISP


Nyquist Workbench

The Nyquist Workbench gives the ability to run arbitrary Nyquist code in Audacity from a graphical IDE. When enabled, Nyquist Workbench can be found at the bottom of the View Menu.

Nyquist-workbench.png


The Nyquist Workbench is an Audacity experimental module though at one time it was available as standalone source code.

Ready-built module for Windows and Mac

For the Audacity 2.1.3 release, you can download a ready-built Nyquist workbench module as follows:

On Windows, after unzipping, place the "modules" folder containing the mod-nyq-bench file in the folder where Audacity is installed. On macOS, after unzipping, right-click or CTRL-click over Audacity.app, choose "Show Package Contents", then place the "modules" folder in the "Contents" folder.

Then on all operating systems, enable the module in Modules Preferences and restart Audacity.

Compiling Nyquist Workbench

For GNU/Linux (and for the other platforms if you are compiling the latest Audacity code), Nyquist Workbench is included in the Audacity HEAD source code at \lib-src\mod-nyq-bench. Follow the steps below for your operating system to compile Audacity and then compile Nyquist Workbench.

Warning icon It is necessary to compile the mod-nyq-bench module on the same date as Audacity. Otherwise the version string check will stop the module loading.

Windows

  1. If this is your first time compiling Audacity, read the introductory yellow panel at the top of Developing On Windows so as to install the correct version of Microsoft Visual Studio.
  2. Build Audacity according to win/compile.txt in the source code. If you are reopening Visual Studio to build Nyquist Workbench, open "audacity.sln" and choose "Debug" or "Release" configuration according to which configuration of Audacity you already built.
  3. In the "Solution Explorer" panel, right-click Solution 'audacity'.
  4. Choose Add > Existing Project..., browse to the \lib-src\mod-nyq-bench folder then select and open mod-nyq-bench.vcxproj.
  5. Right-click the new mod-nyq-bench entry in the Solution Explorer tree and choose "Build".
  6. After building, a post-build event copies the compiled "mod-nyq-bench.dll" file to \win\Debug\modules or \win\Release\modules as appropriate.
  7. Next time you build Audacity, mod-nyq-bench should be rebuilt automatically.

Mac

Follow /mac/Build.txt to patch and build wxWidgets.

Using xcodebuild, the steps below assume you will build Release configuration of Audacity but you can build Debug configuration instead by replacing "Release" with "Debug" in the steps.

  1. Clone or unzip the Audacity sources at GitHub.
  2. Change into the "mac" directory in the Audacity sources. For example if you unzipped the sources the command might be:
    cd /Users/joe/Downloads/audacity-master/mac

  3. Run the installation scripts to build Audacity and install it to /private/tmp/Audacity.dst/Audacity:
    xcodebuild -configuration Release install

  4. Build mod-nyq-bench.so and install it at /private/tmp/Audacity.dst/Audacity/modules
    xcodebuild -configuration Release install -target mod-nyq-bench

  5. Launch Audacity, enable mod-nyq-bench in Modules Preferences then restart Audacity.

If you use the Xcode IDE, select "Audacity - Release" or "Audacity - Debug" from the Toolbar or Product > Scheme menu, then use Product > Build. To build the workbench, select "Nyquist Workbench Module - Release" or "Nyquist Workbench Module - Debug" from the Toolbar or Product menu (according to which configuration of Audacity you built). Then use Product > Build to build the module.

GNU/Linux

Gale 26May15: ToDo-2 Placeholder to adjust step 6 if Bug 978 is fixed.
  1. Create a new "build" directory in which to build Audacity (and mod-nyq-bench). This keeps the source tree clean of files which are only created by the build.
    mkdir build
  2. Change to the new "build" directory:
    cd build
  3. Configure in the root of the source tree (note the two dots before "../configure"). Using just that command builds a release configuration build of Audacity:
    ../configure
  4. If configure completes successfully, type:
    make

    If you have problems at Step 3 or 4, try the Compiling Audacity Step by Step Guide.

  5. If 'make' completes successfully, type:
    cd lib-src/mod-nyq-bench
  6. Compile Nyquist Workbench:
    make

    There should now be a hidden folder "/build/lib-src/mod-nyq-bench/.libs" containing three files and three links.

  7. The "sudo make install" command does not currently allow Audacity to see the compiled mod-nyq bench, so instead of that command, go back to the "build" folder:
    cd ../..
  8. Then create a "modules" directory inside the "build" folder:
    mkdir modules
  9. Copy the file "mod-nyq-bench.so.0.0.0" and the link "mod-nyq-bench.so" from the /build/lib-src/mod-nyq-bench/.libs directory into the new "modules" directory.

Loading/Enabling mod-nyq-bench

After first building mod-nyq-bench you will need to launch Audacity then enable mod-nyq-bench in Modules Preferences. Set the control for mod-nyq-bench to "Enable" and restart Audacity then the "Nyquist Workbench" item will be visible at the bottom of View Menu.

Note that if you build some earlier versions of Audacity than HEAD, for example the 2.1.0 release tarball, there are no Modules Preferences. Each time you launch Audacity you will be asked if you want to load mod-nyq-bench. If you choose "Yes" and the build of mod-nyq-bench matches with the version string of Audacity, you should then have an additional "Nyquist Workbench" entry at the bottom of the "View" Menu.

Rebuilding Audacity and Nyquist Workbench

When you update your Audacity source code tree and rebuild Audacity on a subsequent day, you must also rebuild mod-nyq-bench. This happens automatically on Windows if you add mod-nyq-bench to the Audacity solution as described above.

Mac OS X/macOS:

Using xcodebuild, run these two commands to clean then build and install mod-nyq-bench:

  1. xcodebuild -configuration Release clean -target mod-nyq-bench

  2. xcodebuild -configuration Release install -target mod-nyq-bench
  • Alternatively in Xcode IDE, use the Toolbar or Product > Scheme menu to select "Nyquist Workbench Module - Release" or "Nyquist Workbench Module - Debug" according to which configuration of Audacity you built. Then choose Product > Clean followed by Product > Build.

GNU/Linux:

  • It is recommended to run "make clean" or "make distclean" before configuring and building Audacity.
  • After building Audacity, change to the mod-nyq-bench directory, type "make clean" to remove NyqBench.so and NyqBench.o, then type "make" to rebuild NyqBench.so.

Nyquist Apropos Plug-in

Because not all functions, documented in the Nyquist manual, are implemented in Audacity and also not even all Nyquist functions are documented in the Nyquist manual [Lisp is a "programmable programming language", only functions which are considered as stable are documented], it is often helpful to have a tool to find out whether a particular Nyquist function is implemented or not.

Basically only Nyquist functions beginning with "snd-..." are implemented in C within the Nyquist interpreter [in the Nyquist manual they are called 'low-level' functions], while all other Nyquist functions are implemented in the Lisp files within the Audacity "nyquist" sub-directory and can be changed, improved and extended with no need to re-compile Audacity [as long as no C-implemented Nyquist "low-level" function is needed which is not included with Nyquist in Audacity].

All Nyquist/XLISP symbols [e.g. all variable and function names] are stored in the XLISP *obarray*. To find out from within Audacity, whether a particular function is implemented or not, you can e.g. first create and select a "dummy" audio track with any generator from the Audacity Generate menu, then open Effect > Nyquist Prompt... [doesn't work without a selected audio track] and copy the following line into the "Nyquist Prompt" text input field:

 (print (fboundp 'snd-abs))

Important: now please click "Debug" instead of the "OK" button.

First a dialog appears telling you: "Nyquist did not return audio" [or similar]. In this dialog, click the "OK" button. Then another dialog "Nyquist output" appears with the result of the "print" function:

  • T - meaning "true", function is implemented
  • NIL - meaning "false", function is not implemented

I had typed this so often in the past that I have written an Audacity Nyquist "Apropos" Plug-in:

Download: Apropos-Plug-in

Right-Click on the plug-in link, choose "save target as", and save the file "apropos.ny" file in the Audacity "Plug-Ins" sub-directory. After a re-start of Audacity you can find the "Apropos" Plug-in in the Generate menu, the only menu that works without a "dummy" audio track.

The "Apropos" Plug-in offers a pattern search through the Nyquist/XLISP *obarray*. You can also choose between "Functions only", "Variables only" and "All symbols":

Appropos-window.png

Note: with no search pattern [empty field], the plug-in matches all symbol names.


Important: As written in the plug-in window, please press "Debug" instead of the "OK" button, otherwise you will not see the results.

First appears a dialog that reminds me that I have forgotten to press the "Debug" button:

Appropos-message.png

In the first dialog above, just klick the "OK" button. Afterwards, but only if you have clicked the "Debug" button in the plug-in window, appears the window with the results, sorted in alphabetical order:

Appropos-output.png

Bugs

Details of current bugs that affect Nyquist in Audacity are listed on Bugzilla.


Links

|< Nyquist

Personal tools

Donate securely by PayPal, using your credit card or PayPal account!