Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwasmwebaudiosink.cpp File Reference

(3d4fba00ae895807eabe9d8b0f99f4166e4235a6)

#include "qwasmwebaudiosink_p.h"
#include <emscripten.h>
#include <emscripten/val.h>
#include <QDebug>
#include <QIODevice>
#include <QtMath>
Include dependency graph for qwasmwebaudiosink.cpp:

Go to the source code of this file.

Classes

class  QWasmAudioSinkDevice

Functions

EMSCRIPTEN_KEEPALIVE void qt_sinkWorkletReady (int id)
EMSCRIPTEN_KEEPALIVE void qt_sinkDeliverData (int id)
 EM_JS (void, qt_sink_clearWorklet,(int callbackId), { if(Module._qtSinkWorkletParams) Module._qtSinkWorkletParams[callbackId]=undefined;})
 EM_JS (void, qt_st_sink_loadWorkletModule,(EM_VAL ctxHandle, int callbackId, int channels), { var ctx=Emval.toValue(ctxHandle);var code=[ 'class QtSink extends AudioWorkletProcessor {', ' constructor(opts) {', ' super(opts);', ' this._numChannels=opts.processorOptions.channels|0;', ' this._queue=[];', ' this._pos=0;', ' this.port.onmessage=(e)=> { this._queue.push(e.data);};', ' }', ' process(inputs, outputs) {', ' var out=outputs[0];', ' if(!out||!out.length) return true;', ' var samplesPerChannel=out[0].length;', ' for(var i=0;i< samplesPerChannel;i++) {', ' while(this._queue.length > 0 &&this._pos >=this._queue[0].samplesPerChannel) {', ' this._queue.shift();', ' this._pos=0;', ' }', ' if(this._queue.length===0) break;', ' var frame=this._queue[0];', ' for(var channel=0;channel< out.length &&channel< frame.numChannels;channel++)', ' out[channel][i]=frame.data[channel *frame.samplesPerChannel+this._pos];', ' this._pos++;', ' }', ' this.port.postMessage(null);', ' return true;', ' }', '}', 'registerProcessor("qt-audio-sink", QtSink);'].join('\n');var blob=new Blob([code], { type:'application/javascript' });var url=URL.createObjectURL(blob);ctx.audioWorklet.addModule(url).then(function() { URL.revokeObjectURL(url);Module._qt_sinkWorkletReady(callbackId);});})
 EM_JS (EM_VAL, qt_st_sink_createWorkletNode,(EM_VAL ctxHandle, int callbackId, int channels), { var node=new AudioWorkletNode(Emval.toValue(ctxHandle), 'qt-audio-sink', { numberOfInputs:0, numberOfOutputs:1, outputChannelCounts:[channels], processorOptions:{ channels:channels } });node.port.onmessage=function() { Module._qt_sinkDeliverData(callbackId);};return Emval.toHandle(node);})
 EM_JS (void, qt_st_sink_postFrame,(EM_VAL nodeHandle, int channels, int samplesPerChannel, const float *dataPtr), { var copy=HEAPF32.slice(dataPtr > > 2,(dataPtr > > 2)+channels *samplesPerChannel);Emval.toValue(nodeHandle).port.postMessage({ numChannels:channels, samplesPerChannel:samplesPerChannel, data:copy }, [copy.buffer]);})

Variables

QT_BEGIN_NAMESPACE constexpr unsigned int DEFAULT_BUFFER_DURATION = 250'000
constexpr int RING_BUFFER_DURATION = 250'000
static QHash< int, QWasmAudioSink * > s_sinkRegistry

Function Documentation

◆ EM_JS() [1/4]

EM_JS ( EM_VAL ,
qt_st_sink_createWorkletNode ,
(EM_VAL ctxHandle, int callbackId, int channels) ,
{ var node=new AudioWorkletNode(Emval.toValue(ctxHandle), 'qt-audio-sink', { numberOfInputs:0, numberOfOutputs:1, outputChannelCounts:[channels], processorOptions:{ channels:channels } });node.port.onmessage=function() { Module._qt_sinkDeliverData(callbackId);};return Emval.toHandle(node);}  )

◆ EM_JS() [2/4]

EM_JS ( void ,
qt_sink_clearWorklet ,
(int callbackId) ,
{ if(Module._qtSinkWorkletParams) Module._qtSinkWorkletParams[callbackId]=undefined;}  )

References EM_JS().

Referenced by EM_JS().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EM_JS() [3/4]

EM_JS ( void ,
qt_st_sink_loadWorkletModule ,
(EM_VAL ctxHandle, int callbackId, int channels) ,
{ var ctx=Emval.toValue(ctxHandle);var code=[ 'class QtSink extends AudioWorkletProcessor {', ' constructor(opts) {', ' super(opts);', ' this._numChannels=opts.processorOptions.channels|0;', ' this._queue=[];', ' this._pos=0;', ' this.port.onmessage=(e)=> { this._queue.push(e.data);};', ' }', ' process(inputs, outputs) {', ' var out=outputs[0];', ' if(!out||!out.length) return true;', ' var samplesPerChannel=out[0].length;', ' for(var i=0;i< samplesPerChannel;i++) {', ' while(this._queue.length > 0 &&this._pos >=this._queue[0].samplesPerChannel) {', ' this._queue.shift();', ' this._pos=0;', ' }', ' if(this._queue.length===0) break;', ' var frame=this._queue[0];', ' for(var channel=0;channel< out.length &&channel< frame.numChannels;channel++)', ' out[channel][i]=frame.data[channel *frame.samplesPerChannel+this._pos];', ' this._pos++;', ' }', ' this.port.postMessage(null);', ' return true;', ' }', '}', 'registerProcessor("qt-audio-sink", QtSink);'].join('\n');var blob=new Blob([code], { type:'application/javascript' });var url=URL.createObjectURL(blob);ctx.audioWorklet.addModule(url).then(function() { URL.revokeObjectURL(url);Module._qt_sinkWorkletReady(callbackId);});}  )

References EM_JS().

Referenced by EM_JS(), EM_JS(), EM_JS(), and EM_JS().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ EM_JS() [4/4]

EM_JS ( void ,
qt_st_sink_postFrame ,
(EM_VAL nodeHandle, int channels, int samplesPerChannel, const float *dataPtr) ,
{ var copy=HEAPF32.slice(dataPtr > > 2,(dataPtr > > 2)+channels *samplesPerChannel);Emval.toValue(nodeHandle).port.postMessage({ numChannels:channels, samplesPerChannel:samplesPerChannel, data:copy }, [copy.buffer]);}  )

References EM_JS().

Here is the call graph for this function:

◆ qt_sinkDeliverData()

EMSCRIPTEN_KEEPALIVE void qt_sinkDeliverData ( int id)

Definition at line 38 of file qwasmwebaudiosink.cpp.

References QWasmAudioSink::deliverDataCallback().

Here is the call graph for this function:

◆ qt_sinkWorkletReady()

EMSCRIPTEN_KEEPALIVE void qt_sinkWorkletReady ( int id)

Definition at line 37 of file qwasmwebaudiosink.cpp.

References QWasmAudioSink::workletReadyCallback().

Here is the call graph for this function:

Variable Documentation

◆ DEFAULT_BUFFER_DURATION

QT_BEGIN_NAMESPACE constexpr unsigned int DEFAULT_BUFFER_DURATION = 250'000
constexpr

Definition at line 17 of file qwasmwebaudiosink.cpp.

◆ RING_BUFFER_DURATION

int RING_BUFFER_DURATION = 250'000
constexpr

Definition at line 18 of file qwasmwebaudiosink.cpp.

◆ s_sinkRegistry

QHash< int, QWasmAudioSink * > s_sinkRegistry
static

Definition at line 22 of file qwasmwebaudiosink.cpp.