@@ -13,23 +13,15 @@ pub(crate) struct Alloc;
1313
1414thread_local ! {
1515 static POOL : RefCell <Vec <Rc <[ f32 ; RENDER_QUANTUM_SIZE ] >>> = RefCell :: new( Vec :: with_capacity( 32 ) ) ;
16- static ZEROES : Rc <[ f32 ; RENDER_QUANTUM_SIZE ] > = Rc :: new( [ 0. ; RENDER_QUANTUM_SIZE ] ) ;
1716}
1817
1918impl Alloc {
20- pub fn with_capacity ( n : usize ) -> Self {
19+ pub fn with_capacity ( _n : usize ) -> Self {
2120 Self { }
2221 }
2322
24- #[ cfg( test) ]
25- pub fn allocate ( & self ) -> AudioRenderQuantumChannel {
26- AudioRenderQuantumChannel { data : allocate ( ) }
27- }
28-
2923 pub fn silence ( & self ) -> AudioRenderQuantumChannel {
30- AudioRenderQuantumChannel {
31- data : ZEROES . with ( Rc :: clone) ,
32- }
24+ AudioRenderQuantumChannel { data : None }
3325 }
3426
3527 #[ cfg( test) ]
@@ -67,25 +59,35 @@ fn push(data: Rc<[f32; RENDER_QUANTUM_SIZE]>) {
6759/// mutate it from there.
6860#[ derive( Clone , Debug ) ]
6961pub struct AudioRenderQuantumChannel {
70- data : Rc < [ f32 ; RENDER_QUANTUM_SIZE ] > ,
62+ data : Option < Rc < [ f32 ; RENDER_QUANTUM_SIZE ] > > ,
7163}
7264
7365impl AudioRenderQuantumChannel {
7466 fn make_mut ( & mut self ) -> & mut [ f32 ; RENDER_QUANTUM_SIZE ] {
75- if Rc :: strong_count ( & self . data ) != 1 {
76- let mut new = allocate ( ) ;
77- Rc :: make_mut ( & mut new) . copy_from_slice ( self . data . deref ( ) ) ;
78- self . data = new;
67+ if self . data . is_none ( ) {
68+ self . data = Some ( allocate ( ) ) ;
69+ Rc :: make_mut ( self . data . as_mut ( ) . unwrap ( ) ) . fill ( 0. ) ;
7970 }
8071
81- Rc :: make_mut ( & mut self . data )
72+ match & mut self . data {
73+ Some ( data) => {
74+ if Rc :: strong_count ( data) != 1 {
75+ let mut new = allocate ( ) ;
76+ Rc :: make_mut ( & mut new) . copy_from_slice ( & data[ ..] ) ;
77+ * data = new;
78+ }
79+
80+ return Rc :: make_mut ( data) ;
81+ }
82+ None => unreachable ! ( ) ,
83+ }
8284 }
8385
8486 /// `O(1)` check if this buffer is equal to the 'silence buffer'
8587 ///
8688 /// If this function returns false, it is still possible for all samples to be zero.
8789 pub ( crate ) fn is_silent ( & self ) -> bool {
88- ZEROES . with ( |z| Rc :: ptr_eq ( & self . data , z ) )
90+ self . data . is_none ( )
8991 }
9092
9193 /// Sum two channels
@@ -98,9 +100,7 @@ impl AudioRenderQuantumChannel {
98100 }
99101
100102 pub ( crate ) fn silence ( & self ) -> Self {
101- Self {
102- data : ZEROES . with ( Rc :: clone) ,
103- }
103+ Self { data : None }
104104 }
105105}
106106
@@ -110,7 +110,10 @@ impl Deref for AudioRenderQuantumChannel {
110110 type Target = [ f32 ] ;
111111
112112 fn deref ( & self ) -> & Self :: Target {
113- self . data . as_slice ( )
113+ match & self . data {
114+ Some ( data) => data. as_slice ( ) ,
115+ None => & [ 0. ; RENDER_QUANTUM_SIZE ] ,
116+ }
114117 }
115118}
116119
@@ -122,16 +125,22 @@ impl DerefMut for AudioRenderQuantumChannel {
122125
123126impl AsRef < [ f32 ] > for AudioRenderQuantumChannel {
124127 fn as_ref ( & self ) -> & [ f32 ] {
125- & self . data [ ..]
128+ match & self . data {
129+ Some ( data) => data. as_slice ( ) ,
130+ None => & [ 0. ; RENDER_QUANTUM_SIZE ] ,
131+ }
126132 }
127133}
128134
129135impl std:: ops:: Drop for AudioRenderQuantumChannel {
130136 fn drop ( & mut self ) {
131- if Rc :: strong_count ( & self . data ) == 1 {
132- let zeroes = ZEROES . with ( Rc :: clone) ;
133- let rc = std:: mem:: replace ( & mut self . data , zeroes) ;
134- push ( rc) ;
137+ let data = match self . data . take ( ) {
138+ None => return ,
139+ Some ( data) => data,
140+ } ;
141+
142+ if Rc :: strong_count ( & data) == 1 {
143+ push ( data) ;
135144 }
136145 }
137146}
@@ -626,8 +635,15 @@ impl AudioRenderQuantum {
626635 let mut channels = self . channels . iter ( ) ;
627636 let first = channels. next ( ) . unwrap ( ) ;
628637 for c in channels {
629- if !Rc :: ptr_eq ( & first. data , & c. data ) {
630- return false ;
638+ match ( & first. data , & c. data ) {
639+ ( None , None ) => ( ) ,
640+ ( None , _) => return false ,
641+ ( _, None ) => return false ,
642+ ( Some ( d1) , Some ( d2) ) => {
643+ if !Rc :: ptr_eq ( d1, d2) {
644+ return false ;
645+ }
646+ }
631647 }
632648 }
633649
@@ -650,7 +666,7 @@ mod tests {
650666 alloc_counter:: deny_alloc ( || {
651667 {
652668 // take a buffer out of the pool
653- let a = alloc. allocate ( ) ;
669+ let a = alloc. silence ( ) ;
654670
655671 assert_float_eq ! ( & a[ ..] , & [ 0. ; RENDER_QUANTUM_SIZE ] [ ..] , abs_all <= 0. ) ;
656672 assert_eq ! ( alloc. pool_size( ) , 1 ) ;
@@ -675,12 +691,12 @@ mod tests {
675691 assert_eq ! ( alloc. pool_size( ) , 2 ) ;
676692
677693 let c = {
678- let a = alloc. allocate ( ) ;
679- let b = alloc. allocate ( ) ;
694+ let a = alloc. silence ( ) ;
695+ let b = alloc. silence ( ) ;
680696
681697 let c = alloc_counter:: allow_alloc ( || {
682698 // we can allocate beyond the pool size
683- let c = alloc. allocate ( ) ;
699+ let c = alloc. silence ( ) ;
684700 assert_eq ! ( alloc. pool_size( ) , 0 ) ;
685701 c
686702 } ) ;
@@ -757,7 +773,7 @@ mod tests {
757773 let mut signal1 = alloc. silence ( ) ;
758774 signal1. copy_from_slice ( & [ 1. ; RENDER_QUANTUM_SIZE ] ) ;
759775
760- let mut signal2 = alloc. allocate ( ) ;
776+ let mut signal2 = alloc. silence ( ) ;
761777 signal2. copy_from_slice ( & [ 2. ; RENDER_QUANTUM_SIZE ] ) ;
762778
763779 // test add silence to signal
0 commit comments