@@ -23,6 +23,8 @@ use super::graph::Graph;
23
23
pub ( crate ) struct RenderThread {
24
24
graph : Option < Graph > ,
25
25
sample_rate : f32 ,
26
+ /// number of channels of the backend stream, i.e. sound card number of
27
+ /// channels clamped to MAX_CHANNELS
26
28
number_of_channels : usize ,
27
29
frames_played : Arc < AtomicU64 > ,
28
30
receiver : Option < Receiver < ControlMessage > > ,
@@ -176,12 +178,12 @@ impl RenderThread {
176
178
buffer
177
179
}
178
180
179
- pub fn render < S : FromSample < f32 > + Clone > ( & mut self , buffer : & mut [ S ] ) {
181
+ pub fn render < S : FromSample < f32 > + Clone > ( & mut self , output_buffer : & mut [ S ] ) {
180
182
// collect timing information
181
183
let render_start = Instant :: now ( ) ;
182
184
183
185
// perform actual rendering
184
- self . render_inner ( buffer ) ;
186
+ self . render_inner ( output_buffer ) ;
185
187
186
188
// calculate load value and ship to control thread
187
189
if let Some ( load_value_sender) = & self . load_value_sender {
@@ -198,13 +200,13 @@ impl RenderThread {
198
200
}
199
201
}
200
202
201
- fn render_inner < S : FromSample < f32 > + Clone > ( & mut self , mut buffer : & mut [ S ] ) {
203
+ fn render_inner < S : FromSample < f32 > + Clone > ( & mut self , mut output_buffer : & mut [ S ] ) {
202
204
// There may be audio frames left over from the previous render call,
203
205
// if the cpal buffer size did not align with our internal RENDER_QUANTUM_SIZE
204
206
if let Some ( ( offset, prev_rendered) ) = self . buffer_offset . take ( ) {
205
207
let leftover_len = ( RENDER_QUANTUM_SIZE - offset) * self . number_of_channels ;
206
208
// split the leftover frames slice, to fit in `buffer`
207
- let ( first, next) = buffer . split_at_mut ( leftover_len. min ( buffer . len ( ) ) ) ;
209
+ let ( first, next) = output_buffer . split_at_mut ( leftover_len. min ( output_buffer . len ( ) ) ) ;
208
210
209
211
// copy rendered audio into output slice
210
212
for i in 0 ..self . number_of_channels {
@@ -226,23 +228,23 @@ impl RenderThread {
226
228
}
227
229
228
230
// if there's still space left in the buffer, continue rendering
229
- buffer = next;
231
+ output_buffer = next;
230
232
}
231
233
232
234
// handle addition/removal of nodes/edges
233
235
self . handle_control_messages ( ) ;
234
236
235
237
// if the thread is still booting, or shutting down, fill with silence
236
238
if self . graph . is_none ( ) {
237
- buffer . fill ( S :: from_sample_ ( 0. ) ) ;
239
+ output_buffer . fill ( S :: from_sample_ ( 0. ) ) ;
238
240
return ;
239
241
}
240
242
241
243
// The audio graph is rendered in chunks of RENDER_QUANTUM_SIZE frames. But some audio backends
242
244
// may not be able to emit chunks of this size.
243
245
let chunk_size = RENDER_QUANTUM_SIZE * self . number_of_channels ;
244
246
245
- for data in buffer . chunks_mut ( chunk_size) {
247
+ for data in output_buffer . chunks_mut ( chunk_size) {
246
248
// update time
247
249
let current_frame = self
248
250
. frames_played
@@ -258,17 +260,19 @@ impl RenderThread {
258
260
} ;
259
261
260
262
// render audio graph, clone it in case we need to mutate/store the value later
261
- let mut rendered = self . graph . as_mut ( ) . unwrap ( ) . render ( & scope) . clone ( ) ;
263
+ let mut destination_buffer = self . graph . as_mut ( ) . unwrap ( ) . render ( & scope) . clone ( ) ;
262
264
263
- // online AudioContext allows channel count to be less than no of hardware channels
264
- if rendered. number_of_channels ( ) != self . number_of_channels {
265
- rendered. mix ( self . number_of_channels , ChannelInterpretation :: Discrete ) ;
265
+ // online AudioContext allows channel count to be less than the number
266
+ // of channels of the backend stream, i.e. number of channels of the
267
+ // soundcard clamped to MAX_CHANNELS.
268
+ if destination_buffer. number_of_channels ( ) < self . number_of_channels {
269
+ destination_buffer. mix ( self . number_of_channels , ChannelInterpretation :: Discrete ) ;
266
270
}
267
271
268
272
// copy rendered audio into output slice
269
273
for i in 0 ..self . number_of_channels {
270
274
let output = data. iter_mut ( ) . skip ( i) . step_by ( self . number_of_channels ) ;
271
- let channel = rendered . channel_data ( i) . iter ( ) ;
275
+ let channel = destination_buffer . channel_data ( i) . iter ( ) ;
272
276
for ( sample, input) in output. zip ( channel) {
273
277
let value = S :: from_sample_ ( * input) ;
274
278
* sample = value;
@@ -279,7 +283,7 @@ impl RenderThread {
279
283
// this is the last chunk, and it contained less than RENDER_QUANTUM_SIZE samples
280
284
let channel_offset = data. len ( ) / self . number_of_channels ;
281
285
debug_assert ! ( channel_offset < RENDER_QUANTUM_SIZE ) ;
282
- self . buffer_offset = Some ( ( channel_offset, rendered ) ) ;
286
+ self . buffer_offset = Some ( ( channel_offset, destination_buffer ) ) ;
283
287
}
284
288
285
289
// handle addition/removal of nodes/edges
0 commit comments