@@ -50,7 +50,9 @@ impl ScriptProcessorNode {
50
50
51
51
context. base ( ) . register ( move |registration| {
52
52
let render = ScriptProcessorRenderer {
53
- buffer : None ,
53
+ input_buffer : Vec :: with_capacity ( buffer_size / RENDER_QUANTUM_SIZE ) ,
54
+ output_buffer : Vec :: with_capacity ( buffer_size / RENDER_QUANTUM_SIZE ) ,
55
+ next_output_buffer : Vec :: with_capacity ( buffer_size / RENDER_QUANTUM_SIZE ) ,
54
56
buffer_size,
55
57
number_of_output_channels,
56
58
} ;
@@ -111,14 +113,16 @@ impl ScriptProcessorNode {
111
113
}
112
114
113
115
struct ScriptProcessorRenderer {
114
- buffer : Option < AudioRenderQuantum > , // TODO buffer_size
116
+ input_buffer : Vec < AudioRenderQuantum > ,
117
+ output_buffer : Vec < AudioRenderQuantum > ,
118
+ next_output_buffer : Vec < AudioRenderQuantum > ,
115
119
buffer_size : usize ,
116
120
number_of_output_channels : usize ,
117
121
}
118
122
119
123
// SAFETY:
120
- // AudioRenderQuantums are not Send but we promise the `buffer` is None before we ship it to the
121
- // render thread.
124
+ // AudioRenderQuantums are not Send but we promise the `buffer` VecDeque is empty before we ship it
125
+ // to the render thread.
122
126
#[ allow( clippy:: non_send_fields_in_send_ty) ]
123
127
unsafe impl Send for ScriptProcessorRenderer { }
124
128
@@ -134,34 +138,66 @@ impl AudioProcessor for ScriptProcessorRenderer {
134
138
let input = & inputs[ 0 ] ;
135
139
let output = & mut outputs[ 0 ] ;
136
140
137
- let mut silence = input. clone ( ) ;
138
- silence. make_silent ( ) ;
139
- if let Some ( buffer) = self . buffer . replace ( silence) {
140
- * output = buffer;
141
+ output. make_silent ( ) ;
142
+
143
+ let number_of_quanta = self . input_buffer . capacity ( ) ;
144
+
145
+ self . input_buffer . push ( input. clone ( ) ) ;
146
+ if self . input_buffer . len ( ) == number_of_quanta {
147
+ // convert self.input_buffer to an AudioBuffer
148
+ let number_of_input_channels = self
149
+ . input_buffer
150
+ . iter ( )
151
+ . map ( |i| i. number_of_channels ( ) )
152
+ . max ( )
153
+ . unwrap ( ) ;
154
+ let mut input_samples = vec ! [ vec![ 0. ; self . buffer_size] ; number_of_input_channels] ;
155
+ self . input_buffer . iter ( ) . enumerate ( ) . for_each ( |( i, b) | {
156
+ let offset = RENDER_QUANTUM_SIZE * i;
157
+ b. channels ( )
158
+ . iter ( )
159
+ . zip ( input_samples. iter_mut ( ) )
160
+ . for_each ( |( c, o) | {
161
+ o[ offset..( offset + RENDER_QUANTUM_SIZE ) ] . copy_from_slice ( c) ;
162
+ } ) ;
163
+ } ) ;
164
+ let input_buffer = AudioBuffer :: from ( input_samples, scope. sample_rate ) ;
165
+
166
+ // create a suitable output AudioBuffer
167
+ let output_samples = vec ! [ vec![ 0. ; self . buffer_size] ; self . number_of_output_channels] ;
168
+ let output_buffer = AudioBuffer :: from ( output_samples, scope. sample_rate ) ;
169
+
170
+ // emit event to control thread
171
+ let playback_time =
172
+ scope. current_time + self . buffer_size as f64 / scope. sample_rate as f64 ;
173
+ scope. send_audio_processing_event ( input_buffer, output_buffer, playback_time) ;
174
+
175
+ // clear existing input buffer
176
+ self . input_buffer . clear ( ) ;
177
+
178
+ // move next output buffer into current output buffer
179
+ std:: mem:: swap ( & mut self . output_buffer , & mut self . next_output_buffer ) ;
180
+ // fill next output buffer with silence
181
+ self . next_output_buffer . clear ( ) ;
182
+ let silence = output. clone ( ) ;
183
+ self . next_output_buffer . resize ( number_of_quanta, silence) ;
141
184
}
142
185
143
- // TODO buffer_size
144
- let input_samples = input. channels ( ) . iter ( ) . map ( |c| c. to_vec ( ) ) . collect ( ) ;
145
- let input_buffer = AudioBuffer :: from ( input_samples, scope. sample_rate ) ;
146
- let output_samples = vec ! [ vec![ 0. ; RENDER_QUANTUM_SIZE ] ; self . number_of_output_channels] ;
147
- let output_buffer = AudioBuffer :: from ( output_samples, scope. sample_rate ) ;
148
-
149
- let playback_time =
150
- scope. current_time + ( RENDER_QUANTUM_SIZE as f32 / scope. sample_rate ) as f64 ; // TODO
151
- scope. send_audio_processing_event ( input_buffer, output_buffer, playback_time) ;
186
+ if !self . output_buffer . is_empty ( ) {
187
+ * output = self . output_buffer . remove ( 0 ) ;
188
+ }
152
189
153
190
true // TODO - spec says false but that seems weird
154
191
}
155
192
156
193
fn onmessage ( & mut self , msg : & mut dyn Any ) {
157
194
if let Some ( buffer) = msg. downcast_mut :: < AudioBuffer > ( ) {
158
- if let Some ( render_quantum) = & mut self . buffer {
159
- buffer
160
- . channels ( )
161
- . iter ( )
162
- . zip ( render_quantum. channels_mut ( ) )
163
- . for_each ( |( i, o) | o. copy_from_slice ( i. as_slice ( ) ) ) ; // TODO bounds check
164
- }
195
+ buffer. channels ( ) . iter ( ) . enumerate ( ) . for_each ( |( i, c) | {
196
+ c. as_slice ( )
197
+ . chunks ( RENDER_QUANTUM_SIZE )
198
+ . zip ( self . next_output_buffer . iter_mut ( ) )
199
+ . for_each ( |( s, o) | o. channel_data_mut ( i) . copy_from_slice ( s) )
200
+ } ) ;
165
201
return ;
166
202
} ;
167
203
0 commit comments