@@ -13,23 +13,15 @@ pub(crate) struct Alloc;
13
13
14
14
thread_local ! {
15
15
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 ] ) ;
17
16
}
18
17
19
18
impl Alloc {
20
- pub fn with_capacity ( n : usize ) -> Self {
19
+ pub fn with_capacity ( _n : usize ) -> Self {
21
20
Self { }
22
21
}
23
22
24
- #[ cfg( test) ]
25
- pub fn allocate ( & self ) -> AudioRenderQuantumChannel {
26
- AudioRenderQuantumChannel { data : allocate ( ) }
27
- }
28
-
29
23
pub fn silence ( & self ) -> AudioRenderQuantumChannel {
30
- AudioRenderQuantumChannel {
31
- data : ZEROES . with ( Rc :: clone) ,
32
- }
24
+ AudioRenderQuantumChannel { data : None }
33
25
}
34
26
35
27
#[ cfg( test) ]
@@ -67,25 +59,35 @@ fn push(data: Rc<[f32; RENDER_QUANTUM_SIZE]>) {
67
59
/// mutate it from there.
68
60
#[ derive( Clone , Debug ) ]
69
61
pub struct AudioRenderQuantumChannel {
70
- data : Rc < [ f32 ; RENDER_QUANTUM_SIZE ] > ,
62
+ data : Option < Rc < [ f32 ; RENDER_QUANTUM_SIZE ] > > ,
71
63
}
72
64
73
65
impl AudioRenderQuantumChannel {
74
66
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. ) ;
79
70
}
80
71
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
+ }
82
84
}
83
85
84
86
/// `O(1)` check if this buffer is equal to the 'silence buffer'
85
87
///
86
88
/// If this function returns false, it is still possible for all samples to be zero.
87
89
pub ( crate ) fn is_silent ( & self ) -> bool {
88
- ZEROES . with ( |z| Rc :: ptr_eq ( & self . data , z ) )
90
+ self . data . is_none ( )
89
91
}
90
92
91
93
/// Sum two channels
@@ -98,9 +100,7 @@ impl AudioRenderQuantumChannel {
98
100
}
99
101
100
102
pub ( crate ) fn silence ( & self ) -> Self {
101
- Self {
102
- data : ZEROES . with ( Rc :: clone) ,
103
- }
103
+ Self { data : None }
104
104
}
105
105
}
106
106
@@ -110,7 +110,10 @@ impl Deref for AudioRenderQuantumChannel {
110
110
type Target = [ f32 ] ;
111
111
112
112
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
+ }
114
117
}
115
118
}
116
119
@@ -122,16 +125,22 @@ impl DerefMut for AudioRenderQuantumChannel {
122
125
123
126
impl AsRef < [ f32 ] > for AudioRenderQuantumChannel {
124
127
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
+ }
126
132
}
127
133
}
128
134
129
135
impl std:: ops:: Drop for AudioRenderQuantumChannel {
130
136
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) ;
135
144
}
136
145
}
137
146
}
@@ -626,8 +635,15 @@ impl AudioRenderQuantum {
626
635
let mut channels = self . channels . iter ( ) ;
627
636
let first = channels. next ( ) . unwrap ( ) ;
628
637
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
+ }
631
647
}
632
648
}
633
649
@@ -650,7 +666,7 @@ mod tests {
650
666
alloc_counter:: deny_alloc ( || {
651
667
{
652
668
// take a buffer out of the pool
653
- let a = alloc. allocate ( ) ;
669
+ let a = alloc. silence ( ) ;
654
670
655
671
assert_float_eq ! ( & a[ ..] , & [ 0. ; RENDER_QUANTUM_SIZE ] [ ..] , abs_all <= 0. ) ;
656
672
assert_eq ! ( alloc. pool_size( ) , 1 ) ;
@@ -675,12 +691,12 @@ mod tests {
675
691
assert_eq ! ( alloc. pool_size( ) , 2 ) ;
676
692
677
693
let c = {
678
- let a = alloc. allocate ( ) ;
679
- let b = alloc. allocate ( ) ;
694
+ let a = alloc. silence ( ) ;
695
+ let b = alloc. silence ( ) ;
680
696
681
697
let c = alloc_counter:: allow_alloc ( || {
682
698
// we can allocate beyond the pool size
683
- let c = alloc. allocate ( ) ;
699
+ let c = alloc. silence ( ) ;
684
700
assert_eq ! ( alloc. pool_size( ) , 0 ) ;
685
701
c
686
702
} ) ;
@@ -757,7 +773,7 @@ mod tests {
757
773
let mut signal1 = alloc. silence ( ) ;
758
774
signal1. copy_from_slice ( & [ 1. ; RENDER_QUANTUM_SIZE ] ) ;
759
775
760
- let mut signal2 = alloc. allocate ( ) ;
776
+ let mut signal2 = alloc. silence ( ) ;
761
777
signal2. copy_from_slice ( & [ 2. ; RENDER_QUANTUM_SIZE ] ) ;
762
778
763
779
// test add silence to signal
0 commit comments