@@ -152,10 +152,15 @@ fn open_device(dev_name: &str, format: AudioFormat) -> Result<(PCM, usize), Alsa
152152
153153 pcm. sw_params ( & swp) . map_err ( AlsaError :: Pcm ) ?;
154154
155+ trace ! ( "Frames per Buffer: {:?}" , frames_per_buffer) ;
156+ trace ! ( "Frames per Period: {:?}" , frames_per_period) ;
157+
155158 // Let ALSA do the math for us.
156159 pcm. frames_to_bytes ( frames_per_period) as usize
157160 } ;
158161
162+ trace ! ( "Period Buffer size in bytes: {:?}" , bytes_per_period) ;
163+
159164 Ok ( ( pcm, bytes_per_period) )
160165}
161166
@@ -193,7 +198,22 @@ impl Sink for AlsaSink {
193198 match open_device ( & self . device , self . format ) {
194199 Ok ( ( pcm, bytes_per_period) ) => {
195200 self . pcm = Some ( pcm) ;
196- self . period_buffer = Vec :: with_capacity ( bytes_per_period) ;
201+ // If the capacity is greater than we want shrink it
202+ // to it's current len (which should be zero) before
203+ // setting the capacity with reserve_exact.
204+ if self . period_buffer . capacity ( ) > bytes_per_period {
205+ self . period_buffer . shrink_to_fit ( ) ;
206+ }
207+ // This does nothing if the capacity is already sufficient.
208+ // Len should always be zero, but for the sake of being thorough...
209+ self . period_buffer
210+ . reserve_exact ( bytes_per_period - self . period_buffer . len ( ) ) ;
211+
212+ // Should always match the "Period Buffer size in bytes: " trace! message.
213+ trace ! (
214+ "Period Buffer capacity: {:?}" ,
215+ self . period_buffer. capacity( )
216+ ) ;
197217 }
198218 Err ( e) => {
199219 return Err ( io:: Error :: new ( io:: ErrorKind :: Other , e) ) ;
@@ -205,20 +225,22 @@ impl Sink for AlsaSink {
205225 }
206226
207227 fn stop ( & mut self ) -> io:: Result < ( ) > {
208- {
209- // Write any leftover data in the period buffer
210- // before draining the actual buffer
211- self . write_bytes ( & [ ] ) ?;
212- let pcm = self . pcm . as_mut ( ) . ok_or_else ( || {
213- io:: Error :: new ( io:: ErrorKind :: Other , "Error stopping AlsaSink, PCM is None" )
214- } ) ?;
215- pcm. drain ( ) . map_err ( |e| {
216- io:: Error :: new (
217- io:: ErrorKind :: Other ,
218- format ! ( "Error stopping AlsaSink {}" , e) ,
219- )
220- } ) ?
221- }
228+ // Zero fill the remainder of the period buffer and
229+ // write any leftover data before draining the actual PCM buffer.
230+ self . period_buffer . resize ( self . period_buffer . capacity ( ) , 0 ) ;
231+ self . write_buf ( ) ?;
232+
233+ let pcm = self . pcm . as_mut ( ) . ok_or_else ( || {
234+ io:: Error :: new ( io:: ErrorKind :: Other , "Error stopping AlsaSink, PCM is None" )
235+ } ) ?;
236+
237+ pcm. drain ( ) . map_err ( |e| {
238+ io:: Error :: new (
239+ io:: ErrorKind :: Other ,
240+ format ! ( "Error stopping AlsaSink {}" , e) ,
241+ )
242+ } ) ?;
243+
222244 self . pcm = None ;
223245 Ok ( ( ) )
224246 }
@@ -228,22 +250,24 @@ impl Sink for AlsaSink {
228250
229251impl SinkAsBytes for AlsaSink {
230252 fn write_bytes ( & mut self , data : & [ u8 ] ) -> io:: Result < ( ) > {
231- let mut processed_data = 0 ;
232- while processed_data < data. len ( ) {
233- let data_to_buffer = min (
234- self . period_buffer . capacity ( ) - self . period_buffer . len ( ) ,
235- data. len ( ) - processed_data,
236- ) ;
253+ let mut start_index = 0 ;
254+ let data_len = data. len ( ) ;
255+ let capacity = self . period_buffer . capacity ( ) ;
256+ loop {
257+ let data_left = data_len - start_index;
258+ let space_left = capacity - self . period_buffer . len ( ) ;
259+ let data_to_buffer = min ( data_left, space_left) ;
260+ let end_index = start_index + data_to_buffer;
237261 self . period_buffer
238- . extend_from_slice ( & data[ processed_data..processed_data + data_to_buffer] ) ;
239- processed_data += data_to_buffer;
240- if self . period_buffer . len ( ) == self . period_buffer . capacity ( ) {
262+ . extend_from_slice ( & data[ start_index..end_index] ) ;
263+ if self . period_buffer . len ( ) == capacity {
241264 self . write_buf ( ) ?;
242- self . period_buffer . clear ( ) ;
243265 }
266+ if end_index == data_len {
267+ break Ok ( ( ) ) ;
268+ }
269+ start_index = end_index;
244270 }
245-
246- Ok ( ( ) )
247271 }
248272}
249273
@@ -276,6 +300,7 @@ impl AlsaSink {
276300 } ) ?
277301 }
278302
303+ self . period_buffer . clear ( ) ;
279304 Ok ( ( ) )
280305 }
281306}
0 commit comments