mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2024-11-01 03:54:15 +00:00
Switch to upsteam cpal and avoid creating unnecessary threads
This commit is contained in:
parent
dba6789b0a
commit
b880fee8e7
|
@ -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
|
||||||
|
|
|
@ -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() =>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue