在a.bestmetronome.com上,他们有一个节拍器,该节拍器会根据噪音产生滴答声。
但是,我无法弄清楚“滴答声”是如何产生的。尽管我能够通过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*))
这是我当前拥有的刻度,它位于生成它的函数中:
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);
}
}
但是,用于自行生成刻度的脚本使用的是基于Lisp的Nyquist语言。如何在JavaScript中编写与Lisp / Nyquist生成器相同的东西,但是使用AudioContext和Web Audio函数呢?
我在网上尝试了许多翻译工具,但似乎没有一个能满足我的需求。另外,如何确保以JS代码中的time
变量完全开头的空缓冲区(上面的代码生成的噪声样本填充了该缓冲区)?
可以通过createBiquadFilter()
完成“ highpass8”,并且可以从随机数开始创建噪声。我以前使用过Web Audio API,并使用它来制作噪声和音调发生器。但是,在执行此任务时,我陷入了困境。
或者,我尝试查找a.bestmetronome.com的来源,但显然他们使用Flash来生成声音,而我找不到真正产生滴答声的ActiveX对象。我如何复制它们产生刻度的方式? (也使用Web Audio API)
答案 0 :(得分:1)
问题中编写的奈奎斯特代码将无法运行,因为尚未定义s-rest-abs函数。此版本可能以Audacity的“奈奎斯特提示”效果运行(请参见:https://manual.audacityteam.org/man/nyquist_prompt.html)
;version 4
;type generate
;; 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 (abs-env (s-rest 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*))
(get-metronome-tick 440 0.8)
最后一行调用函数“ get-metronome-tick”。
(作为Audacity Rhythm Track生成器的作者,我很乐意提供有关此代码在做什么的更多详细信息,尽管我认为在问题的背景下这不是必需的。)>
从在Audacity的Nyquist Prompt中运行此代码可以看到,它生成2200个采样值的序列(在44100 Hz采样率下为50ms)。这样编写的目的是使整个插件可以分布在一个小的文本文件中。
我不是JS专家,但是我希望在JS / HTML5中,简单地为示例数据创建一个小的音频文件会更容易。由于不需要非常高的频率,因此它可以是非常小的低采样率文件(例如,以11025 Hz的采样率进行550个采样)或压缩格式(例如OGG或MP3)。可以使用上述代码生成对勾,然后将其导出,从而以Audacity格式创建文件。
然后可以将声音加载如下:
<audio src="tickSound.ogg" type="audio/ogg"></audio>
另请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API
和