Skip to content

feat(lambda-rs): Add sound playback devices#184

Merged
vmarcella merged 12 commits intomainfrom
vmarcella/sound-playback
Feb 12, 2026
Merged

feat(lambda-rs): Add sound playback devices#184
vmarcella merged 12 commits intomainfrom
vmarcella/sound-playback

Conversation

@vmarcella
Copy link
Member

@vmarcella vmarcella commented Feb 12, 2026

Summary

Add single-sound playback for SoundBuffer through an AudioContext with basic
transport controls (play, pause, stop), looping, and playback state queries.

Related Issues

Changes

  • Add audio-playback feature in lambda-rs.
  • Implement AudioContextBuilder/AudioContext and SoundInstance transport
    controls with PlaybackState queries.
  • Add callback-safe command transport (fixed-capacity SPSC ring queue) from the
    main thread to the audio callback thread.
  • Implement single-voice playback scheduler with click-avoidance gain ramps.
  • Update SoundBuffer sample storage to Arc<[f32]> to avoid large copies when
    sharing with the audio callback.
  • Add demo: sound_playback_transport (play/pause/stop + looping).
  • Document audio-playback in docs/features.md.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (updates to docs, specs, tutorials, or comments)
  • Refactor (code change that neither fixes a bug nor adds a feature)
  • Performance (change that improves performance)
  • Test (adding or updating tests)
  • Build/CI (changes to build process or CI configuration)

Affected Crates

  • lambda-rs
  • lambda-rs-platform
  • lambda-rs-args
  • lambda-rs-logging
  • Other: lambda-demos-audio

Checklist

  • Code follows the repository style guidelines (cargo +nightly fmt --all)
  • Code passes clippy (cargo clippy --workspace --all-targets -- -D warnings)
  • Tests pass (cargo test --workspace)
  • New code includes appropriate documentation
  • Public API changes are documented
  • Breaking changes are noted in this PR description

Testing

Commands run:

cargo +nightly fmt --all
cargo clippy --workspace --all-targets -- -D warnings
cargo clippy -p lambda-rs --all-targets --features audio-playback -- -D warnings
cargo test -p lambda-rs --features audio-playback

Manual verification steps (if applicable):

  1. Run cargo run -p lambda-demos-audio --features audio-playback --bin sound_playback_transport.
  2. Verify that play/pause/stop behave as expected and looping can be toggled.

Screenshots/Recordings

N/A

Platform Testing

  • macOS
  • Windows
  • Linux

Additional Notes

  • This implements single-sound playback only (no mixing of multiple concurrent
    sounds).

@vmarcella vmarcella added enhancement New feature or request lambda-rs Issues pertaining to the core framework audio All things related to audio labels Feb 12, 2026
@vmarcella vmarcella requested a review from Copilot February 12, 2026 20:54
@github-actions
Copy link

github-actions bot commented Feb 12, 2026

✅ Coverage Report

📊 View Full HTML Report (download artifact)

Overall Coverage

Metric Value
Total Line Coverage 77.57%
Lines Covered 11247 / 14500

Changed Files in This PR

File Coverage Lines
crates/lambda-rs-platform/src/wgpu/pipeline.rs 83.65% 394/471
crates/lambda-rs-platform/src/winit/mod.rs 5.96% 9/151
crates/lambda-rs/examples/minimal.rs N/A (no coverage data)
crates/lambda-rs/src/audio/buffer.rs 89.71% 183/204
crates/lambda-rs/src/audio/mod.rs N/A (no coverage data)
crates/lambda-rs/src/audio/playback/callback.rs 89.83% 371/413
crates/lambda-rs/src/audio/playback/context.rs 94.52% 397/420
crates/lambda-rs/src/audio/playback/mod.rs N/A (no coverage data)
crates/lambda-rs/src/audio/playback/transport.rs 100.00% 106/106
crates/lambda-rs/src/render/mod.rs 78.79% 1137/1443
crates/lambda-rs/src/render/pipeline.rs 90.86% 497/547
crates/lambda-rs/src/runtimes/application.rs 25.17% 113/449
crates/lambda-rs/src/runtimes/mod.rs N/A (no coverage data)

PR Files Coverage: 76.28% (3207/4204 lines)


Generated by cargo-llvm-cov · Latest main coverage

Last updated: 2026-02-12 22:41:50 UTC · Commit: 4e8bb5c

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements single-sound playback for the lambda-rs audio system, enabling basic transport controls (play, pause, stop) with looping support and click-free transitions. The implementation adds an AudioContext API with SoundInstance handles for controlling playback, backed by a lock-free command queue for thread-safe communication between the main thread and the real-time audio callback.

Changes:

  • Adds audio-playback feature flag and public APIs (AudioContext, AudioContextBuilder, SoundInstance, PlaybackState)
  • Implements lock-free SPSC command queue for real-time-safe communication with audio callback thread
  • Implements single-voice playback scheduler with linear gain ramps for click-free transport transitions
  • Updates SoundBuffer internal storage from Vec<f32> to Arc<[f32]> for efficient sharing with audio thread
  • Adds comprehensive unit tests covering command queue, scheduler, and controller behavior
  • Includes runnable demo and updates documentation (spec, features guide, index)

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/specs/audio/sound-playback.md New specification document detailing playback API surface, behavior requirements, and implementation constraints
docs/specs/README.md Updated index to include sound playback specification
docs/features.md Documents audio-playback feature flag and its composition with other audio features
demos/audio/src/bin/sound_playback_transport.rs Demo application exercising transport controls and looping
demos/audio/Cargo.toml Adds audio-playback feature to demo package
crates/lambda-rs/src/audio/playback.rs Core implementation: CommandQueue, GainRamp, PlaybackScheduler, PlaybackController, and public API
crates/lambda-rs/src/audio/mod.rs Feature-gates and re-exports playback module
crates/lambda-rs/src/audio/buffer.rs Changes sample storage to Arc<[f32]> and adds test helper for creating buffers
crates/lambda-rs/Cargo.toml Defines audio-playback feature and updates audio umbrella

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 808 to 810
/// This type is a placeholder API surface used while sound playback is under
/// active development. It is expected to become fully functional in a
/// subsequent change set.
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "This type is a placeholder API surface used while sound playback is under active development. It is expected to become fully functional in a subsequent change set," but this PR implements the full functionality. This comment should be updated or removed to accurately reflect that AudioContext is now fully functional.

Suggested change
/// This type is a placeholder API surface used while sound playback is under
/// active development. It is expected to become fully functional in a
/// subsequent change set.
/// This type is the main entry point for single-sound playback and transport
/// control. It manages the audio output device, queues playback commands, and
/// exposes shared playback state such as sample rate and channel configuration.

Copilot uses AI. Check for mistakes.
Comment on lines 1004 to 1005
let _result = self.command_queue.push(PlaybackCommand::StopCurrent);

Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result of pushing the StopCurrent command is silently discarded. If the queue is full and this push fails, but subsequent pushes succeed, this could lead to unexpected behavior. Consider either: (1) checking if the push failed and handling it appropriately, (2) documenting why it's safe to ignore this failure, or (3) removing the StopCurrent command if the SetBuffer command handler already stops playback (which it does on line 619).

Suggested change
let _result = self.command_queue.push(PlaybackCommand::StopCurrent);

Copilot uses AI. Check for mistakes.
@vmarcella vmarcella merged commit 6f96052 into main Feb 12, 2026
10 checks passed
@vmarcella vmarcella deleted the vmarcella/sound-playback branch February 12, 2026 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

audio All things related to audio enhancement New feature or request lambda-rs Issues pertaining to the core framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Basic sound playback

1 participant