@@ -10,7 +10,7 @@ use std::process::exit;
1010use thiserror:: Error ;
1111
1212const MAX_BUFFER : Frames = ( SAMPLE_RATE / 2 ) as Frames ;
13- const MIN_BUFFER : Frames = ( SAMPLE_RATE / 10 ) as Frames ;
13+ const MIN_BUFFER : Frames = ( SAMPLE_RATE / 10 ) as Frames ; // TODO: this is likely no longer valid with variable sampling rates
1414const ZERO_FRAMES : Frames = 0 ;
1515
1616const MAX_PERIOD_DIVISOR : Frames = 4 ;
@@ -162,7 +162,7 @@ fn list_compatible_devices() -> SinkResult<()> {
162162 Ok ( ( ) )
163163}
164164
165- fn open_device ( dev_name : & str , format : AudioFormat ) -> SinkResult < ( PCM , usize ) > {
165+ fn open_device ( dev_name : & str , format : AudioFormat , sample_rate : u32 ) -> SinkResult < ( PCM , usize ) > {
166166 let pcm = PCM :: new ( dev_name, Direction :: Playback , false ) . map_err ( |e| AlsaError :: PcmSetUp {
167167 device : dev_name. to_string ( ) ,
168168 e,
@@ -187,10 +187,10 @@ fn open_device(dev_name: &str, format: AudioFormat) -> SinkResult<(PCM, usize)>
187187 e,
188188 } ) ?;
189189
190- hwp. set_rate ( SAMPLE_RATE , ValueOr :: Nearest ) . map_err ( |e| {
190+ hwp. set_rate ( sample_rate , ValueOr :: Nearest ) . map_err ( |e| {
191191 AlsaError :: UnsupportedSampleRate {
192192 device : dev_name. to_string ( ) ,
193- samplerate : SAMPLE_RATE ,
193+ samplerate : sample_rate ,
194194 e,
195195 }
196196 } ) ?;
@@ -416,18 +416,7 @@ impl Open for AlsaSink {
416416impl Sink for AlsaSink {
417417 fn start ( & mut self ) -> SinkResult < ( ) > {
418418 if self . pcm . is_none ( ) {
419- let ( pcm, bytes_per_period) = open_device ( & self . device , self . format ) ?;
420- self . pcm = Some ( pcm) ;
421-
422- if self . period_buffer . capacity ( ) != bytes_per_period {
423- self . period_buffer = Vec :: with_capacity ( bytes_per_period) ;
424- }
425-
426- // Should always match the "Period Buffer size in bytes: " trace! message.
427- trace ! (
428- "Period Buffer capacity: {:?}" ,
429- self . period_buffer. capacity( )
430- ) ;
419+ self . start_internal ( SAMPLE_RATE ) ?;
431420 }
432421
433422 Ok ( ( ) )
@@ -448,6 +437,13 @@ impl Sink for AlsaSink {
448437 Ok ( ( ) )
449438 }
450439
440+ fn update_sample_rate ( & mut self , new_sample_rate : u32 ) -> SinkResult < ( ) > {
441+ self . stop ( ) ?;
442+ self . start_internal ( new_sample_rate) ?;
443+
444+ Ok ( ( ) )
445+ }
446+
451447 sink_as_bytes ! ( ) ;
452448}
453449
@@ -483,6 +479,23 @@ impl SinkAsBytes for AlsaSink {
483479impl AlsaSink {
484480 pub const NAME : & ' static str = "alsa" ;
485481
482+ fn start_internal ( & mut self , sample_rate : u32 ) -> SinkResult < ( ) > {
483+ let ( pcm, bytes_per_period) = open_device ( & self . device , self . format , sample_rate) ?;
484+ self . pcm = Some ( pcm) ;
485+
486+ if self . period_buffer . capacity ( ) != bytes_per_period {
487+ self . period_buffer = Vec :: with_capacity ( bytes_per_period) ;
488+ }
489+
490+ // Should always match the "Period Buffer size in bytes: " trace! message.
491+ trace ! (
492+ "Period Buffer capacity: {:?}" ,
493+ self . period_buffer. capacity( )
494+ ) ;
495+
496+ Ok ( ( ) )
497+ }
498+
486499 fn write_buf ( & mut self ) -> SinkResult < ( ) > {
487500 if self . pcm . is_some ( ) {
488501 let write_result = {
0 commit comments