1
0
Fork 0
mirror of https://github.com/doukutsu-rs/doukutsu-rs synced 2024-11-22 13:42:47 +00:00

Switch to upsteam cpal and avoid creating unnecessary threads

This commit is contained in:
Alula 2022-01-22 05:08:53 +01:00
parent dba6789b0a
commit b880fee8e7
No known key found for this signature in database
GPG key ID: 3E00485503A1D8BA
4 changed files with 44 additions and 40 deletions

View file

@ -46,7 +46,6 @@ exe = []
android = [] android = []
[dependencies] [dependencies]
#cpal = { path = "./3rdparty/cpal" }
#glutin = { path = "./3rdparty/glutin/glutin", optional = true } #glutin = { path = "./3rdparty/glutin/glutin", optional = true }
#lua-ffi = { path = "./3rdparty/luajit-rs", optional = true } #lua-ffi = { path = "./3rdparty/luajit-rs", optional = true }
#winit = { path = "./3rdparty/winit", optional = true, default_features = false, features = ["x11"] } #winit = { path = "./3rdparty/winit", optional = true, default_features = false, features = ["x11"] }
@ -54,7 +53,7 @@ bitvec = "0.20"
byteorder = "1.4" byteorder = "1.4"
case_insensitive_hashmap = "1.0.0" case_insensitive_hashmap = "1.0.0"
chrono = "0.4" chrono = "0.4"
cpal = { git = "https://github.com/doukutsu-rs/cpal.git", rev = "4218ff23242834d36bcdcc0c2e3883985c15b5e0" } cpal = "0.13"
directories = "3" directories = "3"
downcast = "0.11" downcast = "0.11"
funty = "=1.1.0" # https://github.com/bitvecto-rs/bitvec/issues/105 funty = "=1.1.0" # https://github.com/bitvecto-rs/bitvec/issues/105

View file

@ -176,6 +176,8 @@ impl BackendEventLoop for GlutinEventLoop {
request_android_redraw(); request_android_redraw();
} }
} }
state_ref.sound_manager.resume();
} }
Event::Suspended => { Event::Suspended => {
{ {
@ -187,6 +189,8 @@ impl BackendEventLoop for GlutinEventLoop {
unsafe { unsafe {
window.surface_destroyed(); window.surface_destroyed();
} }
state_ref.sound_manager.pause();
} }
Event::WindowEvent { event: WindowEvent::Resized(size), window_id } Event::WindowEvent { event: WindowEvent::Resized(size), window_id }
if window_id == window.window().id() => if window_id == window.window().id() =>

View file

@ -168,11 +168,14 @@ impl BackendEventLoop for SDL2EventLoop {
*mutex = false; *mutex = false;
} }
state.sound_manager.resume();
game.loops = 0; game.loops = 0;
} }
WindowEvent::FocusLost | WindowEvent::Hidden => { WindowEvent::FocusLost | WindowEvent::Hidden => {
let mut mutex = GAME_SUSPENDED.lock().unwrap(); let mut mutex = GAME_SUSPENDED.lock().unwrap();
*mutex = true; *mutex = true;
state.sound_manager.pause();
} }
WindowEvent::SizeChanged(width, height) => { WindowEvent::SizeChanged(width, height) => {
ctx.screen_size = (width.max(1) as f32, height.max(1) as f32); ctx.screen_size = (width.max(1) as f32, height.max(1) as f32);
@ -267,7 +270,6 @@ impl BackendEventLoop for SDL2EventLoop {
refs.video.gl_get_proc_address(name) as *const _ refs.video.gl_get_proc_address(name) as *const _
}; };
// log::info!("gl proc {} -> {:?}", name, result);
*user_data = Rc::into_raw(refs) as *mut c_void; *user_data = Rc::into_raw(refs) as *mut c_void;
result result

View file

@ -41,6 +41,7 @@ pub struct SoundManager {
prev_song_id: usize, prev_song_id: usize,
current_song_id: usize, current_song_id: usize,
no_audio: bool, no_audio: bool,
stream: Option<cpal::Stream>,
} }
enum SongFormat { enum SongFormat {
@ -67,7 +68,13 @@ impl SoundManager {
if ctx.headless { if ctx.headless {
log::info!("Running in headless mode, skipping initialization."); log::info!("Running in headless mode, skipping initialization.");
return Ok(SoundManager { tx: tx.clone(), prev_song_id: 0, current_song_id: 0, no_audio: true }); return Ok(SoundManager {
tx: tx.clone(),
prev_song_id: 0,
current_song_id: 0,
no_audio: true,
stream: None,
});
} }
let host = cpal::default_host(); let host = cpal::default_host();
@ -76,18 +83,29 @@ impl SoundManager {
let config = device.default_output_config()?; let config = device.default_output_config()?;
let bnk = wave_bank::SoundBank::load_from(filesystem::open(ctx, "/builtin/organya-wavetable-doukutsu.bin")?)?; let bnk = wave_bank::SoundBank::load_from(filesystem::open(ctx, "/builtin/organya-wavetable-doukutsu.bin")?)?;
let res = match config.sample_format() {
cpal::SampleFormat::F32 => run::<f32>(rx, bnk, device, config.into()),
cpal::SampleFormat::I16 => run::<i16>(rx, bnk, device, config.into()),
cpal::SampleFormat::U16 => run::<u16>(rx, bnk, device, config.into()),
};
std::thread::spawn(move || { if let Err(res) = &res {
if let Err(err) = match config.sample_format() { log::error!("Error initializing audio: {}", res);
cpal::SampleFormat::F32 => run::<f32>(rx, bnk, &device, &config.into()),
cpal::SampleFormat::I16 => run::<i16>(rx, bnk, &device, &config.into()),
cpal::SampleFormat::U16 => run::<u16>(rx, bnk, &device, &config.into()),
} {
log::error!("Something went wrong in audio thread: {}", err);
} }
});
Ok(SoundManager { tx: tx.clone(), prev_song_id: 0, current_song_id: 0, no_audio: false }) Ok(SoundManager { tx: tx.clone(), prev_song_id: 0, current_song_id: 0, no_audio: false, stream: res.ok() })
}
pub fn pause(&mut self) {
if let Some(stream) = &mut self.stream {
let _ = stream.pause();
}
}
pub fn resume(&mut self) {
if let Some(stream) = &mut self.stream {
let _ = stream.play();
}
} }
pub fn play_sfx(&self, id: u8) { pub fn play_sfx(&self, id: u8) {
@ -367,7 +385,7 @@ impl SoundManager {
} }
} }
enum PlaybackMessage { pub(in crate::sound) enum PlaybackMessage {
Stop, Stop,
PlayOrganyaSong(Box<Song>), PlayOrganyaSong(Box<Song>),
#[cfg(feature = "ogg-playback")] #[cfg(feature = "ogg-playback")]
@ -408,9 +426,9 @@ impl Default for PlaybackStateType {
fn run<T>( fn run<T>(
rx: Receiver<PlaybackMessage>, rx: Receiver<PlaybackMessage>,
bank: SoundBank, bank: SoundBank,
device: &cpal::Device, device: cpal::Device,
config: &cpal::StreamConfig, config: cpal::StreamConfig,
) -> GameResult ) -> GameResult<cpal::Stream>
where where
T: cpal::Sample, T: cpal::Sample,
{ {
@ -444,7 +462,7 @@ where
let err_fn = |err| eprintln!("an error occurred on stream: {}", err); let err_fn = |err| eprintln!("an error occurred on stream: {}", err);
let stream = device.build_output_stream( let stream = device.build_output_stream(
config, &config,
move |data: &mut [T], _: &cpal::OutputCallbackInfo| { move |data: &mut [T], _: &cpal::OutputCallbackInfo| {
loop { loop {
match rx.try_recv() { match rx.try_recv() {
@ -456,7 +474,7 @@ where
org_engine.start_song(*song, &bank); org_engine.start_song(*song, &bank);
for i in &mut bgm_buf[0..samples] { for i in &mut bgm_buf[0..samples] {
*i = 0x8080 *i = 0x8000
} }
samples = org_engine.render_to(&mut bgm_buf); samples = org_engine.render_to(&mut bgm_buf);
bgm_index = 0; bgm_index = 0;
@ -651,24 +669,5 @@ where
stream.play()?; stream.play()?;
let mut saved_state = true; Ok(stream)
loop {
std::thread::sleep(Duration::from_millis(10));
{
let mutex = crate::GAME_SUSPENDED.lock().unwrap();
let state = *mutex;
if saved_state != state {
saved_state = state;
if state {
if let Err(e) = stream.pause() {
log::error!("Failed to pause the stream: {:?}", e);
}
} else if let Err(e) = stream.play() {
log::error!("Failed to unpause the stream: {:?}", e);
}
}
}
}
} }