Audacity Support Forum / Audacity and Nyquist / Nyquist Reference Manual / Nyquist Examples and Tutorials
The Audacity Nyquist Interface is implemented in the following files in the Audacity source code:
Note: All [comments] and [explanations] on this page are written
in square brackets, so they cannot be confused with
Important: In the Nyquist plugin header there must be only one single semicolon at the beginning of each line because these lines are parsed by Audacity.
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 plugin header, comments can also be started with several semicolons in a row.
;nyquist plug-in ;version version ;type type ;name "name" ;action "text" ;categories "text" ;info "text" ;control parameters ;codetype type ;debugflags flags
The 'categories', 'info', 'control', 'codetype', and 'debugflags' lines are optional and can be omitted.
Required plugin header lines:
|
tells Audacity 'this is a Nyquist plugin'. | ||
|
only the Slider widget is supported. | ||
|
the |
||
|
the
|
||
Only one ';version' line is needed. If you don't know
which one to choose use the version with the highest number. The
version line is only needed to prevent Audacity from raising errors in
case a user comes to the idea to apply a plugin with a
|
|||
|
plugin appears in the Audacity 'Generate' menu. | ||
|
plugin appears in the Audacity 'Effect' menu. | ||
|
plugin appears in the Audacity 'Analyze' menu. | ||
Only one ';type' line is needed. A plugin cannot appear
in several Audacity menus at the same time. But it is possible to write
several plugins 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 |
|||
|
name of the plugin how it will appear in the Audacity menu. | ||
|
text to be displayed while the plugin is working. | ||
Optional plugin header lines: | |||
|
LV2 categories, see Categories below. | ||
|
text to be displayed at the top border of the plugin window. | ||
A character sequence '\n' within 'text' causes a line
break. It is not possible to 'quote' a line break in the plugin code
with a |
|||
|
defines a Plugin Widget. There can be several 'control' lines in the plugin header. | ||
|
the syntax of the plugin is Lisp. This is the default if the 'codetype' line is missing. | ||
|
the syntax of the plugin is SAL. The default is 'lisp'. | ||
|
see |
Categories [
LV2 categories had been introduced in Audacity as part of 'Google Summer
The categories were tried out in the
The 'categories' header line is currently optional.
Internal Debug Options
There is an optional 'debugflags' line available, which skips the plugin
window and directly executes the plugin code, so if a 'debugflags' line is
found in the plugin header no
|
sets *tracenable* to 'true'. The plugin behaves as if the 'Debug' button was clicked by the user. This is the default. | ||
|
sets *tracenable* to 'false'. The plugin behaves as if the 'OK' button was clicked by the user. | ||
|
sets |
||
|
sets |
In the
Every ';control' line gets parsed by Audacity into several tokens, where each token is separated by one or several whitespaces:
|
|
|
|
|
|
|
|
||||||||||
|
;control |
|
var-name |
|
"text-left" |
|
widget-type |
|
"text-right" |
|
initial-value |
|
minimum |
|
maximum |
||
|
;control |
|
symbol |
|
"string" |
|
int |
|
"string" |
|
integer |
|
integer |
|
integer |
||
|
;control |
|
symbol |
|
"string" |
|
real |
|
"string" |
|
float |
|
float |
|
float |
||
|
;control |
|
symbol |
|
"string" |
|
string |
|
"string" |
|
"string" |
|
|
||||
|
;control |
|
symbol |
|
"string" |
|
choice |
|
"string" |
|
integer |
|
|
Blue words represent data types. Because tokens are separated by
whitepace, strings containing whitespace must be written
Slider widgets are supported in all Audacity Nyquist plugin versions.
;control variable-name "text-left" variable-type "text-right" initial-value minimum maximum
|
a Lisp symbol. | ||||||||||
|
a 'number' type: | ||||||||||
|
|||||||||||
|
text that will appear to the left of the slider | ||||||||||
|
text that will appear to the right of the slider | ||||||||||
|
variable value [and slider position] at the first start of the plugin | ||||||||||
|
variable value when the slider is moved to the left border | ||||||||||
|
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 plugin code.
In more recent versions of Audacity there appears a text input box beside the slider, where the user can type in a variable value via the keyboard. Note that it's up to the plugin programmer to catch undesired variable values typed in by the user.
The text input widget is supported in plugins version 2 or above, it will
not work in
;control variable-name "text-left" string "text-right" "initial-string"
|
a Lisp symbol. | ||
|
text that will appear to the left of the text input field. | ||
|
text that will appear to the right of the text input field. | ||
|
the string will appear inside the text field. |
The text typed in by the user in the text field of the plugin window can be referred as a string variable from within the plugin code.
Examples how to use the 'text input' widget can be found in the source code of the Apropos plugin.
The choice widget is supported in plugins
;control variable-name "text-left" choice "string-1,string-2,..." initial-value
|
a Lisp symbol. | ||
|
text that will appear to the left of the
|
||
|
for every string an entry in a list to choose from will be produced. | ||
|
the number of the list entry, that will be displayed as the default choice at the first start of the plugin. |
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
Examples how to use the 'choice' widget can be found in the source code of the Apropos plugin.
The variables given from Audacity to Nyquist are defined in the file
'
The following variables are given from Audacity to Nyquist:
|
the Audacity sound [the selected part of the Audacity audio track] | |||||||||||||||
|
the number of samples contained in 's' | |||||||||||||||
|
the sample frequency of the Audacity track | |||||||||||||||
|
a list of three values: | |||||||||||||||
|
The length of the sound in seconds can be computed one of the following ways:
|
divide the number of samples by the sample frequency | ||
|
get the 'time-stretch' value from the *warp* variable |
Roger Dannenberg writes:
The details of *warp* are part of the Nyquist internal implementation, and one should not write code that accesses *warp* directly. To get the duration of an Audacity selection, call the Nyquist function:
(get-duration 1)
This function 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
Since
Roger Dannenberg writes:
The point of *scratch* is to provide some way for information to survive
from one invocation of a
To pass data from plugin '
1. Assign a property name based on the effect name, e.g.:
'EFFECTX
2. '
remprop(quote(*scratch*), quote(effectx))
3. '
putprop(quote(*scratch*), v, quote(effectx))
4. '
get(quote(*scratch*), quote(effectx))
5. When '
remprop(quote(*scratch*), quote(effectx)), ...
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 plugins
operating on different inputs to collect data to feed into a plugin 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, there
should be another effect, e.g. '
remprop(quote(*scratch*), quote(effectx))
allowing the user to explicitly free up any data stored on the 'EFFECTX
property. It would be reasonable to omit the
'
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 being re-combined into an array before it is given back to Audacity.
(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
|
tests if 's' is an array | ||
|
re-combines the two mono signals into a stereo signal, a 'vector' is an one-dimensional array | ||
|
the left stereo channel [the 0-th slot of the array] | ||
|
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 sequencially, 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
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:
(multichan-expand #'snd-function s)
This looks a bit more cryptic and reads less intelligibly [arrording to my opinion], but it can help to clean up the code in long-winded audio processing functions.
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 Nyquist return value one of the following actions will be invoked in Audacity:
|
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. | ||
|
a dialog window will appear with the string being displayed as text. | ||
|
if a specially formatted list [see below] will be given back to Audacity, a label track will be created below the audio track[s]. |
The list to create a label track must have the following format:
((int-or-float "string") (int-or-float "string") ... )
|
the time in seconds from the beginning of the Audacity selection, where the label will appear. | ||
|
a string to be displayed in the label's text field. |
(exp (* (log x-number) n-number))
n-th root of a number:
(exp (/ (log x-number) n-number))
n-th root of a sound:
(s-exp (mult (s-log x-sound) (/ 1.0 n-number)))
n-th root with two sounds:
(s-exp (mult (s-log x-sound) (s-recip n-sound)))
The Nyquist Workbench gives the ability to run arbitrary Nyquist code
in Audacity from a
The Nyquist Workbench is an Audacity module, which currently
[
Download the 'NyqBench'
Here is how it works on Linux:
1. First type './configure' in the Audacity source code directory:
sh:~/downloads/audacity$ ./configure
After 'configure' has finished, do not type 'make', you first need to compile the Nyquist Workbench.
2. Open the Makefile in the Nyquist Workbench directory and make the AUDACITY_DIR variable at the top of the Makefile point to the base of the Audacity source code directory:
AUDACITY_DIR ?= /home/edgar/downloads/audacity
Of course you need to replace '/home/edgar/downloads/audacity' with the Audacity source code directory on your harddisk.
3. After saving the changes in the Makefile, compile the Nyquist Workbench. In the Nyquist Workbench directory type:
sh:~/downloads/nyqbench$ make
After 'make' has finished you shold see a message like:
NyqBench.so has been copied to /home/edgar/downloads/audacity/modules
4. Now compile Audacity. In the Audacity source code directory type:
sh:~/downloads/audacity$ make
5. If 'make' has finished successfully, still in the Audacity source code directory, type:
sh:~/downloads/audacity$ sudo make install
6. Currently
sh:~/downloads/audacity$ sudo cp -r modules /usr/local/share/audacity
This copies the 'modules' directory including everything inside from the
Audacity source code directory to
'
7. After the next start of Audacity, you should have an additional Audacity 'Tools' menu with a 'Nyquist Workbench' entry inside.
Tested with
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 wether 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, wether 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 the 'Nyquist Prompt' from the Audacity 'Effect' menu [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 klick 'Debug' instead of the 'OK' button.
First a dialog appears telling you: 'Nyquist did not return audio' [or similar]. In this dialog, klick the 'OK' button. Then another dialog 'Nyquist output' appears with the result of the 'print' function:
|
meaning 'true', function is implemented | ||
|
meaning 'false', function is not implemented |
I had typed this so often in the past that I have written an Audacity Nyquist 'Apropos' plugin:
Download: Apropos-Plugin
Right-Click on the plugin 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' plugin in the 'Generate' menu, the only menu that works without a 'dummy' audio track.
The 'Apropos' plugin offers a pattern search through the Nyquist/XLISP
*obarray*. You can also choose between
Note: with no search pattern
Important: As written in the plugin 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:
In the first dialog above, just klick the 'OK' button. Afterwards, but only if you have clicked the 'Debug' button in the plugin window, appears the window with the results, sorted in alphabetical order:
Audacity Support Forum / Audacity and Nyquist / Nyquist Reference Manual / Nyquist Examples and Tutorials