Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The audio engine has been refactored for lower latency and stability:
- Inline cleanup of finished sources during mixing (simpler, no separate cleanup pass)
- Bounded source channel (capacity 64) to prevent unbounded memory growth
- Precomputed channel mappings at sample load time (no allocations during trigger)
- Song playback is buffered to reduce buffer underrun.

### Changed

Expand Down
132 changes: 118 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ tonic-reflection = "0.12.3"
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
crossbeam-channel = "0.5.15"
thread-priority = "3.0"
pest = "2.7"
pest_derive = "2.7"

Expand Down
2 changes: 2 additions & 0 deletions src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ use crate::songs::Song;
use std::collections::HashMap;
use std::sync::Barrier;

pub mod context;
pub mod cpal;
pub mod format;
pub mod mixer;
pub mod mock;
pub mod sample_source;

// Re-export the format types for backward compatibility
pub use context::PlaybackContext;
pub use format::{SampleFormat, TargetFormat};

/// Global source ID counter shared by song playback and sample triggers so IDs are unique.
Expand Down
52 changes: 52 additions & 0 deletions src/audio/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (C) 2026 Michael Wilson <mike@mdwn.dev>
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation, version 3.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/>.
//
// Shared context for audio playback (song and sample sources). Carries
// format, buffer sizes, and shared pools so call sites don't thread many
// separate arguments.
//

use std::sync::Arc;

use crate::audio::format::TargetFormat;
use crate::audio::sample_source::BufferFillPool;

/// Context passed into playback and source-creation paths so they can
/// obtain target format, buffer size, and shared resources (e.g. buffer
/// fill pool) without many separate parameters.
#[derive(Clone)]
pub struct PlaybackContext {
/// Target sample rate, format, and bit depth for output.
pub target_format: TargetFormat,
/// Device buffer size in frames (used for BufferedSampleSource capacity
/// and for file decode buffer size).
pub buffer_size: usize,
/// Shared pool for prefilling BufferedSampleSource. If None, sources
/// are not wrapped in BufferedSampleSource.
pub buffer_fill_pool: Option<Arc<BufferFillPool>>,
}

impl PlaybackContext {
/// Builds a context from the given format, buffer size, and optional pool.
pub fn new(
target_format: TargetFormat,
buffer_size: usize,
buffer_fill_pool: Option<Arc<BufferFillPool>>,
) -> Self {
Self {
target_format,
buffer_size,
buffer_fill_pool,
}
}
}
Loading