Skip to content

Commit f6ed386

Browse files
authored
[AUDIO_WORKLET] Reword API to make it clearer (#22741)
Following from @juj 's suggestion in #22681, the use of quantum has been reduced to only where it refers to the API. Internally it's named `samplesPerChannel` to match the `numberOfChannels` in the `AudioSampleFrame`. (This is entirely optional and doesn't change anything other than the naming.)
1 parent 0054150 commit f6ed386

File tree

9 files changed

+31
-31
lines changed

9 files changed

+31
-31
lines changed

site/source/docs/api_reference/wasm_audio_worklets.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Once a class type is instantiated on the Web Audio graph and the graph is
4747
running, a C/C++ function pointer callback will be invoked for each 128
4848
samples of the processed audio stream that flows through the node. Newer Web
4949
Audio API specs allow this to be changed, so for future compatibility use the
50-
``AudioSampleFrame``'s ``quantumSize`` to get the value.
50+
``AudioSampleFrame``'s ``samplesPerChannel`` to get the value.
5151

5252
This callback will be executed on a dedicated separate audio processing
5353
thread with real-time processing priority. Each Web Audio context will
@@ -159,7 +159,7 @@ which resumes the audio context when the user clicks on the DOM Canvas element t
159159
void *userData)
160160
{
161161
for(int i = 0; i < numOutputs; ++i)
162-
for(int j = 0; j < outputs[i].quantumSize*outputs[i].numberOfChannels; ++j)
162+
for(int j = 0; j < outputs[i].samplesPerChannel*outputs[i].numberOfChannels; ++j)
163163
outputs[i].data[j] = emscripten_random() * 0.2 - 0.1; // Warning: scale down audio volume by factor of 0.2, raw noise can be really loud otherwise
164164
165165
return true; // Keep the graph output going

src/audio_worklet.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ function createWasmAudioWorkletProcessor(audioParams) {
3131
let opts = args.processorOptions;
3232
this.callbackFunction = Module['wasmTable'].get(opts['cb']);
3333
this.userData = opts['ud'];
34-
// Plus the number of samples to process, fixed for the lifetime of the
34+
// Then the samples per channel to process, fixed for the lifetime of the
3535
// context that created this processor. Note for when moving to Web Audio
36-
// 1.1: the typed array passed to process() should be the same size as the
37-
// the quantum size, and this exercise of passing in the value shouldn't
38-
// be required (to be verified).
39-
this.quantumSize = opts['qs'];
36+
// 1.1: the typed array passed to process() should be the same size as this
37+
// 'render quantum size', and this exercise of passing in the value
38+
// shouldn't be required (to be verified).
39+
this.samplesPerChannel = opts['sc'];
4040
}
4141

4242
static get parameterDescriptors() {
@@ -51,15 +51,15 @@ function createWasmAudioWorkletProcessor(audioParams) {
5151
let numInputs = inputList.length,
5252
numOutputs = outputList.length,
5353
numParams = 0, i, j, k, dataPtr,
54-
quantumBytes = this.quantumSize * 4,
54+
bytesPerChannel = this.samplesPerChannel * 4,
5555
stackMemoryNeeded = (numInputs + numOutputs) * {{{ C_STRUCTS.AudioSampleFrame.__size__ }}},
5656
oldStackPtr = stackSave(),
5757
inputsPtr, outputsPtr, outputDataPtr, paramsPtr,
5858
didProduceAudio, paramArray;
5959

6060
// Calculate how much stack space is needed.
61-
for (i of inputList) stackMemoryNeeded += i.length * quantumBytes;
62-
for (i of outputList) stackMemoryNeeded += i.length * quantumBytes;
61+
for (i of inputList) stackMemoryNeeded += i.length * bytesPerChannel;
62+
for (i of outputList) stackMemoryNeeded += i.length * bytesPerChannel;
6363
for (i in parameters) stackMemoryNeeded += parameters[i].byteLength + {{{ C_STRUCTS.AudioParamFrame.__size__ }}}, ++numParams;
6464

6565
// Allocate the necessary stack space.
@@ -71,13 +71,13 @@ function createWasmAudioWorkletProcessor(audioParams) {
7171
for (i of inputList) {
7272
// Write the AudioSampleFrame struct instance
7373
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.numberOfChannels / 4 }}}] = i.length;
74-
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.quantumSize / 4 }}}] = this.quantumSize;
74+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.samplesPerChannel / 4 }}}] = this.samplesPerChannel;
7575
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 }}}] = dataPtr;
7676
k += {{{ C_STRUCTS.AudioSampleFrame.__size__ / 4 }}};
7777
// Marshal the input audio sample data for each audio channel of this input
7878
for (j of i) {
7979
HEAPF32.set(j, dataPtr>>2);
80-
dataPtr += quantumBytes;
80+
dataPtr += bytesPerChannel;
8181
}
8282
}
8383

@@ -88,11 +88,11 @@ function createWasmAudioWorkletProcessor(audioParams) {
8888
for (i of outputList) {
8989
// Write the AudioSampleFrame struct instance
9090
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.numberOfChannels / 4 }}}] = i.length;
91-
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.quantumSize / 4 }}}] = this.quantumSize;
91+
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.samplesPerChannel / 4 }}}] = this.samplesPerChannel;
9292
HEAPU32[k + {{{ C_STRUCTS.AudioSampleFrame.data / 4 }}}] = dataPtr;
9393
k += {{{ C_STRUCTS.AudioSampleFrame.__size__ / 4 }}};
9494
// Reserve space for the output data
95-
dataPtr += quantumBytes * i.length;
95+
dataPtr += bytesPerChannel * i.length;
9696
}
9797

9898
// Copy parameters descriptor structs and data to Wasm
@@ -117,7 +117,7 @@ function createWasmAudioWorkletProcessor(audioParams) {
117117
// not have one, so manually copy all bytes in)
118118
for (i of outputList) {
119119
for (j of i) {
120-
for (k = 0; k < this.quantumSize; ++k) {
120+
for (k = 0; k < this.samplesPerChannel; ++k) {
121121
j[k] = HEAPF32[outputDataPtr++];
122122
}
123123
}

src/library_webaudio.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ let LibraryWebAudio = {
3737
// Wasm handle ID.
3838
$emscriptenGetAudioObject: (objectHandle) => EmAudio[objectHandle],
3939

40-
// Performs the work of getting the AudioContext's quantum size.
40+
// Performs the work of getting the AudioContext's render quantum size.
4141
$emscriptenGetContextQuantumSize: (contextHandle) => {
4242
// TODO: in a future release this will be something like:
4343
// return EmAudio[contextHandle].renderQuantumSize || 128;
@@ -296,7 +296,7 @@ let LibraryWebAudio = {
296296
processorOptions: {
297297
'cb': callback,
298298
'ud': userData,
299-
'qs': emscriptenGetContextQuantumSize(contextHandle)
299+
'sc': emscriptenGetContextQuantumSize(contextHandle)
300300
}
301301
} : void 0;
302302

src/struct_info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1203,7 +1203,7 @@
12031203
"structs": {
12041204
"AudioSampleFrame": [
12051205
"numberOfChannels",
1206-
"quantumSize",
1206+
"samplesPerChannel",
12071207
"data"
12081208
],
12091209
"AudioParamFrame": [

src/struct_info_generated.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@
479479
"__size__": 12,
480480
"data": 8,
481481
"numberOfChannels": 0,
482-
"quantumSize": 4
482+
"samplesPerChannel": 4
483483
},
484484
"EmscriptenBatteryEvent": {
485485
"__size__": 32,

src/struct_info_generated_wasm64.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@
479479
"__size__": 16,
480480
"data": 8,
481481
"numberOfChannels": 0,
482-
"quantumSize": 4
482+
"samplesPerChannel": 4
483483
},
484484
"EmscriptenBatteryEvent": {
485485
"__size__": 32,

system/include/emscripten/webaudio.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,19 @@ typedef int EMSCRIPTEN_AUDIO_WORKLET_NODE_T;
103103

104104
typedef struct AudioSampleFrame
105105
{
106-
// Number of audio channels to process (multiplied by quantumSize gives the elements in data)
106+
// Number of audio channels to process (multiplied by samplesPerChannel gives the elements in data)
107107
const int numberOfChannels;
108108
// Number of samples per channel in data
109-
const int quantumSize;
110-
// An array of length numberOfChannels*quantumSize elements. Samples are always arranged in a planar fashion,
111-
// where data[channelIndex*quantumSize+i] locates the data of the i'th sample of channel channelIndex.
109+
const int samplesPerChannel;
110+
// An array of length numberOfChannels*samplesPerChannel elements. Samples are always arranged in a planar fashion,
111+
// where data[channelIndex*samplesPerChannel+i] locates the data of the i'th sample of channel channelIndex.
112112
float *data;
113113
} AudioSampleFrame;
114114

115115
typedef struct AudioParamFrame
116116
{
117117
// Specifies the length of the input array data (in float elements). This will be guaranteed to either have
118-
// a value of 1, for a parameter valid for the entire frame, or emscripten_audio_context_quantum_size() for a parameter that changes during the frame.
118+
// a value of 1, for a parameter valid for the entire frame, or emscripten_audio_context_quantum_size() for a parameter that changes per sample during the frame.
119119
int length;
120120
// An array of length specified in 'length'.
121121
float *data;

test/webaudio/audio_worklet_tone_generator.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ bool ProcessAudio(int numInputs, const AudioSampleFrame *inputs, int numOutputs,
4040

4141
// Produce a sine wave tone of desired frequency to all output channels.
4242
for(int o = 0; o < numOutputs; ++o)
43-
for(int i = 0; i < outputs[o].quantumSize; ++i)
43+
for(int i = 0; i < outputs[o].samplesPerChannel; ++i)
4444
{
4545
float s = emscripten_math_sin(phase);
4646
phase += phaseIncrement;
4747
for(int ch = 0; ch < outputs[o].numberOfChannels; ++ch)
48-
outputs[o].data[ch*outputs[o].quantumSize + i] = s * currentVolume;
48+
outputs[o].data[ch*outputs[o].samplesPerChannel + i] = s * currentVolume;
4949
}
5050

5151
// Range reduce to keep precision around zero.
@@ -150,11 +150,11 @@ int main() {
150150

151151
EMSCRIPTEN_WEBAUDIO_T context = emscripten_create_audio_context(&attrs);
152152

153-
// Get the context's quantum size. Once the audio API allows this to be user
154-
// defined or exposes the hardware's own value, this will be needed to
153+
// Get the context's render quantum size. Once the audio API allows this to be
154+
// user defined or exposes the hardware's own value, this will be needed to
155155
// determine the worklet stack size.
156156
int quantumSize = emscripten_audio_context_quantum_size(context);
157-
printf("Context quantum size: %d\n", quantumSize);
157+
printf("Context render quantum size: %d\n", quantumSize);
158158

159159
// and kick off Audio Worklet scope initialization, which shares the Wasm
160160
// Module and Memory to the AudioWorklet scope and initializes its stack.

test/webaudio/audioworklet.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ bool ProcessAudio(int numInputs, const AudioSampleFrame *inputs, int numOutputs,
4040

4141
// Produce noise in all output channels.
4242
for(int i = 0; i < numOutputs; ++i)
43-
for(int j = 0; j < outputs[i].quantumSize*outputs[i].numberOfChannels; ++j)
43+
for(int j = 0; j < outputs[i].samplesPerChannel*outputs[i].numberOfChannels; ++j)
4444
outputs[i].data[j] = (rand() / (float)RAND_MAX * 2.0f - 1.0f) * 0.3f;
4545

4646
// We generated audio and want to keep this processor going. Return false here to shut down.

0 commit comments

Comments
 (0)