Phase control added to TremVib.ny plugin

I wasn’t sure where to post this but I did my best guess. Recently I have been on an endeavor to correct the warping that occurs in some old bagpipe recordings that I have, most of which suffer from warping problems (i.e. a slow vibrato effect that occurs at the revolution of the record). It’s a bit of a complicated process to take care of the warping, even though I have discovered the plugin that can create a vibrato called “Tremvib.ny”. I absolutely love this plugin, but I’d like to request that a phase control should be added to the plugin. Unfortunately this plugin isn’t available through the Index of Nyquist plugins page, I found it while looking for a vibrato plugin via researching the forums. I remember the particular forum was called “Off center filter”, and the plugin could be downloaded from there. Here is what I do. Since the recordings were dubbed at a fixed speed of 78 RPM, what I do is change the speed to upwards of 6300 percent, so that the RPM rhythm becomes a note, it gets so fast that the actual revolution speed becomes 83.2 HZ. Then what I do is divide that number by 64 to get the exact vibrato speed to counteract the warping, which is roughly 1.3 HZ so it can be used in the original file. This does just fine, although when I apply the vibrato effect, even with a depth of 8 percent, the warping increases. I simply cannot insert silence at the beginning so that the warping and the vibrato effect would cancel each other out, so this is why I would like there to be a phase control added to the plugin. Unfortunately I am not trying to plagiarize here, but since I don’t really have experience attaching files to posts, I can paste the code in if you like.


;nyquist plug-in
;version 3
;type process
;categories ""
;name "Tremolo / Vibrato..."
;info "by Steve Daulton\nReleased under GPL v2.\n"

;; TremVib.ny - version 3 plug-in (requires Audacity 1.3 or later)
;; by Steve Daulton June 2011
;; Released under terms of the GNU General Public License version 2:
;; .

;control type "Select function" choice "Tremolo,Vibrato" 0  
;control wave "Modulation wave shape" choice "Sine,Triangle,Sawtooth,Inverse Sawtooth,Square,Random" 0
;control ispeed "Initial speed (Hz)" real "" 4 0 20000
;control fspeed "Final speed (Hz)" real "" 12 0 20000
;control idepth "Initial depth (%)" real "" 40 0 20000
;control fdepth "Final depth (%)" real "" 40 0 20000

; Function to make random waveform
(defun randwave (ifreq ffreq id fd)
	(let ((ifreq (* ifreq 4))
			(ffreq (* ffreq 4))
			(start (snd-avg (noise) 1 (round (/ *sound-srate* ifreq)) op-peak))
			(end (snd-avg (noise) 1 (round (/ *sound-srate* ffreq)) op-peak)))
		(sum -1
			(mult start (pwlv 1 1 0.5))
			(mult end (pwlv 0.5 1 1)))))

;; Alternative function for random waveform
(defun randmod (ifreq ffreq id fd)
; Function to limit input variables to sensible range
(defun sanitise (val minv maxv)
  (min (max val minv) maxv))

;; Vibrato function
(defun vibrato (s-in isp id fsp fd)
  (let* ((bend (mult (fmlfo (pwlv isp 1 fsp) *table*)(pwlv id 1 fd)))
        ;; map to sound-time
        (map (integrate (db-to-linear bend)))
        ;; correct map for exact length
        (map (mult (/ (get-duration 1)(peak map ny:all)) map)))
    ;; compensate for 95% normalizing and compose signal
    (mult (/ 0.95) (snd-resamplev s-in *sound-srate* map))))
 	;; Function to generate sweep tone
	(defun sweep (ifreq ffreq)
		   (mult -0.5 (sum 1.0 (fmlfo (pwlv ifreq 1.0 ffreq) *table*))))

 ;; Tremolo function
 (defun tremolo (s-in isp id fsp fd)
 	(let* ((wet (pwlv id 1 fd))
 			(dry (sum 1 (mult wet -1))))
 			(mult s-in (sum dry (mult wet (sum 1 (sweep isp fsp)))))))

(if (= type 2)(help)
    ; initialise error message
    (setq err "")
    ;; error checking
    (setq idepth 
      (if (= type 0)(/ (sanitise idepth 0 100) 100.0)(/ (sanitise idepth 0 20000) 100.0)))

    (setq fdepth 
      (if (= type 0)(/ (sanitise fdepth 0 100) 100.0)(/ (sanitise fdepth 0 20000) 100.0)))

    (if (or (> ispeed 20000)(> fspeed 20000))
      (setq err "Maximum modulation speed is 20000 Hz")
        (setq ispeed (sanitise ispeed 0 20000))
        (setq fspeed (sanitise fspeed 0 20000))))

    (setf *table*
      (case wave
        (0 *sine-table*) ; sine
        (1 *tri-table*) ; triangle
        (2 *saw-table*) ; sawtooth
        (3 (list (abs-env (pwlv -1 0 1 1 -1))(hz-to-step 1) T)) ; inverse sawtooth
        (4 (list (abs-env (pwlv -1 0.5 -1 0.5 1 1 1))(hz-to-step 1) T)))) ; square

    (if (> (length err) 0)
      (format nil "Error.~%~a" err)
      (case type
        (0 (multichan-expand #' tremolo s ispeed idepth fspeed fdepth))
        (1 (multichan-expand #' vibrato s ispeed idepth fspeed fdepth))

Now that you have the code, is it possible to add a phase control so that when I de-warp my bagpipe records that the existing warping and the vibrato effect would cancel the warping out? I understand there is a bit more to it than just phase, sure you have to have the right depths (which often get deeper as a record progresses), but phase should take care of the rest. Thank you and I hope to hear from you guys soon.


Try this modified version. I’ve changed the name to “Vibrato Phase…”, set the control ranges closer to your settings, and added a phase control.
vibratophase.ny (2.96 KB)

warped bagpipe records :astonished: : that sounds like one for the boys in Camp X-Ray. :slight_smile:

This is almost what I’m looking for, not to be offensive or anything, but I noticed a few things that were wrong with it. First of all there is only one speed control, maybe I should have made it more clear by having the exact same controls in the plugin while just adding the phase control. Also, the Initial Depth plugin has no effect, it would work out better if both depth controls actually modified the audio. Other than that I can’t see anything wrong with it. Right now, there is only “Speed”, and it controls the speed of the vibrato or tremolo. There is both “initial depth” and “Final depth”, but “initial depth” has no effect whatsoever. I’m trying not to be critical or anything, it’s just what I have found. Would it be too hard to modify it so that the controls do work correctly? (so that the Initial speed and final speed affect the audio, and so that initial depth and final depth both affect the audio as well). There are actually some bagpipe records that I have that start at one warp speed and end at another, and also some of them start at a warp depth and end at another. Essentially the existing code only with the necessary text added for a phase effect. Just thought I could tell you what I noticed, sorry for the inconvenience.

Trebor: Yes - warped bagpipe records do exist. The record I have that warps the most is J. Starck, “March Faughaballaugh”, from 1915, dubbed at 78 RPM though it was supposed to be dubbed at 80. There is this huge warp that I just can’t stand, you’ll hear it in the file if it does come through. The pipes played by the way are unique to Ireland, and the guy playing these actually is related to the maker. The maker is Henry Starck, and the guy playing it, according to a big book of Scottish records, is Joseph Starck. Unfortunately on the record it just says “J Starck”. Stupid! Just as another example - my girlfriend is named Deborah Adeniji. On an old record it would be credited as “D. Adeniji”. How stupid that is. Anyway, thanks.


Your record player speeds up / slows down? I expected a 78 to rotate at 78 RPM.

To re-enable the second speed control, delete the first semicolon from the line:

;;control fspeed "Final speed (Hz)" real "" 12 0 20000

so that it is:

;control fspeed "Final speed (Hz)" real "" 12 0 20000

Change the line:

;control ispeed "Speed (Hz)" real "" 1 0 10


;control ispeed "Initial speed (Hz)" real "" 1 0 10

Then delete the line;

(setf fspeed ispeed) ;constant speed

Works for me.
As a test, set the initial depth and final depth to 0 and 100 respectively, or the other way round, and apply to a 30 second constant tone (Generate menu > Tone).

There, now there is both initial and final speed. For some reason though, the initial depth still has no control. Do I delete the other semicolon from that line, or whatever? Not sure how to fix this. By the way, I do not have a record player. A guy gave me some CD’s where he dubbed the records, and I noticed that after speeding a record up, the note that the original RPM rhythm produced gets ever so slightly slower, like if it were so fast that the RPM becomes 82.3 HZ, at the end it might be something like 80.5 Hz, for some reason.

Never mind never mind never mind. Here’s the deal. So, I accidentally modified the code from:
;; error checking
(setq idepth
(if (= type 0)(/ (sanitise idepth 0 100) 100.0)(/ (sanitise idepth 0 20000) 100.0)))

I changed it accidentally to:

;; error checking
(setq idepth
(if (= type 0)(/ (sanitise idepth 0 100000) 100000.0)(/ (sanitise idepth 0 20000) 100000.0)))
So, after changing the 100000 to just 100, it works. What a dudelsack! (I know, nobody has used this derogatory word before, it’s not a usual word we use. Technically, it’s German for “bagpipes”, but to me this word just sounds so derogatory that I think it should be a popularized word… DUDELSACK, pronounced like “doodle-sack” if any you don’t speak German, hahaha…).

Now I have another problem. Sometimes, the warps that occur on the bagpipe records are not just sine waves, but also triangular waves. I’d like to know how to make it so that the vibratos follow the particular wave pattern, because when I select a wave other than Sine, it just uses a sine wave instead. What do I need to edit in order to make it so that all the waves become available WITH phase controls for all of them? (except for “random”). I removed the double semicolon before the word “control” for all of them (so ;;control would be ;control), and the wave options become available. But, when I select a different wave other than “sine”, it doesn’t use that wave, only uses sine waves. Is there a way for it to make use of all the waves available? I kind-of thought that I’d have to repeat the line,

(setf type 1) ;vibrato - vary speed
(setf wave 0) ;Sine

(setf type 1) ;vibrato - vary speed
(setf wave 0) ;Sine
(setf type 1) ;vibrato - vary speed
(setf wave 0) ;Triangle
(setf type 1) ;vibrato - vary speed
(setf wave 0) ;Sawtooth
(setf type 1) ;vibrato - vary speed
(setf wave 0) ;Inverse Sawtooth
(setf type 1) ;vibrato - vary speed
(setf wave 0) ;Square

Is this correct? If not, how should it be different? Thanks


I very much doubt that a warped record really does create triangular modulation, though I can imagine it being a bit more “triangular” than a perfect sine tone. Ideally what you need is to track the pitch deviation and then apply an inverse “map” of that deviation, but that is very complex to do. There is software available for doing this, but it’s very expensive (

The code that creates the modulation “shape” is the line:

(fmlfo (pwlv isp 1 fsp) *table*)

fmlfo is a low frequency oscillator that produces a time varying frequency.
(pwlv isp 1 fsp) sets the frequency to vary from the value of isp to fsp (Initial SPeed to Final SPeed)
and table sets the waveform type (sine. square, triangle or whatever).

All that’s needed is to add the optional “phase” parameter.
Here’s a version with the modification:
vibratophase.ny (3.2 KB)

Unfortunately I’ve tried out Capstan and it seriously does not work with my Jaws screen reader, so Capstan would be of no use to me. Not that I really want to exactly reverse the warping, but I was just thinking of a simple way to correct the warping. Here’s my question. With this new plugin, having not modified it whatsoever, the only way it will work is if I select “sine” for the wave. If I select another wave, there is just an OK button with no dialog text. I think there’s probably something wrong with it, isn’t there? I think I might be able to isolate the problem in this section of coding.

(setf table
(case wave
(0 sine-table) ; sine
(1 tri-table) ; triangle
(2 saw-table) ; sawtooth
(3 (list (abs-env (pwlv -1 0 1 1 -1))(hz-to-step 1) T)) ; inverse sawtooth
(4 (list (abs-env (pwlv -1 0.5 -1 0.5 1 1 1))(hz-to-step 1) T)))) ; square

So, where it says “T)))”, does that have to be replaced with “table phase”? This would be my guess. Like I said the phase control is only available with the Sine option, though I thought it was possible to apply the phase option to all of the waves. It works fine with the Tremolo effect, I wonder why it wouldn’t work with the vibrato effect. I should also add that this isn’t specifically for records, but also along the lines of having some fun with audio. Like if I use a Triangle wave, for instance it starts at the low end of the bend when the file starts, changing the phase would make it able to start at maybe the high end of the bend for instance. If I try that with this effect using Triangle, it doesn’t work. I think there must be something about the code, but since I don’t know a lot about Nyquist, this is just a guess.

That sounds very odd. I don’t have Jaws, but I can check what happens with NVDA.

I very much doubt that it is related to that part of the code.
The only parts of the code that relate to the interface (and thus to what a screen reader sees) are the header lines near the top of the file - specifically, the ;control lines.

No, that needs to be “T”.
Items 0 to 2 (sine, triangle and sawtooth) are using “wave tables” that are predefined in Nyquist.
Nyquist does not have predefined tables for inverse saw or square waves, so the code for items 3 and 4 creates the tables.
A wavetable is a list of the form:
(sound pitch-number periodic)
where “periodic” is true or false. In Nyquist we use “T” for true and “NIL” for false.

If “phase” is set to 180 or minus 180 degrees, then triangle vibrato starts at the high end of the pitch bend.

Gramophone warp & wow are effectively changes in speed which change the pitch, so theoretically correctable by changing the time-track in Audacity into something sinusoidal, a tedious 78 times per minute.

I forgot, screen readers usually show sliders with a range of 0 to 100, at least that’s what NVDA does with Nyquist plug-ins. So to start triangle vibrato at the high end of the pitch bend, the phase needs to be plus or minus 180, which is a slider position of 0 or 100. Other than that, the plug-in works perfectly with NVDA.

Michael Kazmierski says that he is using a screen reader, and unfortunately time tracks are not VI accessible.

It still doesn’t work. Only the sine wave is available. What happens is, all of the options my screen reader can read just fine (sine, square, sawtooth, inverse sawtooth, triangle, random, whatever). However, when I use one of the waves to create a vibrato, the tone alternates just like a sine wave for all of these. I know it’s a sine wave from experimenting with the TremVib.Ny plugin. Now I’m wondering why if you simply add the word “Phase” after the table, and the control for the phase, why it won’t work? Also there is a spot that says,

Setf wave 0; sine
I changed them to Setf wave 1 ;triangle, or setf wave 2 ;Sawtooth - and there is clearly no difference. There has to be something wrong with it. Unless it starts happening when I restart my computer, that might do it.

I’ve just downloaded the most recent version and tested it, just to make sure that it hadn’t been corrupted when uploading to the forum. It works fine.
The “Random” setting does not work, but that does not work in the original code that you posted (because it isn’t implemented). All the other settings work.

Here’s the most recent version again:

If it still does not work for you, please say which version of Audacity you are using. (look in "Help menu > About Audacity).

I have Audacity 2.0.6 on Windows 7. However, I tried this plugin on my girlfriend Deborah’s computer, and she uses Audacity 2.1.2 with Windows 10. Even then, only the sine wave is the only way that the vibrato can modulate the pitch. Is it this part of the code?

(setf table (maketable (abs-env (osc (hz-to-step 1) 1 sine-table phase))))

As I understand it, this code will only allow a sine wave to be used, correct? If so, how do you edit it and add the other waves? Even after restarting my laptop, it still is the exact same. It’s also the same with Deborah’s computer too. I think there is something wrong with the code, though I did delete all of the code relating to “random waveform”, maybe if I do that it will work, who knows.

I think you must be using the wrong version.
To avoid confusion, here’s a new version, the same as the last, but with the (non-functioning) “Random” option removed. I’ve renamed this as
“NEW Tremolo / Vibrato…”
newtremolovibrato.ny (3.2 KB)

THANKS STEVE!!! Guess what: IT WORKS!!! I couldn’t be happier!!! I think all you did was take the original Tremvib.ny and added the phase control I believe, this is what I wanted from the get-go. Now the bagpipe records will sound billions of times better! (Wish I knew how to put smilies in here, they are not screen-reader-friendly, but oh well…). I think you should add this plugin to the list of Nyquist plugins on the page, if they will allow you to, because I think this plugin is absolutely useful for anyone using Audacity. Thanks x 1000000!!! I think Deborah will like it too!

PS. I’ll erase the failed-attempt versions of the old plugins and replace it with this ultimate one.

Glad it works for you :slight_smile:
(that’s a smiley at the end, it’s typed as two characters, colon then closed parenthesis).

The main reason that it’s not on the plug-in page is because there is a problem that needs to be fixed, but I’ve not yet found a satisfactory solution. If the effect is used on long sections of audio there is a gradual deterioration in the sound quality. This problem will probably not be noticeable as long as you keep the length of the selection to no more than a few minutes.

Also, there are several vibrato effects posted on this forum, but what features should the definitive version have? One version allows you to enter a series of numbers, separated by spaces, so that you can vary the speed and depth multiple times through the duration. That’s a nice feature, but not intuitive and not easy to use for people that don’t read instructions (most people). i doubt that many people would need a phase control, yet for your case it is essential. Some users may need the effect to fade in and out, yet for others that is unwanted complication. Some users may need the overall length to remain exactly the same after processing, but we don’t yet have a version that does that. A version that has all of the features, all the bells and whistles that anyone could want, then it would become a very complicated effect, but if we leave out little used features (such as ‘starting phase’) then it will not be sufficient for some users.

What features do you think should go into an ‘official release’ version?