11use projectm_rs:: core:: ProjectMHandle ;
22use sdl2:: audio:: { AudioCallback , AudioDevice , AudioSpecDesired } ;
3+ use std:: sync:: Arc ;
4+ use std:: sync:: Mutex ;
35
46use super :: config:: FrameRate ;
7+ use super :: ProjectMWrapped ;
58
69type AudioDeviceIndex = u32 ;
710type SampleFormat = f32 ; // format of audio samples
@@ -17,11 +20,12 @@ pub struct Audio {
1720 is_capturing : bool ,
1821 frame_rate : Option < FrameRate > ,
1922 capturing_device : Option < AudioDevice < AudioCaptureCallback > > ,
20- projectm : ProjectMHandle ,
23+ projectm : ProjectMWrapped ,
2124}
2225
26+ /// Wrapper around the audio subsystem to capture audio and pass it to projectM.
2327impl Audio {
24- pub fn new ( sdl_context : & sdl2:: Sdl , projectm : ProjectMHandle ) -> Self {
28+ pub fn new ( sdl_context : & sdl2:: Sdl , projectm : ProjectMWrapped ) -> Self {
2529 let audio_subsystem = sdl_context. audio ( ) . unwrap ( ) ;
2630
2731 Self {
@@ -52,7 +56,8 @@ impl Audio {
5256 }
5357 }
5458
55- pub fn set_device ( & mut self , device_index : AudioDeviceIndex ) {
59+ /// Start capturing audio from device_index.
60+ pub fn capture_device ( & mut self , device_index : AudioDeviceIndex ) {
5661 self . stop_audio_capture ( ) ;
5762 self . device_index = device_index;
5863 self . begin_audio_capture ( ) ;
@@ -64,12 +69,14 @@ impl Audio {
6469 . expect ( "could not get audio device" )
6570 }
6671
72+ /// Select a new audio device and start capturing audio from it.
6773 pub fn open_next_device ( & mut self ) {
6874 let device_list = self . get_device_list ( ) ;
6975 let current_device_index = self . device_index ;
7076
71- let next_device_index = current_device_index + 1 % device_list. len ( ) as AudioDeviceIndex ;
72- self . set_device ( next_device_index) ;
77+ let next_device_index = ( current_device_index + 1 ) % device_list. len ( ) as AudioDeviceIndex ;
78+ println ! ( "Opening next device: {}" , next_device_index) ;
79+ self . capture_device ( next_device_index) ;
7380 }
7481
7582 fn get_device_list ( & self ) -> Vec < AudioCaptureDevice > {
@@ -105,7 +112,8 @@ impl Audio {
105112 samples : Some ( buffer_size) ,
106113 } ;
107114
108- let audio_device = self
115+ // open audio device for capture
116+ let audio_device = match self
109117 . audio_subsystem // sdl
110118 . open_capture ( None , & desired_spec, |_spec| {
111119 println ! (
@@ -118,14 +126,19 @@ impl Audio {
118126
119127 // return callback fn
120128 AudioCaptureCallback {
121- pm : self . projectm ,
129+ pm : self . projectm . clone ( ) ,
122130 // spec,
123131 // buffer_size,
124132 // buffer: vec![0; buffer_size as usize],
125133 // position: 0,
126134 }
127- } )
128- . unwrap ( ) ;
135+ } ) {
136+ Ok ( device) => device,
137+ Err ( e) => {
138+ println ! ( "Error opening audio device: {}" , e) ;
139+ return ;
140+ }
141+ } ;
129142
130143 // take ownership of device
131144 self . capturing_device = Some ( audio_device) ;
@@ -140,18 +153,21 @@ impl Audio {
140153 println ! ( "Stopping audio capture for device {}" , current_device_name) ;
141154
142155 println ! (
143- "current capture device: {:?}" ,
156+ "Current capture device status : {:?}" ,
144157 self . capturing_device. as_ref( ) . unwrap( ) . status( )
145158 ) ;
146159
147160 self . is_capturing = false ;
148- // drop(self.capturing_device); // stop capturing
149161 self . capturing_device = None ;
150162 }
151163}
152164
153165struct AudioCaptureCallback {
154- pm : ProjectMHandle ,
166+ // audio_tx: mpsc::Sender<Vec<SampleFormat>>,
167+
168+ // we need to keep a reference to the projectm instance to
169+ // add the audio data to it
170+ pm : Arc < Mutex < ProjectMHandle > > ,
155171 // spec: sdl2::audio::AudioSpec,
156172 // buffer_size: SampleFormat,
157173 // buffer: Vec<u8>,
@@ -166,7 +182,9 @@ impl AudioCallback for AudioCaptureCallback {
166182 // we are receiving some chunk of audio data
167183 // we need to pass it to projectm
168184 fn callback ( & mut self , out : & mut [ SampleFormat ] ) {
169- let pm = self . pm ;
170- projectm_rs:: core:: Projectm :: pcm_add_float ( pm, out. to_vec ( ) , 2 ) ;
185+ {
186+ let pm = * self . pm . lock ( ) . unwrap ( ) ;
187+ projectm_rs:: core:: Projectm :: pcm_add_float ( pm, out. to_vec ( ) , 2 ) ;
188+ }
171189 }
172190}
0 commit comments