@@ -172,6 +172,24 @@ impl<'a> OutputAudioData<'a> {
172172 . map ( |s| s. consumer . read ( ) . buffers . as_slice ( ) )
173173 }
174174
175+ /// Get the latest channels of audio data, along with a "generation" value.
176+ ///
177+ /// The generation value is equal to how many times the buffer has been updated
178+ /// since the node was first created. This can be used to quickly check if the
179+ /// buffer differs from the previous read.
180+ ///
181+ /// The samples are in de-interleaved format (one `Vec` for each channel). The
182+ /// length of each `Vec` will be equal to the `window_size` parameter at the
183+ /// time the buffer was last updated.
184+ ///
185+ /// If the node is not currently active, then this will return `None`.
186+ pub fn channels_with_generation < ' b > ( & ' b mut self ) -> Option < ( & ' b [ Vec < f32 > ] , u64 ) > {
187+ self . guarded_state . as_mut ( ) . map ( |s| {
188+ let data = s. consumer . read ( ) ;
189+ ( data. buffers . as_slice ( ) , data. generation )
190+ } )
191+ }
192+
175193 /// Peek the audio data that is currently in the buffer without checking if
176194 /// there is new data.
177195 ///
@@ -211,9 +229,12 @@ impl AudioNode for TripleBufferNode {
211229 let sample_rate = cx. stream_info . sample_rate ;
212230 let max_window_size_frames = config. max_window_size . as_frames ( sample_rate) as usize ;
213231
214- let ( producer, consumer) = triple_buffer:: triple_buffer :: < TripleBufferData > (
215- & TripleBufferData :: new ( config. channels . get ( ) . get ( ) as usize , max_window_size_frames) ,
216- ) ;
232+ let ( producer, consumer) =
233+ triple_buffer:: triple_buffer :: < TripleBufferData > ( & TripleBufferData :: new (
234+ config. channels . get ( ) . get ( ) as usize ,
235+ max_window_size_frames,
236+ 0 ,
237+ ) ) ;
217238
218239 let state = cx. custom_state_mut :: < TripleBufferState > ( ) . unwrap ( ) ;
219240
@@ -244,6 +265,10 @@ impl AudioNode for TripleBufferNode {
244265 tmp_ring_buffer,
245266 ring_buf_ptr : 0 ,
246267 active_state,
268+ generation : 0 ,
269+ prev_publish_was_silent : true ,
270+ num_silent_frames_in_tmp : window_size_frames,
271+ tmp_buffer_needs_cleared : false ,
247272 }
248273 }
249274}
@@ -261,6 +286,11 @@ struct Processor {
261286
262287 // The processor only uses this when a new stream has started.
263288 active_state : Arc < Mutex < Option < ActiveState > > > ,
289+ generation : u64 ,
290+
291+ prev_publish_was_silent : bool ,
292+ num_silent_frames_in_tmp : usize ,
293+ tmp_buffer_needs_cleared : bool ,
264294}
265295
266296impl AudioNodeProcessor for Processor {
@@ -290,12 +320,15 @@ impl AudioNodeProcessor for Processor {
290320 if !self . params . enabled {
291321 if was_enabled {
292322 {
293- let out_buffer = producer. input_buffer_mut ( ) ;
323+ let buffer = producer. input_buffer_mut ( ) ;
294324
295- for out_ch in out_buffer . buffers . iter_mut ( ) {
296- out_ch . clear ( ) ;
297- out_ch . resize ( self . window_size_frames , 0.0 ) ;
325+ for buf_ch in buffer . buffers . iter_mut ( ) {
326+ buf_ch . clear ( ) ;
327+ buf_ch . resize ( self . window_size_frames , 0.0 ) ;
298328 }
329+
330+ self . generation += 1 ;
331+ buffer. generation = self . generation ;
299332 }
300333
301334 producer. publish ( ) ;
@@ -304,12 +337,17 @@ impl AudioNodeProcessor for Processor {
304337 tmp_ch. clear ( ) ;
305338 tmp_ch. resize ( self . window_size_frames , 0.0 ) ;
306339 }
340+
307341 self . ring_buf_ptr = 0 ;
342+ self . prev_publish_was_silent = true ;
343+ self . num_silent_frames_in_tmp = self . window_size_frames ;
344+ self . tmp_buffer_needs_cleared = false ;
308345 }
309346
310347 return ProcessStatus :: ClearAllOutputs ;
311348 }
312349
350+ let mut resized = false ;
313351 if self . tmp_ring_buffer [ 0 ] . len ( ) != self . window_size_frames {
314352 let prev_window_size_frames = self . tmp_ring_buffer [ 0 ] . len ( ) ;
315353
@@ -348,6 +386,27 @@ impl AudioNodeProcessor for Processor {
348386 }
349387
350388 self . ring_buf_ptr = 0 ;
389+ self . num_silent_frames_in_tmp = 0 ;
390+ resized = true ;
391+ }
392+
393+ let input_is_silent = info
394+ . in_silence_mask
395+ . all_channels_silent ( buffers. inputs . len ( ) ) ;
396+ if input_is_silent {
397+ self . num_silent_frames_in_tmp =
398+ ( self . num_silent_frames_in_tmp + info. frames ) . min ( self . window_size_frames ) ;
399+ } else {
400+ self . num_silent_frames_in_tmp = 0 ;
401+ }
402+
403+ if self . num_silent_frames_in_tmp == self . window_size_frames
404+ && self . prev_publish_was_silent
405+ && !resized
406+ {
407+ // The previous publish already contained silence, so no need to publish again.
408+ self . tmp_buffer_needs_cleared = true ;
409+ return ProcessStatus :: ClearAllOutputs ;
351410 }
352411
353412 if info. frames >= self . window_size_frames {
@@ -357,7 +416,18 @@ impl AudioNodeProcessor for Processor {
357416 . copy_from_slice ( & in_ch[ info. frames - self . window_size_frames ..info. frames ] ) ;
358417 }
359418 self . ring_buf_ptr = 0 ;
419+ self . tmp_buffer_needs_cleared = false ;
360420 } else {
421+ if self . tmp_buffer_needs_cleared {
422+ self . tmp_buffer_needs_cleared = false ;
423+
424+ for tmp_ch in self . tmp_ring_buffer . iter_mut ( ) {
425+ tmp_ch. clear ( ) ;
426+ tmp_ch. resize ( self . window_size_frames , 0.0 ) ;
427+ }
428+ self . ring_buf_ptr = 0 ;
429+ }
430+
361431 let first_copy_frames = info. frames . min ( self . window_size_frames - self . ring_buf_ptr ) ;
362432 let second_copy_frames = info. frames - first_copy_frames;
363433
@@ -399,10 +469,15 @@ impl AudioNodeProcessor for Processor {
399469 buf_ch. extend_from_slice ( & tmp_ch[ 0 ..second_copy_frames] ) ;
400470 }
401471 }
472+
473+ self . generation += 1 ;
474+ buffer. generation = self . generation ;
402475 }
403476
404477 producer. publish ( ) ;
405478
479+ self . prev_publish_was_silent = self . num_silent_frames_in_tmp == self . window_size_frames ;
480+
406481 ProcessStatus :: ClearAllOutputs
407482 }
408483
@@ -430,11 +505,17 @@ impl AudioNodeProcessor for Processor {
430505 } )
431506 . collect ( ) ;
432507 self . ring_buf_ptr = 0 ;
508+ self . num_silent_frames_in_tmp = self . window_size_frames ;
509+ self . tmp_buffer_needs_cleared = false ;
510+ self . prev_publish_was_silent = true ;
511+
512+ self . generation += 1 ;
433513
434514 let ( producer, consumer) =
435515 triple_buffer:: triple_buffer :: < TripleBufferData > ( & TripleBufferData :: new (
436516 self . config . channels . get ( ) . get ( ) as usize ,
437517 self . max_window_size_frames ,
518+ self . generation ,
438519 ) ) ;
439520
440521 * self . active_state . lock ( ) . unwrap ( ) = Some ( ActiveState {
@@ -451,10 +532,11 @@ impl AudioNodeProcessor for Processor {
451532struct TripleBufferData {
452533 buffers : Vec < Vec < f32 > > ,
453534 max_frames : usize ,
535+ generation : u64 ,
454536}
455537
456538impl TripleBufferData {
457- fn new ( num_channels : usize , max_frames : usize ) -> Self {
539+ fn new ( num_channels : usize , max_frames : usize , generation : u64 ) -> Self {
458540 let mut buffers = Vec :: new ( ) ;
459541 buffers. reserve_exact ( num_channels) ;
460542
@@ -470,12 +552,13 @@ impl TripleBufferData {
470552 Self {
471553 buffers,
472554 max_frames,
555+ generation,
473556 }
474557 }
475558}
476559
477560impl Clone for TripleBufferData {
478561 fn clone ( & self ) -> Self {
479- Self :: new ( self . buffers . len ( ) , self . max_frames )
562+ Self :: new ( self . buffers . len ( ) , self . max_frames , self . generation )
480563 }
481564}
0 commit comments