Multiple notches with Nyquist prompt?

It applies to all of the biquad filter functions (highpass, lowpass, notch …) and is very convenient.

Am I using a biquad function in this example:

(scale (/ 3 1.0 4) s)

Because that works on multichannel audio in Audacity 1.3 in the Nyquist prompt as well.

I think you are wrong. I think the environment changed so that you can write for a single channel and it will automatically be applied to every channel without having to test for multichannels in the code.

The ‘1.0’ is needed in order to convert the expression to float instead of integer.

No you’re not using a biquad function in that example, but I think you may have misunderstood what I meant.
In Audacity 1.2.6 some of the filter functions (such as highpass2, notch2,…) only worked for mono tracks, but in Audacity 1.3.12 the code for many filter functions (including highpass2, notch2,…) has been changed in dspprims.lsp so as to accommodate multichannel sounds (as described in my previous post).

I did not intend to suggest that only biquad-m functions worked with multi-channel sounds. Many other functions also work with multi-channel sounds.
My intention was to indicate that not all functions will work with multi-channel sounds in Audacity 1.3.12, and to illustrate why, in the specific case of highpass2 Audacity 1.3.12 is now able to process multi-channel sounds.

Some functions could be used on multi-channel sounds in Audacity 1.2.6. For example, (scale (/ 3 1.0 4) s) will work equally well for mono or stereo tracks in Audacity 1.2.6 or 1.3.12.

An example of a function that does not work in Audacity 1.3.12 with multi-channel sounds is (snd-srate s)

That works fine, but it might perhaps be more straightforward to write (scale (/ 3 4.0) s) or perhaps (scale (/ 3.0 4.0) s). (If either the 3 or the 4 are floats then the division will be calculated as a float.)

That works fine, but it might perhaps be more straightforward to write (scale (/ 3 4.0) s) or perhaps (scale (/ 3.0 4.0) s). (If either the 3 or the 4 are floats then the division will be calculated as a float.)

The Nyquist XLisp 2.0 manual recommended doing it that way; using 1.0 as the float does emphasis that I am trying to treat integers as floats. It’s less typing that putting a zero after all of them and seems less arbitrary than choosing which one in the ratio I want to make a float.

http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-011.htm

Note: An easy way to force a sequence of integers to be divided as floating point numbers is to insert the number 1.0 after the first argument in the list of arguments to the divider function.

Stephen

I think that’s just a little “useful tip” from Edgar (the author) rather than a general recommendation.

In practice (in plug-ins) you would often be using variables rather than numbers. Taking your example:

(scale (/ 3 1.0 4) s)

If we new in advance that we wanted to use 3/4 (which we would need to know if we were to use numbers) then we would probably just write:

(scale 0.75 s)

However, if we wanted to use (for example) a quarter of some value (var):

here’s the basic code:

(scale (/ var 4) s)

but we know that if var is an integer then we have a problem.

Try this code:

(setq var 3)
(scale (/ var 4) s)

because var is an integer less than 4, var/4 =0
so the result is silence.

There are several solutions to this problem.
We could use Edgar’s tip and write:

(setq var 3)
(scale (/ var 1.0 4) s)

or we could ensure that var is a flonum (a floating point number)

(setq var 3.0)
(scale (/ var 4) s)

If we don’t know if var is an integer or a flonum, then we can either force var to be a flonum

(setq var (float var))

or we can force a floating point calculation with either

(scale (/ var 1.0 4) s)

or

(scale (/ var 4.0) s)

(personal opinion)
When setting a variable to a flonum value, I would always add .0 if the value was a whole number.
When setting a variable to an integer value I would always write the value as an integer (no decimal point).
This way it is easy to see whether the value is a flonum or an integer.

There’s a couple of ways that flonums can be converted to integers - you can either use the function ‘round’ or the function ‘truncate’
Truncate simply knocks off the decimal fraction to leave the integer, so (truncate 3.5) will return ‘3’ (which is an integer value).
http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-289.htm

I’ve not seen the ‘round’ function documented anywhere, but what it does is to round the value to the nearest integer, so (round 3.5) returns 4 (.5 is rounded up to the next integer value). The ‘round’ function is only available in recent versions of Audacity.

Example code for ‘truncate’ and ‘round’ functions (use the Debug button to see the output if using the Nyquist Prompt effect)

(setq var 0)
(dotimes (i 20)
   (setq var (+ var 0.1))
   (format T "var = ~a~%" var)
   (format T "(truncate var) = ~a~%" (truncate var))
   (format T "(round var) = ~a~%~%" (round var)))

(here’s a trick question - what’s going on when var = 1.0 ?)

For converting from integer to flonum the usual method would be to use (float var), but there are lots of alternative ways, for example:

(setq *float-format* "%f")
(setq var 3)

(format T "var = ~a~%" var)
(format T "(float var) = ~a~%" (float var))
(format T "(* 1.0 var) = ~a~%" (* 1.0 var))
(format T "(+ 0.0 var) = ~a~%" (+ 0.0 var))
(format T "(/ var 1.0) = ~a~%" (/ var 1.0))

I’m sure that you could think of some other ways.

BTW, (format T “string”) sends the string to the standard-output which by default for Audacity is the debug screen.
http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-121.htm