2012-11-08 6 views
6

Ich bin besonders interessiert an den onaudioprocess der ScriptProcessorNode (bis vor kurzem JavaScriptNode genannt). Es ist ein Ereignis-Listener, der periodisch für die Audio-Verarbeitung aufgerufen wird. Läuft es in einem separaten Thread?Werden Web-Audio-API-Ereignisse in einem separaten Thread ausgeführt?

Ich möchte die Daten in einen Ringspeicher und verarbeiten Sie es außerhalb dieses Callbacks, so dass ich nicht die CPU hog. Ich kann Web-Arbeiter für die asynchrone Verarbeitung verwenden, aber AFAIK Ich würde eine andere Implementierung des Ringpuffers im Fall von verschiedenen Threads benötigen.

Gibt es eine Möglichkeit, dies zu testen?

+0

streamen Sie auch das Audio über Web-Sockets? Wie bist du vorangekommen ? ... am Seitenknoten wäre es nett, Web Audio aus einem Web Worker Thread heraus zu starten! –

Antwort

5

Alle JavaScript ist single-threaded, synchron ausgeführt. Alle asynchronen Vorgänge werden über Ereignisse ausgeführt, die ihre Handler zu der Aufgabenwarteschlange hinzufügen, die ausgeführt werden soll, wenn die aktuelle Aufgabe beendet ist.

Um separate Threads zu verwenden, benötigen Sie eine Umgebung wie WebWorker - jeder Thread hat seinen eigenen Ausführungskontext (globalen Bereich) und Aufgabenwarteschlange; Die Kommunikation zwischen ihnen erfolgt über Ereignisse.

Da die onaudioprocess Handler im gleichen Umfang wie der DOM zu leben scheinen, ist es sehr unwahrscheinlich, dass es in einem eigenen Thread ausgeführt wird. Wenn Sie wirklich eine rechenintensive Aufgabe haben, die Ihre Seite nicht mehr reagiert macht, sollten Sie einen WebWorker verwenden, in dem Sie die Audio-Events füttern:

myScriptProcessorNode.onaudioprocess = myWebWorker.postMessage; 
+0

Ich habe zuvor Web-Arbeiter benutzt. Wenn der Onaudioprozess im Hauptthread ausgeführt wird, dann würde ich wohl keinen Ringpuffer benötigen, nur einen einfachen Synchronspeicher, oder? Ich formuliere meine Frage ein wenig. – Davorin

+0

Ja, mit JavaScript müssen Sie niemals sperren - es gibt immer nur einen ausgeführten Task. – Bergi

0

Mit Bergi-Lösung, Sie gehen mit dem structured clone algorithm in Probleme laufen nicht in der Lage sein, schreibgeschützte Parameter im audioProcessingEvent zu kopieren. Was Sie tun müssen, ist, die Teile brechen Sie von der Veranstaltung müssen die klonbar sind, und geben Sie sie in einer anderen Datenstruktur zu Ihrem Arbeitnehmer über etwa so:

_onAudioProcess(audioProcessingEvent) { 
    const {inputBuffer, outputBuffer} = audioProcessingEvent; 
    // The output buffer contains the samples that will be modified and 
    // eventually played, so we need to keep a reference to it. 
    this._outputBuffer = outputBuffer; 
    const numChannels = inputBuffer.numberOfChannels; 

    const inputChannels = 
    Array.from({length: numChannels}, (i) => { 
     return inputBuffer.getChannelData(i); 
    }); 

    this._worker.postMessage({ 
    command: 'DO_STUFF', 
    inputChannels: inputChannels, 
    }); 
} 

Sie auch Zugang zu benötigen, der Verweis auf Ihren outputBuffer in setMessageHandler, um die verarbeiteten Daten wieder zu kopieren, um schließlich vom Benutzer abgespielt zu werden.