which says: “if the track is stereo, apply the function ‘stereo-delay’ to the track”, else throw an error."
The function “stereo-delay” takes stereo audio as it’s argument, and returns a stereo sound as the result, but the function “extract” requires a mono sound, so you can’t directly apply “extract” to the result of “stereo-delay”.
Solution:
Store the (stereo) result from “stereo-delay” in a temporary variable, then apply “extract” to that intermediate result using “multichan-expand”.
This sounds good. Delay bpm.ny (2.1 KB)
I have fixed the numbers in the bpm function.
Instead of making notes climb by 60, 30, 15 etc, I left this at 60 and added the multiplication in bpm values like 0.5, 1, 2, 4, 8, 16, so if someone wants to modify the values to make notes in other types of times I can easily do.
That works nicely, except for a couple of typos:
In “defun sig” the options are numbered 0, 1, 1, T.
In “;control options” you have a curly brace in the option “Add} high pass filter”
That fixes the issues that I mentioned, but do you really want the low pass filter to use the “Lower frequency for the filter” (default 300 Hz)?
When I first tried the low-pass option, I thought that it broke the delay part of the effect because I could no longer hear the echo. It didn’t break the effect, it just made the echo so quiet (because it was below 300 Hz) that I couldn’t hear it. Yes that was “user error” on my part, but I was initially caught out.
Unfortunately we are not yet able to grey out controls that are not used, so we need to consider GUI very carefully to make effects “intuitive”. You need not agree with me, but I’d be inclined to have just one “filter frequency” control that is used by all three filter types, and a “width” control that is used only by the band-pass filter.
I thought about this possibility, but it would take away the precision to the effect, because the width control in the bandpass2 function works in a way contrary to the number that is used to establish the q in the eq-band function.
I was inspired by the phone effect that there are in some electronic songs.
With the default frequency cut settings and the selected bandpass, it is possible to do this.
If you use a single cut control and a wide one does not allow this effect, since the spectrum passes with little resonance at 2000 Hz.
You don’t need to change the filter to the eq-band filter. You could still use the highpass and lowpass filters, but set them according to a defined centre frequency and band width. For example, a centre frequency of 1000 Hz and a bandwidth of 2 octaves is equivalent to a low pass corner frequency of 2000 Hz and a high pass corner frequency of 500 Hz, which is also equivalent to a centre frequency of 1000 Hz and a width of 1500 Hz.
Calculating the high and low corner frequencies given width in Hz is a bit tricky as it involves solving a quadratic equation. If I remember my math correctly, I think it can be done like this:
;control hz "Centre" float "Hz" 1000 10 10000
;control width "Width" float "Hz" 1500 0 10000
(defun get-ratio (a b c)
;;; We get ratio as the positive solution of a quadratic
(/ (+ (- b) (sqrt (- (* b b)(* 4 a c))))(* 2 a)))
(setf ratio (get-ratio hz (- width) (- hz)))
;(print ratio)
(setf hi (* hz ratio))
(setf low (/ hz ratio))
(print hi)
(print low)
I think no. In case it is published in the audacity wiki it would be little to put only me as the author of this plug-in, because you have contributed to the great majority of the code. I want to say that you are also the author of the delay with bpm and panning.
I’ve made a few minor changes to the UI and rewritten some of the code to make it more efficient (processes faster).
If you’re happy with these changes, I’ll upload this version to the Audacity wiki.
;nyquist plug-in
;version 4
;type process
;preview linear
;name "Delay Tempo with Pan..."
;action "Performing Delay with bpm and panning..."
;release 2.3.1
;author "Felipe Zanabria and Steve Daulton"
;copyright "Released under terms of the GNU General Public License version 2"
;; Released under terms of the GNU General Public License version 2:
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
;control decay "Decay" float "dB" -6 -24 0
;control bpm "Tempo" float "bpm" 120 1 500
;control noteval "Note values:" choice "Half note (0.5),Quarter note (1),Eighth note (2),Sixteenth note (4),Thirty-second note (8),Sixty-fourth note (16)" 2
;control echoes "Number of echoes" int "times" 5 1 100
;control spread "Pan spread" float "move" 0.0 -1 1
;control options "Optional filters:" choice "None,High pass filter,Low pass filter,Band pass filter" 0
;control hz "Filter frequency" float "Hz" 1000 10 10000
;control width "Filter width (bandpass only)" float "Hz" 1500 0 10000
(defun stereo-delay (sig)
;;; Mix multiple repeats of panned, filtered and delayed mono mix
;;; of the signal, with the original stereo signal.
;;; Return the mix.
(let ((out sig)
(mono (filter (mono-mix sig)))
(delay (note-to-seconds bpm noteval)))
(do ((i 1 (1+ i))
(gain decay (+ gain decay))
(where spread (- where))) ;Reverse pan position on each repeat.
((> i echoes) out)
(setf echo (loud gain (cue mono)))
(setf out (sim out
(at-abs (* i delay)
(cue (stereo-pan echo where))))))))
(defun stereo-pan (sig where)
;;; Pan a mono signal by 'where' ratio using the same
;;; pan law as Audacity track pan control.
;;; Return the stereo result.
(if (> where 0)
(vector (mult (- 1 where) sig)
sig)
(vector sig
(mult (- 1 (abs where)) sig))))
(defun mono-mix (stereo)
;;; Return mono mix of stereo input.
(mult 0.5 (sum (aref stereo 0)
(aref stereo 1))))
(defun note-to-seconds(bpm noteval)
;;; Convert note type (whole, half, quarter ...) at given tempo (bpm).
;;; Return delay time in seconds.
(let ((beat-length (/ 60.0 bpm)))
(case noteval
(0 (/ beat-length 0.5))
(1 beat-length)
(2 (/ beat-length 2.0))
(3 (/ beat-length 4.0))
(4 (/ beat-length 8.0))
(t (/ beat-length 16.0)))))
(defun filter (sig)
(case options
(0 sig)
(1 (highpass2 sig hz))
(2 (lowpass2 sig hz))
(t (bandpass sig hz width))))
(defun bandpass (sig cf width)
;;; We get ratio as the positive solution of a quadratic.
(let ((ratio (solve-quadratic hz (- width) (- hz))))
(setf hi (* hz ratio))
(setf low (/ hz ratio))
(highpass2 (lowpass2 sig hi) low)))
(defun solve-quadratic (a b c)
;;; Positive solution of a quadratic
(/ (+ (- b) (sqrt (- (* b b)(* 4 a c))))(* 2 a)))
(setf dur (get-duration 1))
(if (arrayp *track*)
(let ((temp-result (stereo-delay *track*)))
(multichan-expand #'extract-abs 0 dur temp-result))
"Error.\nStereo track required.")
Hi Steve, I think one more modification should be made to the plug-in. I think you should put a mix control for the delayed signal. If I want a low-volume delay, the first is heard but the second and the remaining delays are no longer heard. This occurs because the lower the dekay is set, the more difference there is between one delay and another. For example, if set to -16 dB, the second delay sounds at -32 dB, which is already inaudible. Solution to this: Having together with the dekay control a mix control that helps me control better. You could set the dekay to -6, so there is little difference between the delays, and adjust the mix in case it is sounding too loud.
Se diferencia en el sentido de que con un dekay demaciado bajo se escucha solo el primer retraso. Teniendo el control de mix puedo establecer un decaimiento de -6 dB o menos, y con esto no tengo tanta diferencia entre un eco y otro. Te explicaré un ejemplo que me ha ocurrodo. He configurado el plug-in con un decaimiento de -16 dB y una cierta configuración de panning. Al escuchar el resultado sonaba el sonido original, y el mrimer retraso en uno de los lados en la mezcla. Al querer escuchar el retraso siguiente, el cual sonaría en el otro lado, no he podido, ya que he querido establecer el decaimiento de forma que suene bien en la mezcla. Como dije en el post anterior, el segundo retraso sonaría a -32 dB, lo cual sería inaudible. Teniendo un control de mix, podría tenerlo ajustado a -12 dB, y un decaimiento de -4 o -6 dB. Si ajusto el decaimiento a -4 dB, tendría como resultado -12±4=-16 dB, y los próximos retrasos serían más audibles ya que sonarían a -20, -24 etc.
It differs in the sense that with too low a dekay only the first delay is heard. With the mix control I can set a decay of -6 dB or less, and with this I don’t have that much difference between one echo and another. I will explain an example that has happened to me. I have configured the plug-in with a -16 dB decay and some panning setting. Hearing the result sounded the original sound, and the first delay on one side of the mix. Wanting to hear the next delay, which would sound on the other side, I couldn’t, as I wanted to set the decay so that it sounds good in the mix. As I said in the previous post, the second delay would sound at -32 dB, which would be inaudible. Having a mix control, you could have it set to -12 dB, and a decay of -4 or -6 dB. If I set the decay to -4 dB, it would result in -12 + -4 = -16 dB, and the next delays would be more audible as they would sound at -20, -24 etc.
So how do you want to implement that? (or is that your question?)