Skip to content

Commit df70604

Browse files
committed
'a
1 parent a61e50f commit df70604

File tree

7 files changed

+151
-36
lines changed

7 files changed

+151
-36
lines changed

src/app.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ pub mod main_loop;
77
pub mod playlist;
88
pub mod video;
99

10-
pub struct App {
10+
pub struct App<'a> {
1111
pm: projectm_handle,
1212
playlist: projectm_rs::playlist::Playlist,
1313
sdl_context: sdl2::Sdl,
1414
gl_context: sdl2::video::GLContext,
1515
window: sdl2::video::Window,
1616
config: config::Config,
17-
audio: audio::Audio,
17+
audio: audio::Audio<'a>,
1818
}
1919

2020
pub fn default_config() -> config::Config {
2121
config::Config::default()
2222
}
2323

24-
impl App {
24+
impl App<'_> {
2525
pub fn new(config: Option<crate::app::config::Config>) -> Self {
2626
// setup sdl
2727
let sdl_context = sdl2::init().unwrap();
@@ -82,8 +82,13 @@ impl App {
8282
}
8383
}
8484

85-
pub fn init(&mut self) {
85+
pub fn init(&self) {
8686
// load config
8787
self.load_config(&self.config);
88+
89+
// initialize audio
90+
self.audio.list_devices();
91+
// self.audio
92+
// .begin_audio_capture(projectm::get_frame_rate(self.pm));
8893
}
8994
}

src/app/audio.rs

+126-26
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,91 @@
11
use sdl2::audio::{AudioCallback, AudioDevice, AudioSpecDesired};
22

3-
pub struct Audio {
3+
type AudioDeviceIndex = u32;
4+
5+
pub struct AudioCaptureDevice {
6+
name: String,
7+
index: AudioDeviceIndex,
8+
}
9+
10+
pub struct Audio<'a> {
411
audio_subsystem: sdl2::AudioSubsystem,
5-
audio_device_index: u8,
6-
// device_list: Vec<sdl2::audio::AudioDevice>,
12+
audio_device_index: AudioDeviceIndex, // device_list: Option<Vec<sdl2::audio::AudioDevice>>,
13+
frame_rate: Option<u32>,
14+
capturing_device: Option<AudioDevice<AudioCaptureCallback>>,
715
}
816

9-
impl Audio {
17+
impl Audio<'_> {
1018
pub fn new(sdl_context: &sdl2::Sdl) -> Self {
1119
let audio_subsystem = sdl_context.audio().unwrap();
1220

1321
Self {
1422
audio_subsystem,
1523
audio_device_index: 0,
24+
frame_rate: None,
25+
capturing_device: None,
1626
}
1727
}
1828

19-
// pub fn get_device_list(mut self) -> Vec<sdl2::audio::AudioDevice> {
20-
// let audio_subsystem = sdl_context.audio().unwrap();
21-
// let device_list = audio_subsystem
22-
// .capture_devices()
23-
// .expect("could not get audio device list");
24-
// for (i, device) in device_list.enumerate() {
25-
// println!("{}: {}", i, device.name());
26-
// }
27-
// }
29+
pub fn init(&mut self, frame_rate: u32) {
30+
self.frame_rate = frame_rate.into();
31+
self.begin_audio_capture();
32+
}
33+
34+
pub fn list_devices(&self) {
35+
self.get_device_list();
36+
}
37+
38+
pub fn set_device(&mut self, device_index: AudioDeviceIndex) {
39+
self.stop_audio_capture();
40+
self.audio_device_index = device_index;
41+
self.begin_audio_capture();
42+
}
43+
44+
pub fn get_current_device_name(&self) -> String {
45+
let device_name = self
46+
.audio_subsystem
47+
.audio_capture_device_name(self.audio_device_index)
48+
.expect("could not get audio device");
49+
device_name
50+
}
51+
52+
pub fn open_next_device(&mut self) {
53+
let device_list = self.get_device_list();
54+
let current_device_index = self.audio_device_index;
55+
56+
let next_device_index = current_device_index + 1 % device_list.len() as AudioDeviceIndex;
57+
self.set_device(next_device_index);
58+
}
59+
60+
fn get_device_list(&self) -> Vec<AudioCaptureDevice> {
61+
let audio_subsystem = &self.audio_subsystem;
62+
63+
let num_devices = audio_subsystem
64+
.num_audio_capture_devices()
65+
.expect("could not get number of audio devices");
66+
67+
let mut device_list: Vec<AudioCaptureDevice> = vec![];
2868

29-
pub fn begin_audio_capture(self, frame_rate: u32) {
69+
for i in 0..num_devices {
70+
let device_name = audio_subsystem
71+
.audio_capture_device_name(i)
72+
.expect("could not get audio device");
73+
println!("{}: {}", i, device_name);
74+
75+
device_list.push(AudioCaptureDevice {
76+
name: device_name,
77+
index: i,
78+
});
79+
}
80+
81+
device_list
82+
}
83+
84+
pub fn begin_audio_capture<'a>(&'a mut self) {
3085
let sample_rate: u32 = 44100;
86+
let frame_rate: u32 = self
87+
.frame_rate
88+
.expect("frame rate not set, call init() pls");
3189

3290
// should be enough for 1 frame
3391
let buffer_size = (sample_rate / frame_rate) as u16;
@@ -38,17 +96,59 @@ impl Audio {
3896
samples: Some(buffer_size),
3997
};
4098

41-
// let audio_device = self
42-
// .audio_subsystem
43-
// .open_capture(None, &desired_spec, |spec| {
44-
// // initialize the audio callback
45-
// AudioCallback {
46-
// spec,
47-
// buffer_size,
48-
// buffer: vec![0; buffer_size as usize],
49-
// position: 0,
50-
// }
51-
// })
52-
// .unwrap();
99+
// let mut audio_device: &'a AudioDevice<AudioCaptureCallback> = &self
100+
let mut audio_device = self
101+
.audio_subsystem // sdl
102+
.open_capture(None, &desired_spec, |spec| {
103+
println!(
104+
"Beginning audio capture for device {}",
105+
self.get_current_device_name()
106+
);
107+
// return callback fn
108+
AudioCaptureCallback {
109+
spec,
110+
buffer_size,
111+
buffer: vec![0; buffer_size as usize],
112+
position: 0,
113+
}
114+
})
115+
.unwrap();
116+
117+
self.capturing_device = Some(audio_device);
118+
}
119+
120+
pub fn stop_audio_capture(&self) {
121+
let current_device_name = self.get_current_device_name();
122+
println!("Stopping audio capture for device {}", current_device_name);
123+
124+
let current_device = self.audio_device_index;
125+
drop(self.capturing_device);
126+
}
127+
}
128+
129+
struct AudioCaptureCallback {
130+
spec: sdl2::audio::AudioSpec,
131+
buffer_size: u16,
132+
buffer: Vec<u8>,
133+
position: usize,
134+
}
135+
136+
impl AudioCallback for AudioCaptureCallback {
137+
type Channel = i16;
138+
139+
fn callback(&mut self, out: &mut [i16]) {
140+
// let buffer = &mut self.buffer;
141+
// let position = &mut self.position;
142+
// let buffer_size = self.buffer_size;
143+
144+
// let mut i = 0;
145+
// while i < out.len() {
146+
// out[i] = buffer[*position];
147+
// *position += 1;
148+
// if *position >= buffer_size as usize {
149+
// *position = 0;
150+
// }
151+
// i += 1;
152+
// }
53153
}
54154
}

src/app/config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ impl Default for Config {
1616
}
1717
}
1818

19-
impl App {
20-
pub fn load_config(&mut self, config: &Config) {
19+
impl App<'_> {
20+
pub fn load_config(&self, config: &Config) {
2121
// load presets if provided
2222
if let Some(preset_path) = &config.preset_path {
2323
self.add_preset_path(&preset_path);

src/app/main_loop.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use sdl2::keyboard::Keycode;
55
use crate::app::App;
66
use crate::dummy_audio;
77

8-
impl App {
8+
impl App<'_> {
99
pub fn main_loop(&mut self) {
1010
let config = &self.config;
1111
let frame_rate = config.frame_rate.unwrap();
@@ -76,6 +76,15 @@ impl App {
7676
self.toggle_fullscreen();
7777
}
7878

79+
// Next audio capture input device (ctl-I, cmd-I)
80+
Event::KeyUp {
81+
keycode: Some(Keycode::I),
82+
keymod: sdl2::keyboard::Mod::LCTRLMOD,
83+
..
84+
} => {
85+
self.audio.open_next_device();
86+
}
87+
7988
// default
8089
_ => {}
8190
}

src/app/playlist.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::app::App;
22

3-
impl App {
3+
impl App<'_> {
44
/// Add presets to the playlist recursively skipping duplicates.
5-
pub fn add_preset_path(&mut self, preset_path: &str) {
5+
pub fn add_preset_path(&self, preset_path: &str) {
66
self.playlist.add_path(preset_path, true);
77
println!("added preset path: {}", preset_path);
88
println!("playlist size: {}", self.playlist.len());

src/app/video.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::app::App;
22

3-
impl App {
3+
impl App<'_> {
44
pub fn toggle_fullscreen(&mut self) {
55
let is_fullscreen = self.window.fullscreen_state();
66
self.window

src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ fn main() -> Result<(), String> {
77
// config.preset_path = Some("/usr/local/share/projectM/presets".to_string());
88

99
let mut app = app::App::new(Some(config));
10+
app.init();
1011

1112
app.main_loop();
1213

0 commit comments

Comments
 (0)