Switching between two traks

Using Nyquist scripts in Audacity.
Post and download new plug-ins.
Forum rules
If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like
Post Reply
Scree
Posts: 8
Joined: Wed May 14, 2014 9:45 pm
Operating System: Please select

Switching between two traks

Post by Scree » Wed May 14, 2014 9:57 pm

Hi,
i'm new to nyquist. I need a plugin which switches between two tracks every x seconds. For example i have one track with
aaabbbbbaa
and anotherone
cddddccddd
and it switches every second to
a_a_b_b_a_
_d_d_c_d_d
__________
adadbcbdad

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

Sincerely,
Scree

steve
Site Admin
Posts: 80679
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Switching between two traks

Post by steve » Wed May 14, 2014 11:18 pm

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:
a_a_a_
or
_b_b_b

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:

Code: Select all

___    ___    ___    ___
   |__|   |__|   |__|
and for the "b" track, one like this:

Code: Select all

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

Thus for the "a" track you can have:

Code: Select all

(setq hz (/ 1.0 interval))
(sum 0.5 (mult 0.5 (osc-pulse hz 0)))
and for the "b" track:

Code: Select all

(sum 0.5 (mult -0.5 (osc-pulse 1 0)))
http://www.cs.cmu.edu/~rbd/doc/nyquist/ ... l#index370

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/ ... l#index589

Does that help?
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Scree
Posts: 8
Joined: Wed May 14, 2014 9:45 pm
Operating System: Please select

Re: Switching between two traks

Post by Scree » Fri May 16, 2014 7:53 am

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

Code: Select all

;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.

Sincerely,
Scree

steve
Site Admin
Posts: 80679
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Switching between two traks

Post by steve » Fri May 16, 2014 1:25 pm

Congratulations, it works :)

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

Code: Select all

.... (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:

Code: Select all

(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:

Code: Select all

--header..

;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))))
Scree wrote: It's a little bit uncomfortable, that you have to modify each track separately,
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:

Code: Select all

(setq *scratch* "Hello World")
the output will be: "Hello World".
Now run in the Nyquist Prompt:

Code: Select all

(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/e ... an-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.

Code: Select all

(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:

Code: Select all

; 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:

Code: Select all

; 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:

Code: Select all

; 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/e ... ef-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.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Post Reply