2017-04-25 2 views
2

Ich erstelle einen polyphonen Synthesizer mit WebAudioAPI und WebMIDIAPI. Ich habe einen Verstärkungsknoten für jeden meiner zwei Oszillatoren, der dann mit einem Hauptverstärkungsknoten verbunden ist.Web Audio API - Korrekte Art, den Oszillator zu stoppen, um die Hüllkurve freizugeben

Ich fragte mich, wie man den Oszillator nach der Veröffentlichung korrekt stoppt (und wenn nötig löscht?). Ich bin mir nicht sicher, ob es notwendig ist, den Oszillator von den Arrays oscillator.stop() und delete aufzurufen.

Wenn ich das tue, funktioniert die Envelope Envelope nicht und die Note stoppt sofort. Wenn nicht, funktioniert die Envelope Envelope, aber die Note kann manchmal ewig weiterspielen.

EDIT: Es scheint, dass, wenn die .stop() Funktionalität nicht implementiert ist und zwei Noten gleichzeitig gespielt werden, einer der Oszillatoren immer an bleibt. Nicht sicher, ob es mein Code ist oder ??

Mein Code für noteOff Funktion ist unten:

/** 
* 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; 
    }); 
}; 

Jede Hilfe wäre sehr dankbar, danke!

+0

In der Tat bin ich nicht sicher, dass Sie Ihren OSC aus dem Array löschen sollten. Wie wäre es mit einer Funktion, die den Gewinn nach dem Freigeben der Note absenkt? So können Sie sicherstellen, dass die Lautstärke an einem bestimmten Punkt ausgeschaltet ist, ohne dass Sie den OSC stoppen und löschen müssen? Nur eine Idee ... Ich müsste etwas Zeit darauf verbringen ahah ... – DevMoutarde

+0

@DevMoutarde Eine gute Idee vielleicht, ich habe versucht, schnell oscillator.stop() 'in eine' setTimeout' -Funktion mit der Zeit zu setzen zu den 'osc1ReleaseVal' und' osc2ReleaseVal' aber hat nicht funktioniert .. denke, ich muss mir etwas anderes zu dieser –

+0

hinzufügen Oh, schade, es hat nicht funktioniert, weil es wie ein guter Weg zu gehen klingt. Vielleicht (ich denke, du hast es bereits getan) solltest du dir ein paar HTML/Js-Synths im Internet ansehen, um zu sehen, wie sie es schaffen, ein handliches Spiel/Stop zu machen. Ich habe früher selbst mit Verstärkerknoten gespielt, anstatt den Oszillator zu stoppen – DevMoutarde

Antwort

1

Verwenden Sie nicht oscillator.stop(now). Verwenden Sie oscillator.stop(osc1ReleaseVal), um den Oszillator so einzustellen, dass er zur gleichen Zeit stoppt, wenn die Verstärkung auf 0 geht.

Sie müssen die Oszillatoren nicht trennen und löschen. Nach dem Stoppen kann sich der Oszillator selbst von dem Verstärkungsknoten trennen. Wenn Sie den Verweis auf den Oszillator löschen, kann es sich um Garbage Collection handeln.

+0

Danke für die Antwort, das funktioniert _in gewissem Umfang_. Ich denke, es ist wahrscheinlich mein Code, aber obwohl ** das den "Sustained Forever Note Bug" stoppt **, scheint es, dass jetzt, wenn zwei Noten gleichzeitig gedrückt werden, es 'linearRampToValueAtTime' nicht tut und mit einem Klick-Sound abrupt endet . Irgendwelche Ideen dafür? Wenn nicht, werde ich wahrscheinlich Ihre Antwort trotzdem akzeptieren, weil sie mein Problem beantwortet. –

+0

Kann der obige Codeausschnitt dies verdeutlichen? Irgendwie ist es schwer zu wissen, was passiert, ohne den Code zu sehen, der das Problem zeigt. –

+0

Ja, ich meine, das ist der einzige Code, der ausgeführt wird, um die Oszillatoren zu stoppen, er könnte damit verbunden sein, wie ich sie erstelle, aber ich dachte, das wäre außerhalb der Reichweite der Frage. Ich kann es bearbeiten, um die Erzeugung von Oszillatoren einzuschließen, würde es dich interessieren zu sehen? –

Verwandte Themen