Vibrato Nyquist script

Does anyone know of a Nyquist script to do a vibrato? I’m new to Nyquist and since I’d like to add a little vibrato on one note, it would be nice if there’s a script already existing, rather than having to actually write something from scratch just to finish up this one little sound track.

Ideally this would be something that could create a sort of “envelope” of vibrato so that it could start slow with a very small range, and then get faster and wider, and back again, so that the transition from the surrounding sound is very smooth.

I tried a VST pluging called JS vibrato, but that only works in preview mode; it actually deletes the sound if you try to apply it. And of course a Nyquist script seems to be the safest route anyway in terms of online safety.

There’s a plug-in that will do a variable “tremolo” (the amplitude wobbles with a tremolo effect, whereas the frequency wobbles with a vibrato effect).
If you want the develop a true “vibrato” effect, this variable tremolo effect may give you some ideas of where to start.

To create a varying pitch effect is quite tricky as it it involves “warp”, which is probably the most difficult concept in Nyquist, but could be accomplished using the function (snd-compose) http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/manual/part6.html#index502

Sorry, not mucht time yet, but maybe this helps:

The Nyquist FMOSC can take a wavetable as argument. If you turn the Audacity “s” sound into a wavetable (or two wavetables with a stereo sound) then FMOSC can do an LFO-controlled frequency modulation (= vibrato) with it. If a second FMOSC is used as the LFO then the vibrato frequency as well as the modulation depth can be controlled via PWL envelopes.

See the Vinal Scratch Tutorial to get an idea how this works. Use the Audacity “s” sound instead of the “voc1.snd” file from the tutorial.

That’ll work very nicely for very short sounds, but the maximum size of a wavetable is only 100000 samples (about 2 seconds at 44100 Hz). Is there a way to work round that?

Thanks for the comments so far…This helps me get started at least. I actually did start by looking at the tremolo plugin yesterday, but I have a heck of a lot of reading to do in order to understand LISP, Nyquist, and the basic hooks for Audacity plugins. I was hoping there would be something out there so I could just focus on my music piece and maybe learn Nyquist later sometime, but I guess there’s no such shortcut. :slight_smile:

So far I’ve also found some relevant examples at http://www.cs.cmu.edu/~rbd/doc/nyquist/part6.html and http://audacity-forum.de/download/edgar/nyquist/nyquist-doc/examples/rbd/14-warble-tutorial.htm , both of which seem to use that fmosc function. The sound samples in the warble-tutorial as well as the vinyl scratch are longer than 2 seconds…I suppose that’s because since the oscillation repeats, there’s not really any time limit?

I’m seeing “s” in a lot of the plugins. I’m guessing “s” is what allows the code to refer to the existing sound that’s being modified?

How long is that one note?

If the note is less than 100000 samples and is mono, you can use this code in the “Nyquist Prompt” effect:

(setq initial-speed 1.0) ; Hz
(setq final-speed 4.0)
(setq initial-depth 50) ; scale of 0 to 100
(setq final-depth 50)

(setq initial-speed (/ initial-speed 2.0)) ; 1/2 the vibrato speed
(setq final-speed (/ final-speed 2.0))
(setf vib-speed (pwlv initial-speed 1 final-speed)) ; the vibrato speed envelope

(setq initial-depth (/ initial-depth 100.0)) ; changes scale from % to a scale of 0 to 1
(setq final-depth (/ final-depth 100.0))
(setf vib-depth (pwlv initial-depth 1 final-depth)) ; the vibrato depth envelope

(setf *s-table* (list s 0 nil)) ; makes the sound 's' into a wavetable

(fmosc 0.0 (mult vib-depth (fmosc 0 vib-speed)) *s-table* 0) ;

Newbis: > I’m seeing “s” in a lot of the plugins. I’m guessing “s” is what allows the code to refer to the existing sound that’s being modified?

The “s” variable is the sound object given from the Audacity Nyquist interface to the Nyquist interpreter, see Nyquist Variables.

Unfortunately the Audacity Nyquist documentation is a bit littered, because Nyquist was “added” to Audacity later on, so some aspects of Nyquist in Audacity do not fully comply to the original CMU Nyquist, as described in Roger Dannenberg’s Nyquist manual.

The basics of Nyquist in Audacity are described under:

In the German Audacity Forum (text is in English language):

steve: > the maximum size of a wavetable is only 100000 samples

Unfortunately once again Steve is right, and even worse, it’s a limit in the Nyquist C-code, so there is no easy workaround from the Lisp level.

Newbis: > The sound samples in the warble-tutorial as well as the vinyl scratch are longer than 2 seconds…I suppose that’s because since the oscillation repeats, there’s not really any time limit?

A “wavetable” is a sound that is played by some of the Nyquist oscillators (OSC, FMOSC, etc.) as a “loop” in circle, so the sound output of the oscillator itself is not limited in length, but the length of the “loop” (= wavetable) is limited to 100000 samples. If we want to use the Audacity selection as a “loop” in FMOSC, then FMOSC will complain “maximum wavetable length exceeded” if the Audacity selection is longer than 100000 samples.

I still have no really good idea how to work around the 100000 samples limit but will try to work on this later on…

That’s because the wavetable repeats.
The wavetable in the warble tutorial is the default sine table which consists of just one cycle of a sine wave which then repeats for as long as required.
if the vibrato is to be applied to an existing (recorded) sound (rather than generating a tone), the wavetable must contain the entire waveform.
Nyquist in Audacity 1.3.13 is configured with a maximum size of 100000 samples, hence the length restriction when applying fmosc to a recorded sound.

“s” is a “global variable” that is used to pass audio data from Audacity into Nyquist.
For a mono track, “s” is a sound.
For a stereo track, “s” is an array with two elements. The two elements are sounds and correspond to the left and audio right channels.

There’s a good introduction to Nyquist programming here: http://audacityteam.org/help/nyquist

And another really useful one: Audacity and Nyquist

And the manuals:
http://www.cs.cmu.edu/~rbd/doc/nyquist/title.html
http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-index.htm

(I see that Edgar has posted while I’ve been typing and already covered some of these points, but I’ve started so I’ll finish :wink:

It would be quite easy to turn this code into a “plug-in”.
The first 4 lines set the user input variables,

(setq initial-speed 1.0) ; Hz
(setq final-speed 4.0)
(setq initial-depth 50) ; scale of 0 to 100
(setq final-depth 50)

These variable could be set as “slider controls” (see here: Audacity and Nyquist )
Unfortunately it does have the 100000 sample limit, so it’s not hugely useful as a general purpose vibrato plug-in.

Thanks! I’ll try that. I suppose I just put that together with the header comments that apparently tell Audacity what the plugin is, and then it’s all set? The note is very short…less than a second, and ideally I’d want the degree of vibrato to get more intense towards the middle. String players call that a “vibrato accent,” where you just give a tiny bit of vibrato for emphasis.

But it’s in stereo…Is it hard to modify this for a stereo track?

To use the code, making a full plug-in is optional. The code will run as is in the “Nyquist Prompt” http://manual.audacityteam.org/man/Nyquist_Prompt

Currently the “the vibrato speed envelope” and “the vibrato depth envelope” have just 2 points defined - the start and the end. You can extend the (pwlv) function to add as many control points as you like.
http://www.cs.cmu.edu/~rbd/doc/nyquist/part8.html#index384
for example:

(pwlv initial-depth 0.5 mid-depth 1 final-depth)



Try it first with mono tracks.
A stereo track can be split into 2 mono tracks, and 2 mono tracks can be (re)joined into a stereo track - click on the track name for a drop down menu with these options.

See here for using stereo tracks in Nyquist:
http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/devel/audacity-nyquist-en.htm#stereo

Thanks for everyone’s help. I know I have a lot of reading to do on this…:slight_smile: As a first shot, I just pasted the code as a plugin, but I get “Nyquist did not return audio.” If I enter it into the Nyquist prompt and click “Debug,” I get this (below). From what I can make out, fmosc calls the lower level snd-fmosc, and it’s complaining there about what was passed in. It’s a little hard for me to make out what it doesn’t like though.

error: bad argument type - #(#<Sound: #6ef0328> #<Sound: #6ef0568>)
Function: #<Subr-SND-FMOSC: #6c77cb0>
Arguments:
  #(#<Sound: #6ef0328> #<Sound: #6ef0568>)
  0
  44100
  8.1758
  0
  #<Sound: #6ef0a18>
  0
Function: #<FSubr-LET: #6c73350>
Arguments:
  ((MODULATION-SRATE (SND-SRATE MODULATION)) (HZ (STEP-TO-HZ (+ PITCH (GET-TRANSPOSE)))))
  (COND ((< *SOUND-SRATE* MODULATION-SRATE) (FORMAT T "Warning: down-sampling FM modulation in fmosc~%") (SETF MODULATION (SND-DOWN *SOUND-SRATE* MODULATION))))
  (COND ((> HZ (/ *SOUND-SRATE* 2)) (FORMAT T "Warning: fmosc nominal frequency (~A hz) will alias at current sample rate (~A hz).n" HZ *SOUND-SRATE*)))
  (SCALE-DB (GET-LOUD) (SND-FMOSC (CAR SOUND) (CADR SOUND) *SOUND-SRATE* HZ (LOCAL-TO-GLOBAL 0) MODULATION PHASE))
Function: #<Closure-FMOSC: #6b51070>
Arguments:
  0
  #<Sound: #6ef0a18>
  (#(#<Sound: #6ef0328> #<Sound: #6ef0568>) 0 NIL)
  0
1>

Which version of Audacity are you using? (look in “Help menu > About Audacity” for the exact version number).

That error looks like you are applying the code to a stereo track. The code (as is) will only work on a mono track.

Here’s a version that works with stereo tracks. It still has the 100,000 sample (per channel) limitation, but as Edgar explained, this is a limitation of the (fmosc) function and is hard coded into Audacity.

(setq initial-speed 1.0) ; Hz
(setq final-speed 5.0)
(setq initial-depth 10) ; scale of 0 to 100
; values greater than 100 will produce extreme vibrato
(setq mid-depth 100)
(setq final-depth 20)
(setq mid-pos 30) ; position of the 'mid' point as % of the selection length
; 'mid' point of 30% is about 1/3 of the way along the selection

(setq initial-speed (/ initial-speed 2.0)) ; 1/2 the vibrato speed
(setq final-speed (/ final-speed 2.0))
(setf vib-speed (pwlv initial-speed 1 final-speed)) ; the vibrato speed envelope

(setq initial-depth (/ initial-depth 100.0)) ; changes scale from % to a scale of 0 to 1
(setq mid-depth (/ mid-depth 100.0))
(setq final-depth (/ final-depth 100.0))
(setq mid-pos (/ mid-pos 100.0))
(setf vib-depth (pwlv initial-depth mid-pos mid-depth 1 final-depth)) ; the vibrato depth envelope

(defun vibrato (s-in)
	(setf *s-table* (list s-in 0 nil)) ; makes the sound 's' into a wavetable
	(fmosc 0.0 (mult vib-depth (fmosc 0 vib-speed)) *s-table* 0))

(setq *float-format* "%.2f") ; set printed output to 2 decimal places
(if (> len 100000)
	(format nil "ERROR~%Selection length too long.~%Maximum length at ~a Hz (sample rate) is ~a seconds." *sound-srate* (/ 100000 *sound-srate*))
	(multichan-expand #'vibrato s))

Toward the end you’ll notice an (if) structure. This checks the length of the selection before processing and outputs a meaningful error message if the selection is too long.
You may be interested to compare this code with the plug-in version that I’ve posted here: https://forum.audacityteam.org/t/vibrato/18944/1

The plug-in code can be opened in any plain text editor (such as NotePad), though for writing Nyquist scripts I would highly recommend using a plain text editor that supports bracket matching (such as NotePad++).

That’s great…thanks. It’s interesting that when you add the user controls, it enables Audacity’s undo feature, whereas the version without the user controls can’t be undone except by exiting the file without saving.

Anyhow, this gives me pretty much what I was looking for. I’m trying it with initial speed and depth of 0, final speed of 1, and midpoint depth of 8. That gives me close to what I want, although I’ll probably play with it further.

If you decrease some of the default values slightly and change the “debug” button into a “preview” button, I bet a lot of people would be interested in this.

You should be able to Undo the effect when applied from the Nyquist Prompt, but it won’t be listed as “vibrato”, it should be listed as “Nyquist Prompt”.

If it does not Undo, then either you have applied the effect more than once and you are only Undoing the last application of the effect (press Undo again to Undo the previous action, or go to “View Menu > History” to undo multiple levels in one go), or there is something wrong, in which case please specify which version of Audacity you are using. Please could you check this, as the Undo should work with the Nyquist Prompt.

I deliberately set the values quite high so that the user (you) could hear easily what it is doing.
If you want to customise the script and set your own default values, then see here for the format of the ;control settings: Audacity and Nyquist

You will see that the last three parameters are initial-value minimum maximum
The initial-value is the default when you first use the effect in an Audacity session. Set that to whatever you want.

Unfortunately Nyquist plug-ins do not support a Preview function, though I have it on a wish-list here: Wish List - Preview button for 'process' plug-ins

I actually wasn’t doing it from the Nyquist prompt, but was pasting your earlier code (without the controls) together with header information based on other plugins. At the time, after applying vibrato, “Undo” was grayed out. However, I tried it again now, with what I think was exactly the same header and code I was trying before, and Undo works now. So it must have been a fluke.

I did try earlier today changing the default settings, plus I tried having a “mid-speed” control. However, when I set it to something other than 1, it changed the length of the selection, so its role in pwlv must be different from what I thought. Anyhow, I’ll have to look more into how it really works when I have time.

As of now though, I got my sound editing finished up, and it sounds good. I applied it on one note on the saxophone that hadn’t sounded expressive enough before. One thing I found was that the vibrato sounds best when I add a little extra reverb, which I did with a VST plugin I had bought, using the “plate” preset.

By the way, I understand what you’re saying about the defaults; it makes sense from a developer’s point of view to have the default be dramatic so it’s clear it’s really doing something. As a user, though, I do find that a lot of the Audacity effects may cause users to underestimate their quality, because the default settings seem so blatant. It’s just a psychological “first impressions” sort of thing. :slight_smile:

You may have missed some of the header information the first time that you did it and left Audacity not knowing what it had done :slight_smile:

There are several different forms of the “pwl” command:

where t’ is the time index and l’ is the level

For the first two version, the time index is (usually) relative to the length of the selected audio, so t=0 is the beginning and t=1 is the end

(pwl t1 l1 t2 l2 ... tn)

t=0 l=0 is assumed for the start


(pwlv l1 t2 l2 t3 t3 ... tn ln)

t=0 is assumed


The next two variations are of a similar form to the first two, but t’ is a time interval, so each t’ value is added to the end of the previous time.
Example,
if t1 = 0, t2=0.2, t3=0.3, t4=0.1, then that will create points at 0, 0.2, 0.5 and 0.6

(pwlr i1 l1 i2 l2 ... in)

t=0 l=0 is assumed for the start


(pwlvr l1 t2 l2 t3 t3 ... tn ln)

t=0 is assumed

The version that I have used is (pwlv l1 t2 l2 t3 t3 … tn ln)

If you get stuck, post what you’ve got so far.

I agree entirely.

I recently modified the GVerb plug-in (unfortunately the modification only works on Linux at the moment). The current default values are so awful that most users go running to find a better replacement. GVerb is probably not the best reverb effect, but with suitable settings it’s a heck of a lot better than first impressions. The first user feedback that I had about the modification was that it didn’t work. I suggested that they tested it on a completely “dry” recording (a “clean” sound with little or no reverb or other effect) because any existing effects may be masking the new GVerb effect. They then replied saying “Oh yes, it’s subtle, like the kind of reverb that you might apply to a vocal”.

So there we have the two extremes, an effect that is so “strong” that it sounds terrible, and much more useful effect settings where it may not be obvious that it is doing anything.

It is very easy to overdo effects. For most types of music I generally recommend that effects should be backed off so that you can just hear the effect, then back it off a little more and that will probably be just the right amount. Of course this depends on music tastes and the type of music. Many modern genres are supposed to have in-your-face effects.

Thanks for your explanations and all your help on this. :slight_smile: