1
+ /// A iterator that stores extracted data in memory while allowing
2
+ /// concurrent reading in real time.
1
3
use std:: mem;
2
4
use std:: sync:: { Arc , Mutex } ;
3
5
use std:: time:: Duration ;
4
6
5
7
use super :: SeekError ;
6
8
use crate :: common:: { ChannelCount , SampleRate } ;
9
+ use crate :: math:: PrevMultipleOf ;
7
10
use crate :: Source ;
8
11
9
- /// Internal function that builds a `Buffered` object.
10
- #[ inline]
11
- pub fn buffered < I > ( input : I ) -> Buffered < I >
12
- where
13
- I : Source ,
14
- {
15
- let total_duration = input. total_duration ( ) ;
16
- let first_span = extract ( input) ;
17
-
18
- Buffered {
19
- current_span : first_span,
20
- position_in_span : 0 ,
21
- total_duration,
22
- }
23
- }
24
-
25
- /// Iterator that at the same time extracts data from the iterator and stores it in a buffer.
12
+ /// Iterator that at the same time extracts data from the iterator and
13
+ /// stores it in a buffer.
26
14
pub struct Buffered < I >
27
15
where
28
16
I : Source ,
29
17
{
30
18
/// Immutable reference to the next span of data. Cannot be `Span::Input`.
31
19
current_span : Arc < Span < I > > ,
32
20
21
+ parameters_changed : bool ,
22
+
33
23
/// The position in number of samples of this iterator inside `current_span`.
34
24
position_in_span : usize ,
35
25
36
26
/// Obtained once at creation and never modified again.
37
27
total_duration : Option < Duration > ,
38
28
}
39
29
40
- enum Span < I >
41
- where
42
- I : Source ,
43
- {
44
- /// Data that has already been extracted from the iterator. Also contains a pointer to the
45
- /// next span.
46
- Data ( SpanData < I > ) ,
47
-
48
- /// No more data.
49
- End ,
50
-
51
- /// Unextracted data. The `Option` should never be `None` and is only here for easier data
52
- /// processing.
53
- Input ( Mutex < Option < I > > ) ,
54
- }
55
-
56
- struct SpanData < I >
57
- where
58
- I : Source ,
59
- {
60
- data : Vec < I :: Item > ,
61
- channels : ChannelCount ,
62
- rate : SampleRate ,
63
- next : Mutex < Arc < Span < I > > > ,
64
- }
65
-
66
- impl < I > Drop for SpanData < I >
67
- where
68
- I : Source ,
69
- {
70
- fn drop ( & mut self ) {
71
- // This is necessary to prevent stack overflows deallocating long chains of the mutually
72
- // recursive `Span` and `SpanData` types. This iteratively traverses as much of the
73
- // chain as needs to be deallocated, and repeatedly "pops" the head off the list. This
74
- // solves the problem, as when the time comes to actually deallocate the `SpanData`,
75
- // the `next` field will contain a `Span::End`, or an `Arc` with additional references,
76
- // so the depth of recursive drops will be bounded.
77
- while let Ok ( arc_next) = self . next . get_mut ( ) {
78
- if let Some ( next_ref) = Arc :: get_mut ( arc_next) {
79
- // This allows us to own the next Span.
80
- let next = mem:: replace ( next_ref, Span :: End ) ;
81
- if let Span :: Data ( next_data) = next {
82
- // Swap the current SpanData with the next one, allowing the current one
83
- // to go out of scope.
84
- * self = next_data;
85
- } else {
86
- break ;
87
- }
88
- } else {
89
- break ;
90
- }
91
- }
92
- }
93
- }
94
-
95
- /// Builds a span from the input iterator.
96
- fn extract < I > ( mut input : I ) -> Arc < Span < I > >
97
- where
98
- I : Source ,
99
- {
100
- if input. parameters_changed ( ) {
101
- return Arc :: new ( Span :: End ) ;
102
- }
103
-
104
- let channels = input. channels ( ) ;
105
- let rate = input. sample_rate ( ) ;
30
+ impl < I : Source > Buffered < I > {
31
+ pub ( crate ) fn new ( input : I ) -> Buffered < I > {
32
+ let total_duration = input. total_duration ( ) ;
33
+ let first_span = extract ( input) ;
106
34
107
- let mut data = Vec :: new ( ) ;
108
- loop {
109
- let Some ( element) = input. next ( ) else { break } ;
110
- data. push ( element) ;
111
- if input. parameters_changed ( ) {
112
- break ;
113
- }
114
- if data. len ( ) > 32768 {
115
- break ;
35
+ Buffered {
36
+ current_span : first_span,
37
+ position_in_span : 0 ,
38
+ total_duration,
39
+ parameters_changed : false ,
116
40
}
117
41
}
118
42
119
- if data. is_empty ( ) {
120
- return Arc :: new ( Span :: End ) ;
121
- }
122
-
123
- Arc :: new ( Span :: Data ( SpanData {
124
- data,
125
- channels,
126
- rate,
127
- next : Mutex :: new ( Arc :: new ( Span :: Input ( Mutex :: new ( Some ( input) ) ) ) ) ,
128
- } ) )
129
- }
130
-
131
- impl < I > Buffered < I >
132
- where
133
- I : Source ,
134
- {
135
43
/// Advances to the next span.
136
44
fn next_span ( & mut self ) {
137
45
let next_span = {
145
53
Span :: End => next_span_ptr. clone ( ) ,
146
54
Span :: Input ( input) => {
147
55
let input = input. lock ( ) . unwrap ( ) . take ( ) . unwrap ( ) ;
56
+ dbg ! ( ) ;
148
57
extract ( input)
149
58
}
150
59
} ;
169
78
let current_sample;
170
79
let advance_span;
171
80
172
- match & * self . current_span {
81
+ match dbg ! ( & * self . current_span) {
173
82
Span :: Data ( SpanData { data, .. } ) => {
174
83
current_sample = Some ( data[ self . position_in_span ] ) ;
175
84
self . position_in_span += 1 ;
@@ -185,39 +94,31 @@ where
185
94
} ;
186
95
187
96
if advance_span {
97
+ dbg ! ( ) ;
98
+ self . parameters_changed = true ;
188
99
self . next_span ( ) ;
100
+ } else {
101
+ self . parameters_changed = false ;
189
102
}
190
103
191
104
current_sample
192
105
}
193
-
194
- #[ inline]
195
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
196
- // TODO:
197
- ( 0 , None )
198
- }
199
106
}
200
107
201
- // TODO: implement exactsize iterator when size_hint is done
202
-
203
108
impl < I > Source for Buffered < I >
204
109
where
205
110
I : Source ,
206
111
{
207
112
#[ inline]
208
113
fn parameters_changed ( & self ) -> bool {
209
- match & * self . current_span {
210
- Span :: Data ( _) => false ,
211
- Span :: End => true ,
212
- Span :: Input ( _) => unreachable ! ( ) ,
213
- }
114
+ self . parameters_changed
214
115
}
215
116
216
117
#[ inline]
217
118
fn channels ( & self ) -> ChannelCount {
218
119
match * self . current_span {
219
120
Span :: Data ( SpanData { channels, .. } ) => channels,
220
- Span :: End => 1 ,
121
+ Span :: End => 0 ,
221
122
Span :: Input ( _) => unreachable ! ( ) ,
222
123
}
223
124
}
@@ -226,7 +127,7 @@ where
226
127
fn sample_rate ( & self ) -> SampleRate {
227
128
match * self . current_span {
228
129
Span :: Data ( SpanData { rate, .. } ) => rate,
229
- Span :: End => 44100 ,
130
+ Span :: End => 0 ,
230
131
Span :: Input ( _) => unreachable ! ( ) ,
231
132
}
232
133
}
@@ -256,6 +157,105 @@ where
256
157
current_span : self . current_span . clone ( ) ,
257
158
position_in_span : self . position_in_span ,
258
159
total_duration : self . total_duration ,
160
+ parameters_changed : self . parameters_changed ,
161
+ }
162
+ }
163
+ }
164
+
165
+ enum Span < I >
166
+ where
167
+ I : Source ,
168
+ {
169
+ /// Data that has already been extracted from the iterator.
170
+ /// Also contains a pointer to the next span.
171
+ Data ( SpanData < I > ) ,
172
+
173
+ /// No more data.
174
+ End ,
175
+
176
+ /// Unextracted data. The `Option` should never be `None` and is only here for easier data
177
+ /// processing.
178
+ Input ( Mutex < Option < I > > ) ,
179
+ }
180
+
181
+ impl < I : Source > std:: fmt:: Debug for Span < I > {
182
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
183
+ match self {
184
+ Span :: Data ( _) => f. write_str ( "Span::Data" ) ,
185
+ Span :: End => f. write_str ( "Span::End" ) ,
186
+ Span :: Input ( _) => f. write_str ( "Span::Input" ) ,
259
187
}
260
188
}
261
189
}
190
+
191
+ struct SpanData < I >
192
+ where
193
+ I : Source ,
194
+ {
195
+ data : Vec < I :: Item > ,
196
+ channels : ChannelCount ,
197
+ rate : SampleRate ,
198
+ next : Mutex < Arc < Span < I > > > ,
199
+ }
200
+
201
+ impl < I > Drop for SpanData < I >
202
+ where
203
+ I : Source ,
204
+ {
205
+ fn drop ( & mut self ) {
206
+ // This is necessary to prevent stack overflows deallocating long chains of the mutually
207
+ // recursive `Span` and `SpanData` types. This iteratively traverses as much of the
208
+ // chain as needs to be deallocated, and repeatedly "pops" the head off the list. This
209
+ // solves the problem, as when the time comes to actually deallocate the `SpanData`,
210
+ // the `next` field will contain a `Span::End`, or an `Arc` with additional references,
211
+ // so the depth of recursive drops will be bounded.
212
+ while let Ok ( arc_next) = self . next . get_mut ( ) {
213
+ if let Some ( next_ref) = Arc :: get_mut ( arc_next) {
214
+ // This allows us to own the next Span.
215
+ let next = mem:: replace ( next_ref, Span :: End ) ;
216
+ if let Span :: Data ( next_data) = next {
217
+ // Swap the current SpanData with the next one, allowing the current one
218
+ // to go out of scope.
219
+ * self = next_data;
220
+ } else {
221
+ break ;
222
+ }
223
+ } else {
224
+ break ;
225
+ }
226
+ }
227
+ }
228
+ }
229
+
230
+ /// Builds a span from the input iterator.
231
+ fn extract < I > ( mut input : I ) -> Arc < Span < I > >
232
+ where
233
+ I : Source ,
234
+ {
235
+ let channels = input. channels ( ) ;
236
+ let rate = input. sample_rate ( ) ;
237
+
238
+ let mut data = Vec :: new ( ) ;
239
+ loop {
240
+ let Some ( sample) = input. next ( ) else { break } ;
241
+ data. push ( sample) ;
242
+ dbg ! ( sample) ;
243
+ if input. parameters_changed ( ) {
244
+ break ;
245
+ }
246
+ if data. len ( ) > 32768 . prev_multiple_of ( channels) {
247
+ break ;
248
+ }
249
+ }
250
+
251
+ if dbg ! ( data. is_empty( ) ) {
252
+ return Arc :: new ( Span :: End ) ;
253
+ }
254
+
255
+ Arc :: new ( Span :: Data ( SpanData {
256
+ data,
257
+ channels,
258
+ rate,
259
+ next : Mutex :: new ( Arc :: new ( Span :: Input ( Mutex :: new ( Some ( input) ) ) ) ) ,
260
+ } ) )
261
+ }
0 commit comments