Skip to content

Commit

Permalink
Refactor AudioManager to accept dynamic audio buffer size and add UI …
Browse files Browse the repository at this point in the history
…slider for configuration
  • Loading branch information
samclane committed Jan 19, 2025
1 parent 6da735b commit 199e4f9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
4 changes: 3 additions & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ impl MantleApp {
})
.collect();

app.audio_manger.build_stream().unwrap();
app.audio_manger
.build_stream(&app.settings.audio_buffer_size)
.unwrap();

if !failures.is_empty() {
app.error_toast(&format!(
Expand Down
20 changes: 11 additions & 9 deletions src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ use cpal::{
};
use std::sync::{Arc, Mutex};

pub const AUDIO_BUFFER_DEFAULT: usize = 48000;

pub struct AudioManager {
host: Host,
current_device: Option<cpal::Device>,
configuration: Option<cpal::StreamConfig>,
stream: Option<cpal::Stream>,
samples_buffer: Arc<Mutex<Vec<f32>>>,
max_buffer_size: usize,
}

impl Default for AudioManager {
Expand All @@ -29,24 +30,25 @@ impl Default for AudioManager {
configuration,
stream: None,
samples_buffer: Arc::new(Mutex::new(Vec::new())),
max_buffer_size: 48000,
}
}
}

impl AudioManager {
pub fn build_stream(&mut self) -> Result<(), cpal::BuildStreamError> {
let device = self.current_device
pub fn build_stream(&mut self, max_buffer_size: &usize) -> Result<(), cpal::BuildStreamError> {
let device = self
.current_device
.as_ref()
.ok_or(cpal::BuildStreamError::DeviceNotAvailable)?;

let config = self.configuration

let config = self
.configuration
.as_ref()
.ok_or(cpal::BuildStreamError::InvalidArgument)?;

let buffer_clone = Arc::clone(&self.samples_buffer);
let max_size = self.max_buffer_size;
let max_size = *max_buffer_size;

let stream = device.build_output_stream(
config,
move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
Expand All @@ -62,7 +64,7 @@ impl AudioManager {
},
None,
)?;

self.stream = Some(stream);
Ok(())
}
Expand Down
16 changes: 16 additions & 0 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
use crate::{
action::UserAction,
app::MantleApp,
audio::AUDIO_BUFFER_DEFAULT,
color::default_hsbk,
device_info::DeviceInfo,
scenes::Scene,
Expand All @@ -17,13 +18,15 @@ const DEFAULT_REFRESH_RATE_MS: u64 = 500;
const DEFAULT_FOLLOW_RATE_MS: u64 = 500;
const REFRESH_RATE_RANGE: std::ops::RangeInclusive<u64> = 50..=10_000;
const FOLLOW_RATE_RANGE: std::ops::RangeInclusive<u64> = 50..=10_000;
const AUDIO_BUFFER_RANGE: std::ops::RangeInclusive<usize> = 1024..=AUDIO_BUFFER_DEFAULT;

#[derive(Deserialize, Serialize)]
pub struct Settings {
pub custom_shortcuts: Vec<KeyboardShortcutAction>,
pub refresh_rate_ms: u64,
pub follow_rate_ms: u64,
pub scenes: Vec<Scene>,
pub audio_buffer_size: usize,
}

impl Default for Settings {
Expand All @@ -33,6 +36,7 @@ impl Default for Settings {
refresh_rate_ms: DEFAULT_REFRESH_RATE_MS,
follow_rate_ms: DEFAULT_FOLLOW_RATE_MS,
scenes: Vec::new(),
audio_buffer_size: AUDIO_BUFFER_DEFAULT,
}
}
}
Expand All @@ -55,6 +59,8 @@ impl MantleApp {

self.render_follow_rate(ui);

self.render_audio_buffer_size(ui);

self.render_add_shortcut_ui(ui);

ui.separator();
Expand Down Expand Up @@ -259,6 +265,16 @@ impl MantleApp {
});
}

fn render_audio_buffer_size(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
ui.label("Audio Buffer Size:");
ui.add(
egui::Slider::new(&mut self.settings.audio_buffer_size, AUDIO_BUFFER_RANGE)
.text("samples"),
);
});
}

fn render_refresh_rate(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
ui.label("Refresh Rate:");
Expand Down

0 comments on commit 199e4f9

Please sign in to comment.