2015-08-27 3 views
6

Das Verhalten ich bin geschieht in Chrome 44, zu beschreiben, aber tut nicht in Firefox passieren 40.Web Audio-Oszillatoren unerwartet von einer Frequenz gleiten zu einem anderen in Chrome

Wenn Sie einen Oszillator erstellen, setzen Sie es zu einer Frequenz von 220 Hz, und ändern Sie dann die Frequenz auf 440 Hz eine Sekunde später, können Sie einen deutlichen Portamento-Effekt hören: statt sofort von 220 auf 440 zu ändern, gleitet der Oszillator von der ursprünglichen Frequenz auf die neue Frequenz.

Der folgende Code veranschaulicht dieses Phänomen:

var ac = new AudioContext(); 
 

 
var osc = ac.createOscillator(); 
 
osc.connect(ac.destination); 
 

 
osc.type = 'sawtooth'; 
 

 
osc.frequency.value = 220; 
 
osc.start(0); 
 

 
window.setTimeout(function() { 
 
    osc.frequency.value = 440; 
 
}, 1000); 
 

 
window.setTimeout(function() { 
 
    osc.stop(0); 
 
}, 2000);

ich die Dokumentation für das OscillatorNode Objekt untersucht haben, und es gibt keine Erwähnung dieses Verhalten.

Ich habe auch Google durchforstet, und (überraschenderweise) kann ich keine anderen Erwähnungen dieses Phänomens finden.

Was ist los? Das scheint kein richtiges Verhalten zu sein. Wenn ich die Frequenz Glide wollte, würde ich die linearRampToValueAtTime() Methode verwenden. Wenn Sie die Frequenz direkt auf einen bestimmten Wert einstellen, sollten Sie dies einfach tun.

Ist das nur ein Fehler? Ich weiß, dass diese API noch im Fluss ist, aber das scheint ziemlich eklatant zu sein - das würde nicht die oberflächlichsten Tests bestehen. Aber ich kann mir auch nicht vorstellen, dass Google es so implementieren würde absichtlich.

Am wichtigsten: Gibt es einen Workaround?

+0

Es funktioniert "richtig" in Firefox, das ist ein Webkit-Problem, also funktioniert das auch mit Opera und Safari. –

Antwort

4

Ziemlich sicher, dass dies ein Fehler ist.

Ich kann nichts in der Spezifikation finden, die auf einer AudioParam von value direkte Zuordnung sagt sollte jede Art von Interpolation tun.

Es ist möglich, dass es unbemerkt bleibt, weil Menschen den Wert wahrscheinlich mit Automatisierungsmethoden ändern. Was bringt mich zu Ihrer Frage der Problemumgehung ...

Wenn Sie eigentlich eine explizite Verzögerung wollten, können Sie dies tun (beachten Sie, es gibt keine setTimeout).

// change the value to 440Hz 1 second from now 
osc.frequency.setValueAtTime(440, ac.currentTime + 1); 

Wenn Sie die Frequenz in der Lage sein wollen, sofort zu ändern (zum Beispiel als Reaktion auf eine Benutzeraktion), können Sie dies nur tun:

osc.frequency.setValueAtTime(440, 0); 

Hoffnung, das hilft.

Übrigens sollten Sie darüber nachdenken, ein Problem zu stellen (https://code.google.com/p/chromium/issues/list).

+1

Danke! Diese Problemumgehung funktioniert für mich. Wahrscheinlich hätte ich selbst daran denken sollen, aber ... weißt du? Ich werde versuchen, mich daran zu erinnern, morgen einen Fehlerbericht einzureichen. Prost! – greenie2600

+0

Kein Problem. Für das, was es wert ist, ist das Verhalten auch in Chrome Canary vorhanden (Chrome 47) - was ein wenig überraschend ist. Normalerweise sehe ich Web Audio Bugs nicht so lange. –

+0

Übrigens, warum ändern Menschen den Wert normalerweise mithilfe von Automatisierungsmethoden? Soll das Timing knapp gehalten werden? (Ich stelle mir vor, dass das Feuern zu dem Zeitpunkt, zu dem es benötigt wird, manuell geändert wird, ist nicht so genau/zuverlässig wie das Planen im Voraus mit setValueAtTime() und dergleichen. Aber in Fällen, in denen Sie auf Benutzereingaben reagieren - z MIDI-Event oder eine Parameteränderung über ein In-Browser-Steuerelement - Sie haben wirklich keine Wahl. – greenie2600

4

Dies ist der eingebaute "Entzippungseffekt", den die Arbeitsgruppe mehrmals hin und her gegangen ist. Ab Juni beschloss die WG schließlich, die Dekomprimierung zu entfernen (Status: https://github.com/WebAudio/web-audio-api/issues/76). Also ja, das ist ein Chrome "Bug" - https://code.google.com/p/chromium/issues/detail?id=496282). Bis es behoben ist, verwenden Sie setValueAtTime(), wie Kevin vorgeschlagen hat.

+1

Danke für die Klarstellung, Chris. Ich stieß auf eine Erwähnung des Entzipperns, während ich darauf schaute, aber ich konnte es nur in Bezug auf GainNode finden - also wollte ich nicht den Sprung machen, der vielleicht auch für Oszillatoren verwendet wurde. –

+0

Ja, es passiert derzeit für .value auf allen AudioParams. – cwilso

Verwandte Themen