如何在JavaScript中生成这种滴答声?

如何在JavaScript中生成这种滴答声?,javascript,html5-audio,audiocontext,nyquist,Javascript,Html5 Audio,Audiocontext,Nyquist,在a.bestmetronome.com上,他们有一个节拍器,可以根据噪音产生节拍 然而,我无法理解“滴答声”是如何产生的。尽管我能够大胆地设计出“勾号”生成器: ;; Metronome tick by Steve Daulton. (defun metronome-tick (hz peak) (let* ((ln 300) (sig-array (make-array ln)) (x 1)) ;; generate some 'predict

在a.bestmetronome.com上,他们有一个节拍器,可以根据噪音产生节拍

然而,我无法理解“滴答声”是如何产生的。尽管我能够大胆地设计出“勾号”生成器:

;; 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音频函数

我在网上尝试了很多翻译工具,但似乎没有一个能达到我需要的目的。另外,如何确保我开始使用的空缓冲区(填充了上面代码生成的噪声样本)完全按照JS中的
time
变量启动

“highpass8”可以使用
createBiquadFilter()
完成,并且可以从随机数开始创建噪声。我以前使用过Web音频API,并用它制作了一个噪音和音调生成器。然而,在这个任务上,我被卡住了



或者,我尝试查找a.bestmetronome.com的源代码,但显然他们使用Flash生成声音,我找不到实际生成滴答声的ActiveX对象。我怎样才能复制它们产生滴答声的方式?(也使用Web音频API)

问题中编写的Nyquist代码将不会运行,因为s-rest-abs函数尚未定义。此版本可以在Audacity的“Nyquist提示符”效果下运行(请参阅:)

;版本4
;类型生成
;; 史蒂夫·道尔顿的节拍器滴答声。
(除节拍器滴答声(hz峰值)
(出租*((300磅)
(sig数组(生成数组ln))
(x 1))
产生一些“可预测的”白噪声
(时间(i ln)
(setf x(rem(*479 x)997))
(setf(aref sig阵列i)((/x 500.0)1)))
(setf信号(sim(abs环境(s-rest 0.2))
(snd来自阵列0 44100 sig阵列)))
(setf信号
(多个abs环境(pwev 10(/ln 44100.0)2110))
(高通8(低通2信号(*2 hz)6)
(赫兹)
(let((增益(/(峰值信号300)))
;系数“1.11”弥补了“重采样”中的增益减少
(多个abs环境(pwlv 1.11 0.02 1.11 0.05 0))
(jcrev(多峰值增益sig)0.01 0.1‘‘‘‘‘‘‘)
;; 单刻度发生器:
(取消获取节拍器节拍(hz增益)
(重新取样)
(声音srate abs 44100(节拍器节拍hz增益))
*声音(srate*))
(让节拍器滴答4400.8)
最后一行调用函数“get metronome tick”

(作为Audacity节奏轨迹生成器的作者,我很乐意提供关于这段代码到底在做什么的更多细节,尽管我认为在这个问题的上下文中没有必要这样做。)

从Audacity的Nyquist提示符中运行此代码可以看出,它生成了2200个采样值的序列(采样率为44100 Hz时为50毫秒)。它是这样编写的,这样整个插件就可以分布在一个小的文本文件中

我不是JS专家,但我希望在JS/HTML5中,为示例数据创建一个小的音频文件会更容易。由于不需要非常高的频率,这可能是一个非常小的低采样率文件(例如,采样率为11025 Hz的550个样本)或采用压缩格式,如OGG或MP3。通过使用上述代码生成勾号,然后导出,可以在Audacity中创建该文件

然后,声音可以加载以下内容:

<audio src="tickSound.ogg" type="audio/ogg"></audio>


考虑问问作者:)谢谢!我注意到,我能够得到一个突出的剔使用带通滤波白噪声和重剪辑。