@@ -11,7 +11,7 @@ mod imp {
1111 use clap:: Parser ;
1212 use cpal:: duplex:: DuplexStreamConfig ;
1313 use cpal:: traits:: { DeviceTrait , HostTrait , StreamTrait } ;
14- use cpal:: BufferSize ;
14+ use cpal:: { BufferSize , ChannelCount , FrameCount , Sample , SampleRate } ;
1515
1616 #[ derive( Parser , Debug ) ]
1717 #[ command( version, about = "CPAL duplex feedback example" , long_about = None ) ]
@@ -22,33 +22,35 @@ mod imp {
2222
2323 /// Number of input channels
2424 #[ arg( long, value_name = "CHANNELS" , default_value_t = 2 ) ]
25- input_channels : u16 ,
25+ input_channels : ChannelCount ,
2626
2727 /// Number of output channels
2828 #[ arg( long, value_name = "CHANNELS" , default_value_t = 2 ) ]
29- output_channels : u16 ,
29+ output_channels : ChannelCount ,
3030
3131 /// Sample rate in Hz
3232 #[ arg( short, long, value_name = "RATE" , default_value_t = 48000 ) ]
33- sample_rate : u32 ,
33+ sample_rate : SampleRate ,
3434
35- /// Buffer size in frames
36- #[ arg( short, long, value_name = "FRAMES" , default_value_t = 512 ) ]
37- buffer_size : u32 ,
35+ /// Buffer size in frames (omit for device default)
36+ #[ arg( short, long, value_name = "FRAMES" ) ]
37+ buffer_size : Option < FrameCount > ,
3838 }
3939
4040 pub fn run ( ) -> anyhow:: Result < ( ) > {
4141 let opt = Opt :: parse ( ) ;
4242 let host = cpal:: default_host ( ) ;
4343
4444 // Find the device by device ID or use default
45- let device = if let Some ( device_id_str) = opt. device {
46- let device_id = device_id_str. parse ( ) . expect ( "failed to parse device id" ) ;
47- host. device_by_id ( & device_id)
48- . unwrap_or_else ( || panic ! ( "failed to find device with id: {}" , device_id_str) )
49- } else {
50- host. default_output_device ( )
51- . expect ( "no default output device" )
45+ let device = match opt. device {
46+ Some ( device_id_str) => {
47+ let device_id = device_id_str. parse ( ) . expect ( "failed to parse device id" ) ;
48+ host. device_by_id ( & device_id)
49+ . expect ( & format ! ( "failed to find device with id: {}" , device_id_str) )
50+ }
51+ None => host
52+ . default_output_device ( )
53+ . expect ( "no default output device" ) ,
5254 } ;
5355
5456 println ! ( "Using device: \" {}\" " , device. description( ) ?. name( ) ) ;
@@ -58,15 +60,18 @@ mod imp {
5860 input_channels : opt. input_channels ,
5961 output_channels : opt. output_channels ,
6062 sample_rate : opt. sample_rate ,
61- buffer_size : BufferSize :: Fixed ( opt. buffer_size ) ,
63+ buffer_size : opt
64+ . buffer_size
65+ . map ( |s| BufferSize :: Fixed ( s) )
66+ . unwrap_or ( BufferSize :: Default ) ,
6267 } ;
6368
6469 println ! ( "Building duplex stream with config: {config:?}" ) ;
6570
6671 let stream = device. build_duplex_stream :: < f32 , _ , _ > (
6772 & config,
6873 move |input, output, _info| {
69- output. fill ( 0.0 ) ;
74+ output. fill ( Sample :: EQUILIBRIUM ) ;
7075 let copy_len = input. len ( ) . min ( output. len ( ) ) ;
7176 output[ ..copy_len] . copy_from_slice ( & input[ ..copy_len] ) ;
7277 } ,
@@ -76,7 +81,7 @@ mod imp {
7681
7782 println ! ( "Successfully built duplex stream." ) ;
7883 println ! (
79- "Input: {} channels, Output: {} channels, Sample rate: {} Hz, Buffer size: {} frames" ,
84+ "Input: {} channels, Output: {} channels, Sample rate: {} Hz, Buffer size: {:? } frames" ,
8085 opt. input_channels, opt. output_channels, opt. sample_rate, opt. buffer_size
8186 ) ;
8287
@@ -86,7 +91,6 @@ mod imp {
8691 println ! ( "Playing for 10 seconds... (speak into your microphone)" ) ;
8792 std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 10 ) ) ;
8893
89- drop ( stream) ;
9094 println ! ( "Done!" ) ;
9195 Ok ( ( ) )
9296 }
@@ -98,7 +102,6 @@ fn main() {
98102
99103 #[ cfg( not( target_os = "macos" ) ) ]
100104 {
101- eprintln ! ( "Duplex streams are currently only supported on macOS." ) ;
102- eprintln ! ( "Windows (WASAPI) and Linux (ALSA) support is planned." ) ;
105+ eprintln ! ( "Duplex streams are not supported on this platform." ) ;
103106 }
104107}
0 commit comments