@@ -37,6 +37,9 @@ function createWasmAudioWorkletProcessor(audioParams) {
37
37
// 'render quantum size', and this exercise of passing in the value
38
38
// shouldn't be required (to be verified).
39
39
this . samplesPerChannel = opts [ 'sc' ] ;
40
+ // Typed views of the output buffers on the worklet's stack, which after
41
+ // creation should not change (since the stack is passed externally once).
42
+ this . outputViews = null ;
40
43
}
41
44
42
45
static get parameterDescriptors ( ) {
@@ -64,9 +67,6 @@ function createWasmAudioWorkletProcessor(audioParams) {
64
67
65
68
// Allocate the necessary stack space.
66
69
inputsPtr = stackAlloc ( stackMemoryNeeded ) ;
67
- #if WEBAUDIO_DEBUG
68
- console . log ( `WasmAudioWorkletProcessorr::process() ${ inputsPtr } (needed: ${ stackMemoryNeeded } )` ) ;
69
- #endif
70
70
71
71
// Copy input audio descriptor structs and data to Wasm
72
72
k = inputsPtr >> 2 ;
@@ -97,6 +97,20 @@ function createWasmAudioWorkletProcessor(audioParams) {
97
97
// Reserve space for the output data
98
98
dataPtr += bytesPerChannel * i . length ;
99
99
}
100
+ if ( ! this . outputViews ) {
101
+ this . outputViews = [ ] ;
102
+ k = outputDataPtr ;
103
+ for ( /*which output*/ i of outputList ) {
104
+ for ( /*which channel*/ j of i ) {
105
+ this . outputViews . push ( {
106
+ // dataPtr is the sanity check (to be implemented)
107
+ // dataSub is the one-time subarray into the heap
108
+ dataPtr : k ,
109
+ dataSub : HEAPF32 . subarray ( k , k += this . samplesPerChannel )
110
+ } ) ;
111
+ }
112
+ }
113
+ }
100
114
101
115
// Copy parameters descriptor structs and data to Wasm
102
116
paramsPtr = dataPtr ;
@@ -115,14 +129,12 @@ function createWasmAudioWorkletProcessor(audioParams) {
115
129
// Call out to Wasm callback to perform audio processing
116
130
if ( didProduceAudio = this . callbackFunction ( numInputs , inputsPtr , numOutputs , outputsPtr , numParams , paramsPtr , this . userData ) ) {
117
131
// Read back the produced audio data to all outputs and their channels.
118
- // (A garbage-free function TypedArray.copy(dstTypedArray, dstOffset,
119
- // srcTypedArray, srcOffset, count) would sure be handy.. but web does
120
- // not have one, so manually copy all bytes in)
121
- for ( /*which output*/ i of outputList ) {
122
- for ( /*which channel Float32Array<samplesPerChannel>*/ j of i ) {
123
- for ( /*channel index*/ k = 0 ; k < this . samplesPerChannel ; ++ k ) {
124
- j [ k ] = HEAPF32 [ outputDataPtr ++ ] ;
125
- }
132
+ // The 'outputViews' are subarray views into the heap, each with the
133
+ // correct offset and size to be copied directly into the output.
134
+ k = 0 ;
135
+ for ( i of outputList ) {
136
+ for ( j of i ) {
137
+ j . set ( this . outputViews [ k ++ ] . dataSub ) ;
126
138
}
127
139
}
128
140
}
0 commit comments