Switching between two traks

i’m new to nyquist. I need a plugin which switches between two tracks every x seconds. For example i have one track with
and anotherone
and it switches every second to


i hope you understand what i mean, my english is not the best ^^’

all i got so far is the code for the input of a variable
;control interval “Interval” real “sec” 1 0.001 180
and the code to produce silence
(stretch-abs interval (s-rest 1)))

but i dont know how to loop it.

maybe someone can help me


Nyquist can only access one track at a time, so working with multiple tracks can be tricky.
In this case I thing the easiest approach will be to make a plug-in that you can run twice, one for each track separately, and a control to set whether it is to do:

Essentially what you are doing to each track, is modulating the amplitude with a square wave.
Multiplying the sound by +1.0 leaves the sound unchanged. Multiplying the sound by 0.0 will silence the sound, thus, for the “a” track we want to modulate with a square wave like this:

___    ___    ___    ___
   |__|   |__|   |__|

and for the “b” track, one like this:

   ___    ___    ___    ___
__|   |__|   |__|   |__|

The modulation waves are identical square waves, but 180 degree out of phase.

Thus for the “a” track you can have:

(setq hz (/ 1.0 interval))
(sum 0.5 (mult 0.5 (osc-pulse hz 0)))

and for the “b” track:

(sum 0.5 (mult -0.5 (osc-pulse 1 0)))


Note that the “b” square wave is multiplied by -0.5 rather than +0.5, making the two waveforms 180 degrees out of phase.

Then to modulate the sound, just multiply (MULT) http://www.cs.cmu.edu/~rbd/doc/nyquist/part8.html#index589

Does that help?

Thanks, that helps a lot. My plugin now looks like this

;nyquist plug-in
;version 3
;type process
;name "mixer"
;action "doing stuff"
;control interval "Interval" real "sec" 1 0.001 180
;control inv "Inverse" int "off" 1 -1 1 "on"
(setq hz (/ 1.0 interval))
(mult s (sum 0.5 (mult (mult inv 0.5) (osc-pulse hz 0))))

and it does what it should do. It’s a little bit uncomfortable, that you have to modify each track separately, but its ok.


Congratulations, it works :slight_smile:

In your final line, you don’t need to write:

.... (mult (mult inv 0.5) (osc-pulse hz 0))))

The MULT function can be used as (mult a b c d) so the last line could be:

(mult s (sum 0.5 (mult inv 0.5 (osc-pulse hz 0))))

An alternative to setting INV with a slider widget would be to use a choice widget, something like this:


;control interval "Interval" real "sec" 1 0.001 180
;control inv "Inverse" choice "Off,On" 0

(setq hz (/ 1.0 interval))
(setq inv
  (if (= inv 0) -1 1))

(mult s (sum 0.5 (mult inv 0.5 (osc-pulse hz 0))))

We can mostly get round that by using the special variable SCRATCH.
SCRATCH is special because it persists for the duration of the Audacity session. For example, if you run this in the Nyquist Prompt effect:

(setq *scratch* "Hello World")

the output will be: “Hello World”.
Now run in the Nyquist Prompt:

(print *scratch*)

and again the output is “Hello World”.

There is however a danger in using scratch like this - another plug-in could overwrite your stored value.
A better way to use scratch is to use a “property list”: http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-man/xlisp-man-014.htm

The symbol scratch (as with all Nyquist code, it is case insensitive) is a predefined symbol in Nyquist, so you don’t even need to bind it to a value before using it.

The general idea is that, to avoid clashing with the use of scratch in other plug-ins, you use a unique “property name”. It is best to chose a name that is unlikely to occur in any other plug-in. You can then give that property a “value”.

When the plug-in runs, we will need to test for the existence of our scratch property, and if it exists, check its value.
In this simplified example I’ve not used a good name for our “unique” property symbol.

(if (and  (get '*scratch* 'invert)        ; does the property "invert" exist?
        (= (get '*scratch* 'invert) -1))  ; is its value -1 ?
    (... do inverted version and set 'invert to +1)
    (... don non-inverted version and set 'invert to -1))

Note that in the example above SCRATCH and INVERT are quoted, because we just want the symbol names, not their values.

As I had little previous experience programming, I had difficulty getting to grips with this, so for anyone in the same boat, here’s a couple of examples:

; Put 'myproperty into the property list of 'mysymbol
; and set the value of 'myproperty to 'myvalue.
(putprop 'mysymbol 'myvalue 'myproperty)

; Retrieve the value of 'myproperty and print it.
(setf test (get 'mysymbol 'myproperty))
(print test)

Note that the value of “test” is the symbol 'myval and not a string, so it will only be printed in the debug window.

If we use an actual string value, it will be printed in a message box:

; Put 'myproperty into the property list of 'mysymbol
; and set the value of 'myproperty to the string "Hello World".
(putprop 'mysymbol "Hello World" 'myproperty)

; Retrieve the value of 'myproperty and print it.
(setf test (get 'mysymbol 'myproperty))
(print test)

'MYSYMBOL is probably not a very safe “unique” property name, it could easily clash with another plug-in, so lets use a name that is unlikely to clash:

; Set MYPROPERTY to a "unique" symbol name
(setq myproperty 'this-property-symbol-is-unlikely-to-clash-fri-may-16-2014-2pm)

; Put the unique property into the property list of 'mysymbol
; and set the value to the string "Hello World".
; MYPROPERTY is not quoted, so it will be evaluated
; to the unique symbol name 'this-property-sym.....
(putprop 'mysymbol "Hello World" myproperty)

; Retrieve the value of 'myproperty and print it.
(setf test (get 'mysymbol myproperty))
(print test)

When using SCRATCH it is also good practice to either reset it automatically, or provide the means to rest it (an option in the plug-in interface).
Resetting is just a matter of removing the property that we created. (remprop sym prop) http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-221.htm

I’ve no idea what previous programming experience you have Scree, so if you would like an example of how this may be applied in your plug-in, just ask.