Audacity Support Forum / Audacity and Nyquist / Nyquist Reference Manual / Nyquist Examples and Tutorials


Steven Jones / Pedro Morales / David R. Sky / Nyquist and Emacs / Audacity Wiki


Changing the Volume of an Audacity Track


Note: All [comments] and [explanations] are written in square brackets, so they cannot be confused with (Lisp code).

  1. Changing the Volume of an Audacity Track - the 'scale' function

  2. Changing the Volume of Stereo Tracks Independently

  3. Handling Mono and Stereo Tracks Automatically

  4. Changing the Volume with Envelopes

  5. Changing the Volume with a Low Frequency Generator

1  Changing the Volume of an Audacity Track


To change the volume of an Audacity track with Nyquist, the easiest way is to use the Nyquist 'scale' function:

The 'scale' function multiplies the amplitude [volume] of the 'sound' by the given 'number'. A number of 0.5 will make the volume become half as loud as before, while a number of 2 will make the sound become double as loud as before.

Example:

First either load a sound file into Audacity or create an audio track, e.g. with 'Tone' from the Audacity 'Generate' menu. Then mark the whole track either by pressing 'Ctrl+A' on the keyboard, or by clicking with the mouse into the track header, with taking care not to move the buttons or sliders. The whole track then will appear in a different color.

Now open the 'Nyquist Prompt' from the Audacity 'Effect' menu. A window with a text field will appear where you can type in:

(scale 0.5 s)

Important: Do not forget to type the parens. The parens are part of the Lisp language Nyquist is based on. Without the parens the Nyquist interpreter will not be able to understand your code.

The 's' variable is the Audacity 'sound' [the selected part of the Audacity track]. Nyquist in Audacity always understands 's' as the Audacity sound variable.

After clicking 'OK' in the 'Nyquist Prompt' window the 'scale' function will take the Audacity sound and return a 'scaled-down' sound with half the volume to Audacity. The result of the last computation of the Nyquist code always gets automatically returned to Audacity.

Note: If you try 'scale' with big numbers you will notice that you can return sounds with volumes taller than the Audacity track which will sound horribly distorted if you play them afterwards in Audacity. So an important lesson to learn is that Nyquist gives you the freedom to do whatever you want but it's now on you to take care that the result will still sound tolerably afterwards.

  Back to top


2  Changing the Volume of Stereo Tracks Independently


To be able to change the volumes of both channels of a stereo track independently, we first have to split up the stereo track into two mono sounds, then change the volume of both mono sounds independently from each other, and afterwards we need to re-combine the two mono sounds to become a stereo sound again, before the sound can be given back to the Audacity stereo track.

This sounds a lot more complicated than the first example but fortunately Nyquist helps us with many build-in functions.

From the first example we already know how to change the volume with the 'scale' function, so we only need to find a way how to split and re-combine stereo sounds into single mono sounds and back to a stereo sound again.

  Back to top


2.1  Splitting and Re-combining Stereo Sounds


Here the important thing to know is that Nyquist handles sounds with more than one channel as arrays. A stereo sound in Nyquist is represented as an array with two 'slots' [also called 'fields' in other programming languages]. If a sound from an Audacity stereo track is given to Nyquist, the 's' variable is an array.

Note: To keep the code simple, the following examples only work with Audacity stereo tracks, with mono tracks you will get Nyquist errors ['Nyquist did not return audio', etc]. Click 'Debug' instead of 'OK' in the 'Nyquist prompt' window if you want to read the detailed Nyquist error messages. In the next chapter will show how to avoid such errors.

  Back to top


2.2  Splitting Stereo Sounds


The Nyquist function to reference single slots of arrays is:

where the first slot of the array is index 0 [zero].

With an Audacity stereo sound, the slot with the index 0 is always the left channel and the slot with the index 1 is always the right channel:

(aref s 0)  ; left channel
(aref s 1)  ; right channel

Note: everything after the first semicolon until the end of the line is a comment and therefore ignored by Nyquist.

  Back to top


2.3  Combining Mono Sounds


Now we still need a function to re-combine both mono sounds back into a stereo array. Therefore the Nyquist 'vector' function is very handy:

A 'vector' is a one-dimensional array. The 'vector' function creates an array with as many slots as 'expressions' are given as arguments. If we give two sounds as arguments [the two mono channels] we will get back an array of two sounds, what in Nyquist equals to a stereo sound.

The 'stereo to 2 x mono and back again' code in Nyquist would look like this:

(vector
  (aref s 0)   ; left channel
  (aref s 1))  ; right channel

Note: Look at the ordering of the opening and closing parens. The parens tell the interpreter which function comes first. The function in the innermost parens in Lisp ALWAYS gets computed first. So this way the return values from (aref s 0) and (aref s 1) will be given as arguments to the 'vector' function, which in turn will combine and return them as an one-dimensional array with two slots.

  Back to top


2.4  Processing Both Channels Independently


First remember how we changed the volume in the first example:

(scale 0.5 s)

Next we take again advantage of one of the most important principles of Lisp, always to compute the innermost parens first. Look again at the 'vector' code from above. All you have to do is to replace the two innermost occurrences of 's' [the arguments to 'aref'] with the code from the first example:

(vector
  (aref (scale 0.5 s) 0)   ; left channel
  (aref (scale 0.5 s) 1))  ; right channel

The result of course still makes not much difference to the first example, but now you can write:

(vector
  (aref (scale 0.5 s) 0)   ; left channel
  (aref (scale 2.0 s) 1))  ; right channel

Then the left channel will be returned with half the volume while the right channel will be returned with the double volume. This way now both channels can be amplified or attenuated independently from each other.

  Back to top


3  Handling Mono and Stereo Tracks Automatically


We still have the problem that our stereo function raises errors with mono tracks. Now we will see how mono and stereo tracks can be recognized and handled automatically.

  Back to top


3.1  Testing for Stereo Sounds


As you already know, Nyquist handles sounds with more than one channel as arrays.

The Nyquist function to test wether a variable is an array or not is:

Some simple tests with 'arrayp':

Load a mono or a stereo track into Audacity or create a track with any of the generators from the Audacity 'Generate' menu, then mark the whole track or only a part part of it, and open the 'Nyquist Prompt' from the Audacity 'Effect' menu. Into the text field you type:

(print (arrayp s))

Important: Please take care to type the correct ordering of opening and closing parens. The parens tell the interpreter which function comes first. The function in the innermost parens in Lisp ALWAYS gets computed first. Here the return value from (arrayp s) will be given to the 'print' function, which in turn will print the result to the Nyquist 'debug' window.

Important: In the 'Nyquist Prompt' window, do NOT klick the 'OK' button, klick the 'Debug' button instead, otherwise you won't be able to see the result. This way you will simultaneously learn how to use the Nyquist debugging tools.

After clicking the 'Debug' button, first a window 'Nyquist did not return audio' [or similar] appears, were you just klick 'OK'. Then, directly afterwards, a second window 'Nyquist output' [the debugger window] appears with the printed result of the 'arrayp' function:

T
  -  meaning 'true', the sound is an array [= a stereo sound]
NIL
  -  meaning 'false', the sound is NOT an array [= a mono sound]

  Back to top


3.2  If-Then-Else with Lisp


Now that we know how to find out wether the 's' variable contains a mono or stereo sound we can use 'arrayp' in an if-then-else construct. In contrast to most other programming languages in Lisp there is only an 'if' function, but no 'then' and 'else' keywords, instead the ordering what to compute in which case is done with the parens [what else].

We can write Nyquist code for handling mono and stereo signals automatically like this:

(if (arrayp s)         ; IF s is an array [= stereo]
    (stereo-function)  ; THEN use the stereo function
  (mono-function))     ; ELSE use the mono function

Note: Here you can see that Lisp code usually does not get read and understood by humans with counting the parens, but by the different indentation level of the lines. It is also very helpful to use an editor which is capable to 'match' parens. E.g. if you move the cursor to an opening or closing paren, the other related opening or closing paren will be automatically highlighted. This will prevent you from going nuts with counting.

  Back to top


3.3  Handling Mono and Stereo Tracks Automatically


In the next version we will extend our stereo function with an 'arrayp' if-then-else construct and a window with a message to the user, which gets displayed with mono tracks:

(if (arrayp s)
    (vector
      (aref (scale 0.5 s) 0)   ; left channel
      (aref (scale 2.0 s) 1))  ; right channel
  "This function only works with stereo tracks.")  ; message to the user

Note: If Nyquist gives back a string instead of a sound to Audacity, the 'Nyquist did not return audio' window will be replaced by a window displaying the Nyquist string as a message to the user.

It is also possible to give back the unmodified sound in the 's' variable:

(if (arrayp s)
    (vector
      (aref (scale 0.5 s) 0)   ; left channel
      (aref (scale 2.0 s) 1))  ; right channel
  s)  ; unmodified sound

No error will happen and no window will be displayed, Audacity will just re-insert the unmodified sound at the same place where it came from.

  Back to top


Steven Jones / Pedro Morales / David R. Sky / Nyquist and Emacs / Audacity Wiki


Audacity Support Forum / Audacity and Nyquist / Nyquist Reference Manual / Nyquist Examples and Tutorials