stereo-chorus by Kathy Drye and Roger Dannenberg

Hello.
Please, read this code:]

(defun nyq:snd-tapv (sound offset modulation maxdepth)
  (multichan-expand #'snd-tapv sound offset modulation maxdepth))

(defun delay-tapv (sound maxdelay delay
                            depth rate 
                       saturation &optional (phase 0.0))
 (let 
  ((modulation 
   (sum delay (prod depth (lfo rate 10000.0 *sine-table* phase)))))
    (hp (sum (prod (nyq:snd-tapv sound 0.0 modulation maxdelay)
                   saturation) sound) 10)))

(defun chorus (input-sound &key (delay 0.03) (depth 0.003) 
                                (rate 0.3) (saturation 1.0)
                                (phase 0.0)) 
  (delay-tapv input-sound (+ delay depth) 
              delay depth rate saturation phase))


(defun stereo-chorus (input-sound &key (delay 0.03) (depth 0.003) 
                                       (rate1 0.3) (rate2 0.1)
                                       (saturation 1.0))
   (sim
       (pan (chorus input-sound :delay delay :depth depth :rate rate1
                    :saturation saturation) .3)
       (pan (chorus input-sound :delay delay :depth depth :rate rate2
                    :saturation saturation :phase 180.0) .7)))

I have write this code

(abs-env 
 (stereo-chorus (osc 56 5) 0.0))

It does not work well. If I modify the value of the argument rate2, the effect applies to 2 channels. The same goes for the argument rate1. Do you understand the reason of this problem?

I have a second question has to put: in this code, the function stereo-chorus calls the function chorus. This function has the same arguments as the function stereo-chorus. On the other hand, when we adjust the value of an argument of the function stereo-chorus, I have the impression that the regulation of the same argument in the function chorus does not seem to contradict the regulation.
My question is thus: How is this way of functioning possible?
I hope that I am understandable.
Beforehand thank you for your help

The final argument (0.0) in your code will be ignored because you have not given a “key-symbol”.

See here for how “&key” is used:
http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-143.htm

Example. You could have something like:

(stereo-chorus (osc 56 5) :delay 0.1 :depth 0.1)

or

(stereo-chorus (osc 56 5) :delay 0.1)

(where “:depth” will take the default value)

or

(stereo-chorus (osc 56 5) :depth 0.1)

(where “:delay” will take the default value)

or

(stereo-chorus (osc 56 5))

(where both “:depth” and “:delay” take the default values).


When you call a named function and supply it with arguments, the arguments are passed to the named function.
Taking a really simple example:

Nyquist has a built-in function for summing numbers. The function name is “+”. The function takes one or more arguments which must be numbers, and returns the sum of the arguments.
(+ arg1 arg2 …)
For example:

(+ 2 3.5)  ; returns 5.5

The argument “2” (which is a numeric value) and the argument “3.5” (another numeric value) are the two arguments that we send to the function “+”.

Similarly Nyquist has a built-in function called “-” which subtracts numbers.
Example:

(- 10.1 2) ; returns 8.1

Now consider this code;

(setq a 3) ;symbol "a" has the value "3"
(setq b 4) ;symbol "b" has the value "4"

(setq c (+ a b)) ;pass the arguments "a" and "b" to the function "+". The symbol "c" takes the returned value from the function "+".

(print c) ; prints "7"

(setq a 10) ;set the value of "a" to "10"
(setq b 5) ;set the value of "b" to "5"
(setq d (- a b)) ; pass the arguments "a" and b" to the function "-".

(print d) ; prints "5"
(print c) ; prints "7"

Note that in the above example, the value for “c” is still “7” even though we have changed the values of “a” and “b”.
When the expression (+ a b) was evaluated, the value of “a” was “3” and the value of “b” was “4”.

If we continue the above example:

(setq c (+ a b)) 
(print c) ;prints "15"

We have called the function “+” again, and passed it the arguments “a” and “b”, but now the values are a=10 b=5, so the expression (+ a b) evaluates to 15.

Does that answer your question?

Hello.
Thank you for these details. Now, it is more understandable.
I have a question to ask. It concerns the body of the function “chorus”.
The code is

 (delay-tapv input-sound (+ delay depth) 
              delay depth rate saturation phase))

I do not understand which calculations Lisp realize, and in which order. Can you explain me the meaning of the code:

(delay-tapv input-sound (+ delay depth)

Thank you in advance.

The function “delay-tapv” is defined in the code as:

(defun delay-tapv (sound maxdelay delay
                            depth rate
                       saturation &optional (phase 0.0))
 (let
  ((modulation
   (sum delay (prod depth (lfo rate 10000.0 *sine-table* phase)))))
    (hp (sum (prod (nyq:snd-tapv sound 0.0 modulation maxdelay)
                   saturation) sound) 10)))

Look at the parentheses in the first 3 lines an notice that the function has 6 required argument and one optional argument. The required arguments are:
sound
maxdelay
delay
depth
rate
saturation

The optional argument is “phase” and it has a default value of 0.0.

See here for more information about the structure of a LISP function: http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-087.htm