2017-03-11 32 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; 
 
     }) 
 
    })

相關問題