2017-04-25 90 views
2

我正在使用WebAudioAPIWebMIDIAPI創建複音合成器。我的每個振盪器都有一個增益節點,然後連接到主增益節點。Web Audio API - 停止振盪器連接以釋放信封的正確方法

我想知道如何在發佈後正確停止(如果有必要刪除)振盪器。我不確定是否有必要從陣列中調用oscillator.stop()delete振盪器。

如果我這樣做,釋放信封不起作用,筆記立即停止,如果我不這樣做,釋放信封確實有效,但筆記有時可以繼續播放。

編輯:它似乎當.stop()功能沒有實現和兩個音符同時播放一個振盪器將始終保持。不知道這是我的代碼還是??

我對noteOff功能代碼如下:

/** 
* Note is being released 
*/ 
this.noteOff = function (frequency, velocity, note){ 

    var now = this.context.currentTime; 

    // Get the release values 
    var osc1ReleaseVal = now + this.osc1Release; 
    var osc2ReleaseVal = now + this.osc2Release; 

    // Cancel scheduled values 
    this.oscGain.gain.cancelScheduledValues(now); 
    this.osc2Gain.gain.cancelScheduledValues(now); 

    // Set the value 
    this.oscGain.gain.setValueAtTime(this.oscGain.gain.value, now); 
    this.osc2Gain.gain.setValueAtTime(this.osc2Gain.gain.value, now); 

    // Release the note 
    this.oscGain.gain.linearRampToValueAtTime(0.0, osc1ReleaseVal); 
    this.osc2Gain.gain.linearRampToValueAtTime(0.0, osc2ReleaseVal); 

    // ----- IF I COMMENT THE `forEach` Loop the release works correctly but with side-effects! 
    // Stop the oscillators 
    this.oscillators[frequency].forEach(function (oscillator) { 
     oscillator.stop(now); 
     oscillator.disconnect(); 
     delete oscillator; 
    }); 
}; 

任何幫助將不勝感激,謝謝!

+0

事實上,我不知道你應該刪除你的osc陣列。在釋放筆記之後使用可以減少增益的功能怎麼樣?因此,您可以確保音量在某個時間點關閉,而無需停止並刪除osc?只是一個想法... 我需要花一些時間在它上啊... – DevMoutarde

+0

@DevMoutarde一個好主意,或許,我試着把'oscillator.stop()'放在一個'setTimeout'函數中,設置時間到'osc1ReleaseVal'和'osc2ReleaseVal',但沒有工作..認爲我需要想想其他的東西來增加到 –

+0

哦,太糟糕了,它不工作,因爲它聽起來像一個好方法。也許(我想你已經做過了),你應該看看互聯網上的一些html/js合成器,看看他們如何設法方便地播放/停止。我曾經自己玩增益節點,而不是停止osc – DevMoutarde

回答

1

請勿使用oscillator.stop(now)。使用oscillator.stop(osc1ReleaseVal)安排振盪器在增益變爲0的同時停止。

您不必斷開連接並刪除振盪器。一旦停止,振盪器可以自行將其自身與增益節點斷開連接。如果你放棄了對振盪器的引用,它可以被垃圾收集。

+0

謝謝你的回答,這在某種程度上是有效的。我想這可能是我的代碼,但雖然**這樣做可以阻止持久的音符**,但現在當兩個音符同時按下時,它不會執行'linearRampToValueAtTime',並且會發出咔嗒聲。任何想法?如果不是,我可能會接受你的答案,因爲它解決了我的問題。 –

+0

上面的代碼片段說明了這一點嗎?很難知道發生了什麼,卻沒有看到顯示問題的代碼。 –

+0

是的,我的意思是這是唯一的代碼被執行來阻止振盪器,它可能與我如何創建它們有關,但我認爲這超出了問題的範圍。我可以編輯它以包含振盪器的創建,你會關心嗎? –