Need Help with Nyquist (noise n)

Hi all,

I’m pretty stuck with the (noise duration) function of Nyquist.

The reference says:


What exactly is the “1” representing? “1” being the complete selection, “0.5” being half of it?
I know it’s not time (as in seconds) and not number of samples.

The problem I’m having is, I make a selection to test, 72mS and (noise 1) generates 151mS worth of noise.

Help please.

Time is handled differently depending on whether you are running the script as a “generate” type plug-in or as a “process” (Effect) type plug-in.

In the case of generate type plug-ins, 1 “unit” of time is 1 second.

Try this in the Nyquist Prompt:

;type generate
(noise 10)

In process type plug-ins (“Effects”), time is stretched according to the length of the selection. In this case 1 “unit” of time is the full length of the selection. This example will produce white noise that is half the length of the selection:

;type process
(noise 0.5)

By default, the Nyquist Prompt runs code as “;type process”, so this will also produce noise that is half the length of the selection:

(noise 0.5)

For “;type process”, this “should” produce noise that is twice as long as the selection, but there’s a bug in the current version of Audacity that prevents it from exceeding the length of the selection:

;type process
(noise 2)

Hi Steve,

Thanks for your reply.

I tried both, i.e. ;type process and ;type generate.

What I found is:
(In both cases I made a small selection)

;type generate
(noise 0.5)
Does indeed generate 0.5 secs of noise, but… increases the length of the track by the same amount as the selection.

However, with
;type process
(noise 0.5)
It does create a smaller time of noise than my selection, but… it also shrinks the duration of the whole track by the same amount.

This is what is confusing me.

EDIT:

Screenshot below with ;type process and (noise 0.5)

BEFORE:
Note how the track (with a constant 1KHz tone is pretty much 2 secs long).


AFTER:
Note the track length now.

EDIT 2:

AHA, the penny has just dropped… gotta use sum.
For a mono track:

;type process
(sum track (noise 0.5))

Now everything is good.
I will leave this post as is, so that it can be helpful to others that may be struggling with the same thing.

Thanks again Steve, for adding the one bit of crucial information, the difference between ;type generate and ;type process.

The audio returned by Nyquist replaces the selected audio.
So if you select 2 seconds of audio and Nyquist returns 0.5 seconds of audio, the track will shrink by 1.5 seconds.


What you’re doing here is mixing (adding) the noise to the original audio that was in the track.
Nyquist returns the sum of (a mix of) the original selection and the noise. Because the track component of the mix is exactly the same length as the selection (it is the selected audio), the returned mix is the same length as the original selection. When the returned audio replaces the original selection, we still have that original audio because we added it into the mix.

Perfect, thank you Steve.

I just forgot that Nyquist will replace the audio (and hence compensate the total duration) to match.
By mixing, which is what I wanted, solved the problem.

The really useful thing about the (somewhat strange) way that “;type process” effects stretch time, is that if you want to return exactly the same amount of audio that is selected, then you don’t even need to know how long the selection is. You just return sound of length 1.

So…

;type process
(sum *track* (mult 0.2 (noise)))

will add the exact same length of noise as the selection length.

Yep, and the lengthening and shortening of the track can also be put to good use in other cases if required.

I’m getting there, slowly.

Parentheses are no longer a problem, even something like the below would have looked terrifying a few days ago.

;type process
; ..... etc
(sum *track* (scale vol (mult (highpass8 (lowpass8 (noise 1) center) center) (pwlv 0 1 1 1.1 1))))

The variable “vol” I get from a slider and convert with db-to-linear.
“center” is from a selection.
I know the “1” after “noise” is redundant as it’s the default, but like to keep it in.

Long lines are a pain to read. Parentheses matching helps, but long lines are still a pain :smiley:

I would tend to break up the line a bit like this:

(sum *track* 
    (scale vol (mult (pwlv 0 1 1 1.1 1)
                     (highpass8 (lowpass8 (noise 1) center) center))))

Note that “(pwlv” and “(highpass8” line up vertically, indicating that they are each arguments of “mult”.

If you look in “Nyquist” directory inside your Audacity installation folder, you will find a load of .LSP (Lisp) files. These can serve as a useful “style guide”.
The files can also be found on-line here: https://github.com/audacity/audacity/tree/master/nyquist

Don’t pay too much attention to the coding style in “aud-do-support.lsp”. That was written by myself and has a lot of very ugly code to bridge gaps between Nyquist and Audacity. It probably is worth taking a look at the functions in there as there are some useful functions that are not part of the stand-alone Nyquist (such as the two little functions and the little macro at the top). The big functions are for enabling Nyquist to send commands to Audacity through Audacity’s scripting API.

Just a little observation about this example:

Given that MULT is the same as SCALE when acting on sounds, that could be simplified:

(sum *track* 
    (mult vol
          (pwlv 0 1 1 1.1 1)
          (highpass8 (lowpass8 (noise 1) center) center)))

Also note that the length parameter for NOISE is optional, and the default is 1.
A longer, but perhaps easier to read way of writing the same code:

;type process
; ..... etc

(defun myfilter (s hz)
  (highpass8 (lowpass8 sig hz) hz))

;....

(sum *track* 
    (mult vol
          (pwlv 0 1 1 1.1 1)
          (myfilter (noise) center center)))

Good point about the formatting, much easier to read, will use it from now on.

As for the .lsp files, uhmmm, you have presented a veritable smorgasbord of possibilities.

Some great macros and also, the possibility of creating new ones.
My thinking is not to mess with the original files, but rather create a new one and add it to load in nyinit.lsp
Of course then any ny scripts that use the new functions/macros would not be standard.

Another possibility, since there is already a SAL parser, it would be theoretically feasible to create another “language”.
I’m quite enjoying Lisp now, so wouldn’t change, but thinking about something simpler which would hopefully entice more people to try out Nyquist.

All very interesting.

Yes, and for that reason it is nearly always best to include all custom functions and macros in the actual plug-in .ny file. You can then share your plug-ins with others, and easily install on multiple computers.

Yes that’s perfectly possible, but it would be a huge amount of work.
There are also opportunities to extend Nyquist: Appendix 1: Extending Nyquist
or even extending XLISP: Appendix 2: Intgen

Had a look at your “aud-do-support.lsp”, some very nice functions like for example, “char-remove”.

Also peeked inside other .lsp files that don’t seem to be shipped with Audacity, or
maybe I’m wrong and they have been incorporated into the existing .lsp files that are “standard”.

The functions relating to statistics, doppler shift and surround, all look mighty interesting and useful.

Thanks for the info.