77//! precisely synchronised. 
88
99use  clap:: Parser ; 
10- use  cpal:: traits:: { DeviceTrait ,  HostTrait ,  StreamTrait } ; 
10+ use  cpal:: { 
11+     traits:: { DeviceTrait ,  HostTrait ,  StreamTrait } , 
12+     HostUnavailable , 
13+ } ; 
1114use  ringbuf:: { 
1215    traits:: { Consumer ,  Producer ,  Split } , 
1316    HeapRb , 
@@ -28,58 +31,57 @@ struct Opt {
2831     #[ arg( short,  long,  value_name = "DELAY_MS" ,  default_value_t = 150.0 ) ]  
2932    latency :  f32 , 
3033
31-     /// Use the JACK host 
32-      #[ cfg( all(  
33-         any(  
34-             target_os = "linux" ,  
35-             target_os = "dragonfly" ,  
36-             target_os = "freebsd" ,  
37-             target_os = "netbsd"  
38-         ) ,  
39-         feature = "jack"  
40-     ) ) ]  
41-     #[ arg( short,  long) ]  
42-     #[ allow( dead_code) ]  
34+     /// Use the JACK host. Requires `--features jack`. 
35+      #[ arg( long,  default_value_t = false ) ]  
4336    jack :  bool , 
37+ 
38+     /// Use the PulseAudio host. Requires `--features pulseaudio`. 
39+      #[ arg( long,  default_value_t = false ) ]  
40+     pulseaudio :  bool , 
4441} 
4542
4643fn  main ( )  -> anyhow:: Result < ( ) >  { 
4744    let  opt = Opt :: parse ( ) ; 
4845
49-     // Conditionally compile with jack if the feature is specified. 
50-     #[ cfg( all(  
51-         any(  
52-             target_os = "linux" ,  
53-             target_os = "dragonfly" ,  
54-             target_os = "freebsd" ,  
55-             target_os = "netbsd"  
56-         ) ,  
57-         feature = "jack"  
46+     // Jack/PulseAudio support must be enabled at compile time, and is 
47+     // only available on some platforms. 
48+     #[ allow( unused_mut,  unused_assignments) ]  
49+     let  mut  jack_host_id = Err ( HostUnavailable ) ; 
50+     #[ allow( unused_mut,  unused_assignments) ]  
51+     let  mut  pulseaudio_host_id = Err ( HostUnavailable ) ; 
52+ 
53+     #[ cfg( any(  
54+         target_os = "linux" ,  
55+         target_os = "dragonfly" ,  
56+         target_os = "freebsd" ,  
57+         target_os = "netbsd"  
5858    ) ) ]  
59+     { 
60+         #[ cfg( feature = "jack" ) ]  
61+         { 
62+             jack_host_id = Ok ( cpal:: HostId :: Jack ) ; 
63+         } 
64+ 
65+         #[ cfg( feature = "pulseaudio" ) ]  
66+         { 
67+             pulseaudio_host_id = Ok ( cpal:: HostId :: PulseAudio ) ; 
68+         } 
69+     } 
70+ 
5971    // Manually check for flags. Can be passed through cargo with -- e.g. 
6072    // cargo run --release --example beep --features jack -- --jack 
6173    let  host = if  opt. jack  { 
62-         cpal:: host_from_id ( cpal:: available_hosts ( ) 
63-             . into_iter ( ) 
64-             . find ( |id| * id == cpal:: HostId :: Jack ) 
65-             . expect ( 
66-                 "make sure --features jack is specified. only works on OSes where jack is available" , 
67-             ) ) . expect ( "jack host unavailable" ) 
74+         jack_host_id
75+             . and_then ( cpal:: host_from_id) 
76+             . expect ( "make sure `--features jack` is specified, and the platform is supported" ) 
77+     }  else  if  opt. pulseaudio  { 
78+         pulseaudio_host_id
79+             . and_then ( cpal:: host_from_id) 
80+             . expect ( "make sure `--features pulseaudio` is specified, and the platform is supported" ) 
6881    }  else  { 
6982        cpal:: default_host ( ) 
7083    } ; 
7184
72-     #[ cfg( any(  
73-         not( any(  
74-             target_os = "linux" ,  
75-             target_os = "dragonfly" ,  
76-             target_os = "freebsd" ,  
77-             target_os = "netbsd"  
78-         ) ) ,  
79-         not( feature = "jack" )  
80-     ) ) ]  
81-     let  host = cpal:: default_host ( ) ; 
82- 
8385    // Find devices. 
8486    let  input_device = if  opt. input_device  == "default"  { 
8587        host. default_input_device ( ) 
@@ -164,8 +166,8 @@ fn main() -> anyhow::Result<()> {
164166    output_stream. play ( ) ?; 
165167
166168    // Run for 3 seconds before closing. 
167-     println ! ( "Playing for 3  seconds... " ) ; 
168-     std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 3 ) ) ; 
169+     println ! ( "Playing for 10  seconds... " ) ; 
170+     std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 10 ) ) ; 
169171    drop ( input_stream) ; 
170172    drop ( output_stream) ; 
171173    println ! ( "Done!" ) ; 
0 commit comments