2017-03-11 36 views
1

我正在制作一个合成器,我试图完成的是一个振荡器将被创建一次,然后按键然后在关键帧上停止。在keydown()和Web Audio API上触发的事件太多

以下是我的代码。

$(document).on("keydown", e => { 
 
    console.log(e); 
 
    let key = $("div[data-key-id = " + e.keyCode + "]") 
 
    key.addClass('red') 
 
    if (fired) return null; 
 
     fired = true; 
 
     let oscs = playTone($(key[0]).attr("data-frequency")) 
 
     if (!oscs) return null; 
 
     $(document).on('keyup', e => { 
 
      oscs.forEach(osc => { 
 
      osc.stop(); 
 
      }); 
 
     $('.key').removeClass('red') 
 
     fired = false; 
 
     }) 
 
    })

这里被称为普雷通公司的功能。

function playTone(freq) { 
 
    if (!freq) return null; 
 
    let osc = audioCtx.createOscillator(); 
 
    let osc2 = audioCtx.createOscillator(); 
 
    connectNodes(osc, osc2) 
 
    osc.type = type; 
 
    osc2.type = type2; 
 
    osc.detune.value = detune * 5; 
 
    osc2.detune.value = -detune * 5; 
 
    let number = parseFloat(freq.match(/[\d\.]+/)) 
 
    osc.frequency.value = number * octave; 
 
    osc2.frequency.value = number * octave; 
 
    console.log(osc) 
 
    osc.start(); 
 
    console.log(osc2) 
 
    osc2.start(); 
 
    return [osc,osc2] 
 
}

正在发生的事情是,在的keydown,正在触发事件多次,这个叫普雷通公司多次。正在创建的振荡器数量超载了我的CPU并导致音频失真。我需要一种方法来确保事件只被触发一次。我试图使用已打开的变量来实现这一点,但我没有达到我需要的结果。

+0

你在你的'keydown'事件'$(文件)。在('keyup'',这将在每次触发keydown事件时创建一个新的单独的keyup事件处理程序。 –

+0

这是一个很好的观点,谢谢,但我仍然有同样的问题。 – John

回答

0

尽量确保你只一次事件绑定:

$(document).unbind('keydown.namespace').bind('keydown.namespace', e => { 
 
    console.log(e); 
 
    let key = $("div[data-key-id = " + e.keyCode + "]") 
 
    key.addClass('red') 
 
    if (fired) return null; 
 
     fired = true; 
 
     let oscs = playTone($(key[0]).attr("data-frequency")) 
 
     if (!oscs) return null; 
 
     $(document).unbind('keyup.namespace').bind('keyup.namespace', e => { 
 
      oscs.forEach(osc => { 
 
      osc.stop(); 
 
      }); 
 
     $('.key').removeClass('red') 
 
     fired = false; 
 
     }) 
 
    })

相关问题