So far we’ve got how to generate tones and how to amplify them.
What would be useful would be if we could “shape” them so that they are not just a constant volume.
To do this we need to “multiply” them by something that varies - a number does not vary, it is a “constant”.
Nyquist provides a feature called “control signals”.
A Control signal is much like a sound (a waveform) but to improve efficiency they use a low sample rate, typically 1/20th of the track sample rate.
When a control signal is multiplied by a sound, the higher sample rate of the two is used for the output.
To create control signals we can use “piece-wise approximations” http://www.cs.cmu.edu/~rbd/doc/nyquist/part8.html#index379
The version that we will use is pwlv http://www.cs.cmu.edu/~rbd/doc/nyquist/part8.html#index384
Let’s say that we want to create an envelope that rises from 0.2 up to 0.8 at half way and back down to 0 again at the end.
Much like the Audacity Envelope tool we create a number of “control points” which are pairs of “time and level” values.
The correct order of values for pwlv is:
time1, level1, time2, level2, time3, level3…
The first time value is assumed to be zero so that value is not entered.
So our function for the “envelope” is:
(pwlv 0.2 0.5 0.8 1 0)
If you run that command on its own it will produce a very short waveform because of the low sample rate being “squashed” when it gets back to the Audacity track, so let’s try multiplying it by a sound:
(mult (osc 72)
(pwlv 0.2 0.5 0.8 1 0))
Or if we want an exact time duration we can use something like:
;; note that we use absolute time values for both the
;; sound and the control signal
(abs-env
(mult (pwlv 0.2 1.5 0.8 3 0)
(osc (hz-to-step 440) 3)))
So finally we get round to something useful - a little “beep” for our plug-in.
(setq dur 0.1)
(setq hz 1000)
(abs-env
(mult (pwlv 0 (* dur 0.1) 0.8 (* dur 0.9) 0.8 dur 0)
(osc (hz-to-step hz) dur)))
I have used a “variable” called “dur” to hold the required duration - in this case 0.1 seconds,
and the variable “hz” to hold the frequency - in this case 1000 Hz.
To make the code easier to use in our bigger plug-in, I’ll wrap the whole thing in a “function”. http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/xlisp/xlisp-ref/xlisp-ref-124.htm
We will create our own custom function called “beep” and it will take 2 “arguments” (parameter values) which will be the frequency and the duration.
;;; make a beep
(defun beep (hz dur)
(abs-env
(mult (pwlv 0 (* dur 0.1) 0.8 (* dur 0.9) 0.8 dur 0)
(osc (hz-to-step hz) dur))))
On its own this function does nothing. To make it do something we have to call the function (use it):
;;; make a beep
(defun beep (hz dur)
(abs-env
(mult (pwlv 0 (* dur 0.1) 0.8 (* dur 0.9) 0.8 dur 0)
(osc (hz-to-step hz) dur))))
; use the function 'beep' with a frequency of 440 Hz and a duration of 0.5 seconds
(beep 440 0.5)
to be continued…