1
1
use projectm_rs:: core:: ProjectMHandle ;
2
2
use sdl2:: audio:: { AudioCallback , AudioDevice , AudioSpecDesired } ;
3
+ use std:: sync:: Arc ;
4
+ use std:: sync:: Mutex ;
3
5
4
6
use super :: config:: FrameRate ;
7
+ use super :: ProjectMWrapped ;
5
8
6
9
type AudioDeviceIndex = u32 ;
7
10
type SampleFormat = f32 ; // format of audio samples
@@ -17,11 +20,12 @@ pub struct Audio {
17
20
is_capturing : bool ,
18
21
frame_rate : Option < FrameRate > ,
19
22
capturing_device : Option < AudioDevice < AudioCaptureCallback > > ,
20
- projectm : ProjectMHandle ,
23
+ projectm : ProjectMWrapped ,
21
24
}
22
25
26
+ /// Wrapper around the audio subsystem to capture audio and pass it to projectM.
23
27
impl Audio {
24
- pub fn new ( sdl_context : & sdl2:: Sdl , projectm : ProjectMHandle ) -> Self {
28
+ pub fn new ( sdl_context : & sdl2:: Sdl , projectm : ProjectMWrapped ) -> Self {
25
29
let audio_subsystem = sdl_context. audio ( ) . unwrap ( ) ;
26
30
27
31
Self {
@@ -52,7 +56,8 @@ impl Audio {
52
56
}
53
57
}
54
58
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 ) {
56
61
self . stop_audio_capture ( ) ;
57
62
self . device_index = device_index;
58
63
self . begin_audio_capture ( ) ;
@@ -64,12 +69,14 @@ impl Audio {
64
69
. expect ( "could not get audio device" )
65
70
}
66
71
72
+ /// Select a new audio device and start capturing audio from it.
67
73
pub fn open_next_device ( & mut self ) {
68
74
let device_list = self . get_device_list ( ) ;
69
75
let current_device_index = self . device_index ;
70
76
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) ;
73
80
}
74
81
75
82
fn get_device_list ( & self ) -> Vec < AudioCaptureDevice > {
@@ -105,7 +112,8 @@ impl Audio {
105
112
samples : Some ( buffer_size) ,
106
113
} ;
107
114
108
- let audio_device = self
115
+ // open audio device for capture
116
+ let audio_device = match self
109
117
. audio_subsystem // sdl
110
118
. open_capture ( None , & desired_spec, |_spec| {
111
119
println ! (
@@ -118,14 +126,19 @@ impl Audio {
118
126
119
127
// return callback fn
120
128
AudioCaptureCallback {
121
- pm : self . projectm ,
129
+ pm : self . projectm . clone ( ) ,
122
130
// spec,
123
131
// buffer_size,
124
132
// buffer: vec![0; buffer_size as usize],
125
133
// position: 0,
126
134
}
127
- } )
128
- . unwrap ( ) ;
135
+ } ) {
136
+ Ok ( device) => device,
137
+ Err ( e) => {
138
+ println ! ( "Error opening audio device: {}" , e) ;
139
+ return ;
140
+ }
141
+ } ;
129
142
130
143
// take ownership of device
131
144
self . capturing_device = Some ( audio_device) ;
@@ -140,18 +153,21 @@ impl Audio {
140
153
println ! ( "Stopping audio capture for device {}" , current_device_name) ;
141
154
142
155
println ! (
143
- "current capture device: {:?}" ,
156
+ "Current capture device status : {:?}" ,
144
157
self . capturing_device. as_ref( ) . unwrap( ) . status( )
145
158
) ;
146
159
147
160
self . is_capturing = false ;
148
- // drop(self.capturing_device); // stop capturing
149
161
self . capturing_device = None ;
150
162
}
151
163
}
152
164
153
165
struct 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 > > ,
155
171
// spec: sdl2::audio::AudioSpec,
156
172
// buffer_size: SampleFormat,
157
173
// buffer: Vec<u8>,
@@ -166,7 +182,9 @@ impl AudioCallback for AudioCaptureCallback {
166
182
// we are receiving some chunk of audio data
167
183
// we need to pass it to projectm
168
184
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
+ }
171
189
}
172
190
}
0 commit comments