On a.bestmetronome.com, they have a metronome that generates ticks based on noise.
However, I couldn't figure out how the "ticks" are generated. Although I was able to work out the "tick" generator out of Audacity:
;; Metronome tick by Steve Daulton.
(defun metronome-tick (hz peak)
(let* ((ln 300)
(sig-array (make-array ln))
(x 1))
;; generate some 'predictable' white noise
(dotimes (i ln)
(setf x (rem (* 479 x) 997))
(setf (aref sig-array i) (- (/ x 500.0) 1)))
(setf sig (sim (s-rest-abs 0.2)
(snd-from-array 0 44100 sig-array)))
(setf sig
(mult (abs-env (pwev 10 (/ ln 44100.0) 2 1 0))
(highpass8 (lowpass2 sig (* 2 hz) 6)
hz)))
(let ((gain (/ (peak sig 300))))
; The '1.11' factor makes up for gain reduction in 'resample'
(mult (abs-env (pwlv 1.11 0.02 1.11 0.05 0 ))
(jcrev (mult peak gain sig) 0.01 0.1)))))
;; Single tick generator:
(defun get-metronome-tick (hz gain)
(resample
(sound-srate-abs 44100 (metronome-tick hz gain))
*sound-srate*))
And here is the tick I currently have, inside the function that generates it:
function scheduleNote(beatNumber, time)
{
// push the note on the queue, even if we're not playing.
notesInQueue.push({
note: beatNumber,
time: time
});
if (beatNumber % 4 === 0) // beat 0 == high pitche
{
var fader = actx.createGain();
fader.gain.value = 2;
fader.connect(distor);
var oscil0 = actx.createOscillator();
oscil0.frequency.value = noteFreq[0];
oscil0.connect(fader);
var oscil1 = actx.createOscillator();
oscil1.frequency.value = noteFreq[0] * 2;
oscil1.connect(fader);
oscil0.start(time);
oscil1.start(time);
oscil0.frequency.exponentialRampToValueAtTime(noteFreq[1], time + noteLength);
oscil1.frequency.exponentialRampToValueAtTime(noteFreq[1] * 2, time + noteLength);
fader.gain.linearRampToValueAtTime(0, time + noteLength);
oscil0.stop(time + noteLength);
oscil1.stop(time + noteLength);
}
}
However, the script to generate the ticks themselves is in the Nyquist language, which is based on Lisp. How can I write something in JavaScript that does what the Lisp/Nyquist generator does, but using AudioContext and Web Audio functions?
I tried numerous translation tools online, none seemed to get where I needed. Also, how can I make sure that the empty buffer that I start with (Which is filled with the noise sample generated by the code above) starts exactly according to the time
variable in the JS?
The "highpass8" could be done with createBiquadFilter()
and the noise could be created starting with random numbers. I've worked with the Web Audio API before, and made a noise and tone generator out of it. However, on this task I'm stuck.
Alternatively, I tried looking in a.bestmetronome.com's source but apparently they use Flash to generate their sounds, and I couldn't find the ActiveX Object that actually generated the ticks. How could I replicate the way they generated the ticks? (Also using the Web Audio API)