move audio system to wlx-common, compress audio data, sample player

This commit is contained in:
Aleksander
2026-01-02 00:19:17 +01:00
parent b6c16dff18
commit 383bf3b11f
17 changed files with 132 additions and 116 deletions

View File

@@ -325,10 +325,9 @@ impl KeyboardState {
}
}
const KEY_AUDIO_WAV: &[u8] = include_bytes!("../../res/421581.wav");
fn play_key_click(app: &mut AppState) {
app.audio_provider.play(KEY_AUDIO_WAV);
app.audio_sample_player
.play_sample(&mut app.audio_system, "key_click");
}
struct KeyState {

View File

@@ -67,7 +67,8 @@ impl Toast {
let destroy_at = instant.add(std::time::Duration::from_secs_f32(self.timeout));
if self.sound && app.session.config.notifications_sound_enabled {
app.audio_provider.play(app.toast_sound);
app.audio_sample_player
.play_sample(&mut app.audio_system, "toast");
}
// drop any toast that was created before us.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -7,6 +7,7 @@ use wgui::{
renderer_vk::context::SharedContext as WSharedContext,
};
use wlx_common::{
audio,
config::GeneralConfig,
overlays::{ToastDisplayMethod, ToastTopic},
};
@@ -26,7 +27,7 @@ use crate::{
graphics::WGfxExtras,
gui,
ipc::{event_queue::SyncEventQueue, ipc_server, signal::WayVRSignal},
subsystem::{audio::AudioOutput, dbus::DbusConnector, input::HidWrapper},
subsystem::{dbus::DbusConnector, input::HidWrapper},
};
pub struct AppState {
@@ -36,7 +37,9 @@ pub struct AppState {
pub gfx: Arc<WGfx>,
pub gfx_extras: WGfxExtras,
pub hid_provider: HidWrapper,
pub audio_provider: AudioOutput,
pub audio_system: audio::AudioSystem,
pub audio_sample_player: audio::SamplePlayer,
pub wgui_shared: WSharedContext,
@@ -44,7 +47,6 @@ pub struct AppState {
pub screens: SmallVec<[ScreenMeta; 8]>,
pub anchor: Affine3A,
pub anchor_grabbed: bool,
pub toast_sound: &'static [u8],
pub wgui_globals: WguiGlobals,
@@ -93,14 +95,20 @@ impl AppState {
#[cfg(feature = "osc")]
let osc_sender = crate::subsystem::osc::OscSender::new(session.config.osc_out_port).ok();
let toast_sound_wav = Self::try_load_bytes(
&session.config.notification_sound,
include_bytes!("res/557297.wav"),
);
let wgui_shared = WSharedContext::new(gfx.clone())?;
let theme = session.config.theme_path.clone();
let mut audio_sample_player = audio::SamplePlayer::new();
audio_sample_player.register_sample(
"key_click",
audio::AudioSample::from_mp3(include_bytes!("res/key_click.mp3"))?,
);
audio_sample_player.register_sample(
"toast",
audio::AudioSample::from_mp3(include_bytes!("res/toast.mp3"))?,
);
let mut defaults = wgui::globals::Defaults::default();
{
@@ -131,13 +139,13 @@ impl AppState {
gfx,
gfx_extras,
hid_provider,
audio_provider: AudioOutput::new(),
audio_system: audio::AudioSystem::new(),
audio_sample_player,
wgui_shared,
input_state: InputState::new(),
screens: smallvec![],
anchor: Affine3A::IDENTITY,
anchor_grabbed: false,
toast_sound: toast_sound_wav,
wgui_globals: WguiGlobals::new(
Box::new(gui::asset::GuiAsset {}),
defaults,
@@ -156,29 +164,6 @@ impl AppState {
wvr_server: wayvr_server,
})
}
pub fn try_load_bytes(path: &str, fallback_data: &'static [u8]) -> &'static [u8] {
if path.is_empty() {
return fallback_data;
}
let real_path = config_io::get_config_root().join(path);
if std::fs::File::open(real_path.clone()).is_err() {
log::warn!("Could not open file at: {path}");
return fallback_data;
}
match std::fs::read(real_path) {
// Box is used here to work around `f`'s limited lifetime
Ok(f) => Box::leak(Box::new(f)).as_slice(),
Err(e) => {
log::warn!("Failed to read file at: {path}");
log::warn!("{e:?}");
fallback_data
}
}
}
}
pub struct AppSession {

View File

@@ -1,45 +0,0 @@
use std::io::Cursor;
use rodio::{Decoder, OutputStreamBuilder, stream::OutputStream};
pub struct AudioOutput {
audio_stream: Option<OutputStream>,
first_try: bool,
}
impl AudioOutput {
pub const fn new() -> Self {
Self {
audio_stream: None,
first_try: true,
}
}
fn get_handle(&mut self) -> Option<&OutputStream> {
if self.audio_stream.is_none() && self.first_try {
self.first_try = false;
if let Ok(stream) = OutputStreamBuilder::open_default_stream() {
self.audio_stream = Some(stream);
} else {
log::error!("Failed to open audio stream. Audio will not work.");
return None;
}
}
self.audio_stream.as_ref()
}
pub fn play(&mut self, wav_bytes: &'static [u8]) {
let Some(handle) = self.get_handle() else {
return;
};
let cursor = Cursor::new(wav_bytes);
let source = match Decoder::new_wav(cursor) {
Ok(source) => source,
Err(e) => {
log::error!("Failed to play sound: {e:?}");
return;
}
};
let () = handle.mixer().add(source);
}
}

View File

@@ -1,4 +1,3 @@
pub mod audio;
pub mod dbus;
pub mod hid;
pub mod input;