Skip to content

feat(lambda-rs): Pitch and Volume control#186

Merged
vmarcella merged 9 commits intomainfrom
vmrcella/volume-and-pitch-control
Feb 17, 2026
Merged

feat(lambda-rs): Pitch and Volume control#186
vmarcella merged 9 commits intomainfrom
vmrcella/volume-and-pitch-control

Conversation

@vmarcella
Copy link
Member

@vmarcella vmarcella commented Feb 17, 2026

Summary

Add per-sound-instance volume (gain) and pitch (playback speed) controls plus an AudioContext master volume, implemented in the audio callback scheduler (single active sound). Includes a demo for interactively exercising transport/gain/pitch/master controls and updated audio specs.

Related Issues

Changes

  • lambda-rs:

    • Add AudioContext::{set_master_volume, master_volume}.
    • Add SoundInstance::{set_volume, volume}.
    • Add SoundInstance::{set_pitch, pitch} implemented via fractional cursor + linear interpolation resampling.
    • Apply transport ramp * master volume * instance volume in the callback.
    • Add clipping awareness (bounded output), with soft-knee limiting when amplification is in effect.
    • Add unit tests covering normalization behavior and output scaling/bounding.
  • docs:

    • Add draft spec: docs/specs/audio/sound-instance-gain-and-pitch.md.
    • Update specs index and cross-reference from sound-playback non-goals.
  • lambda-demos-audio:

    • Add demo: sound_instance_gain_pitch.
    • Add CLI modes (subcommands) using lambda-rs-args: script, play, repl.
    • Default behavior prints usage when invoked with no args.

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 (used by demo for CLI parsing)
  • 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 (see Testing section)
  • New code includes appropriate documentation
  • Public API changes are documented (spec + rustdoc)
  • Breaking changes are noted in this PR description

Testing

Commands run:

# Unit tests for audio playback (focused)
cargo test -p lambda-rs --no-default-features --features audio-playback

# Demo build
cargo build -p lambda-demos-audio --bin sound_instance_gain_pitch

Manual verification steps (if applicable):

  1. cargo run -p lambda-demos-audio --bin sound_instance_gain_pitch -- --help
  2. cargo run -p lambda-demos-audio --bin sound_instance_gain_pitch -- script
  3. cargo run -p lambda-demos-audio --bin sound_instance_gain_pitch -- repl
    • Try: volume 0, volume 2, pitch 0.5, pitch 2, master 0.05, master 0.25

Screenshots/Recordings

N/A

Platform Testing

  • macOS
  • Windows
  • Linux

Additional Notes

  • Pitch is implemented as resampling (rate change), so it changes both speed and perceived frequency (no time-stretch).
  • Playback remains “single active sound” as per the existing transport/playback design; volume/pitch are stored for the active slot.

@github-actions
Copy link

github-actions bot commented Feb 17, 2026

✅ Coverage Report

📊 View Full HTML Report (download artifact)

Overall Coverage

Metric Value
Total Line Coverage 76.53%
Lines Covered 12453 / 16272

Changed Files in This PR

File Coverage Lines
crates/lambda-rs/src/audio/playback/callback.rs 92.50% 629/680
crates/lambda-rs/src/audio/playback/context.rs 95.96% 547/570
crates/lambda-rs/src/audio/playback/transport.rs 100.00% 163/163

PR Files Coverage: 94.76% (1339/1413 lines)


Generated by cargo-llvm-cov · Latest main coverage

Last updated: 2026-02-17 22:58:33 UTC · Commit: ed77013

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 PR adds per-sound-instance volume and pitch controls, plus a global master volume on AudioContext. The implementation uses atomic storage for lock-free access from the audio callback thread, with pitch implemented via fractional cursor advancement and linear interpolation resampling. A comprehensive CLI demo exercises all transport, gain, and pitch controls through script, play, and REPL modes.

Changes:

  • Added SoundInstance::{set_volume, volume, set_pitch, pitch} and AudioContext::{set_master_volume, master_volume} APIs with infallible normalization for invalid inputs
  • Implemented pitch control via fractional frame cursor (f32) with linear interpolation resampling between adjacent samples
  • Added soft-knee limiter for amplified output when combined gains exceed 1.0, with non-finite sample handling
  • Created sound_instance_gain_pitch demo with three modes (script, play, repl) for interactive testing
  • Added comprehensive unit tests for normalization, pitch resampling, volume scaling, and clipping behavior
  • Documented the feature in new spec sound-instance-gain-and-pitch.md with API surface, behavior, and validation rules

Reviewed changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/specs/audio/sound-instance-gain-and-pitch.md New spec documenting API surface, behavior, validation rules, and acceptance criteria for volume/pitch controls
docs/specs/audio/sound-playback.md Updated non-goals section to reference new gain/pitch spec instead of listing as out-of-scope
docs/specs/README.md Added index entry for new sound-instance-gain-and-pitch spec
crates/lambda-rs/src/audio/playback/transport.rs Added AtomicU32 storage for master_volume, instance_volume, instance_pitch with normalization helpers
crates/lambda-rs/src/audio/playback/context.rs Added public API methods on AudioContext and SoundInstance with unit tests for defaults, clamping, and reset behavior
crates/lambda-rs/src/audio/playback/callback.rs Changed cursor to f32 for fractional advancement, added linear interpolation resampling, soft-clip limiter, and comprehensive tests
demos/audio/src/bin/sound_instance_gain_pitch.rs New interactive demo with CLI argument parsing and three modes for exercising volume/pitch/master controls
demos/audio/Cargo.toml Added lambda-rs-args dependency for CLI parsing in demo
Cargo.lock Dependency lockfile update for lambda-rs-args

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

@vmarcella vmarcella merged commit 244c59e into main Feb 17, 2026
10 checks passed
@vmarcella vmarcella deleted the vmrcella/volume-and-pitch-control branch February 17, 2026 23:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Volume and pitch control

1 participant

Comments