Skip to content

Latest commit

 

History

History
233 lines (177 loc) · 6.11 KB

File metadata and controls

233 lines (177 loc) · 6.11 KB

Phase 1 Implementation - Volume Control & Repeat Modes

Overview

This implementation adds essential playback control features to OneAmp:

  • Volume Control: In-app volume slider with mute functionality
  • Repeat Modes: Off, Repeat One, Repeat All

Changes Made

1. Core Audio Engine (oneamp-core)

New Types and Commands

RepeatMode enum (src/lib.rs):

pub enum RepeatMode {
    Off,   // No repeat
    One,   // Repeat current track
    All,   // Repeat all tracks in playlist
}

New AudioCommand variants:

  • SetVolume(f32) - Set volume (0.0 to 1.0)
  • ToggleMute - Toggle mute state
  • SetMute(bool) - Set mute state explicitly
  • SetRepeatMode(RepeatMode) - Set repeat mode

New AudioEvent variants:

  • VolumeChanged(f32, bool) - Volume and mute state changed
  • RepeatModeChanged(RepeatMode) - Repeat mode changed

Audio Thread Implementation (src/audio_thread_symphonia.rs)

New State:

struct AudioEngineState {
    volume: f32,
    is_muted: bool,
    repeat_mode: RepeatMode,
}

Volume Control:

  • Volume commands update the RodioOutput sink volume
  • Effective volume is 0.0 when muted, otherwise the set volume
  • Volume is applied when loading new tracks

Repeat Mode Logic:

  • RepeatMode::Off - Stops after track ends, requests next from playlist
  • RepeatMode::One - Restarts the same track automatically
  • RepeatMode::All - Requests next track (playlist loops via modulo)

Audio Output (src/rodio_output.rs)

New Methods:

pub fn set_volume(&self, volume: f32)  // Set volume (0.0-1.0)
pub fn volume(&self) -> f32             // Get current volume

2. Desktop Application (oneamp-desktop)

Configuration (src/config.rs)

New Config Structures:

pub struct PlaybackConfig {
    pub volume: f32,
    pub muted: bool,
    pub repeat_mode: RepeatModeConfig,
}

pub enum RepeatModeConfig {
    Off,
    One,
    All,
}

Conversion Traits:

  • From<RepeatModeConfig> for RepeatMode
  • From<RepeatMode> for RepeatModeConfig

Main Application (src/main.rs)

New State Fields:

struct OneAmpApp {
    // ... existing fields ...
    volume: f32,
    is_muted: bool,
    repeat_mode: RepeatMode,
}

Initialization:

  • Loads volume, mute, and repeat mode from config
  • Sends initial commands to audio engine on startup

Event Handling:

  • AudioEvent::VolumeChanged - Updates UI state
  • AudioEvent::RepeatModeChanged - Updates UI state

UI Controls:

  • Volume slider with live updates
  • Mute button (🔇/🔊)
  • Repeat mode buttons (Off/One/All)

Configuration Persistence:

  • on_exit() method saves all settings including volume and repeat mode
  • Config is saved when app closes

3. Tests

Core Tests (oneamp-core/src/tests/mod.rs)

  • test_repeat_mode_variants() - Tests all repeat mode variants
  • test_volume_command_creation() - Tests volume command
  • test_mute_commands() - Tests mute commands
  • test_repeat_mode_command() - Tests repeat mode command
  • test_volume_changed_event() - Tests volume event
  • test_repeat_mode_changed_event() - Tests repeat mode event
  • test_volume_bounds() - Tests volume range validation
  • test_repeat_mode_equality() - Tests repeat mode comparison
  • test_repeat_mode_copy() - Tests repeat mode copy semantics

Config Tests (oneamp-desktop/src/config.rs)

  • test_playback_config_default() - Tests default playback config
  • test_repeat_mode_conversion() - Tests enum conversion
  • test_repeat_mode_roundtrip() - Tests bidirectional conversion
  • test_volume_bounds() - Tests volume validation
  • test_config_with_playback() - Tests full config with playback

Usage

Volume Control

  1. Adjust Volume: Use the volume slider in the control panel
  2. Mute/Unmute: Click the speaker icon (🔊/🔇)
  3. Keyboard: Volume changes are applied immediately

Repeat Modes

  1. Off: Tracks play once, then stop (or move to next in playlist)
  2. One: Current track repeats indefinitely
  3. All: Playlist loops continuously

Click the desired repeat mode button to activate it.

Configuration

Settings are automatically saved to ~/.config/oneamp/config.json:

{
  "playback": {
    "volume": 0.75,
    "muted": false,
    "repeat_mode": "Off"
  },
  "equalizer": { ... },
  "first_run": false,
  "active_skin": "OneAmp Dark"
}

Technical Details

Volume Implementation

  • Volume is stored as f32 (0.0 to 1.0)
  • Applied via rodio::Sink::set_volume()
  • Mute is implemented by setting effective volume to 0.0
  • Volume persists across tracks

Repeat Mode Implementation

  • Off: Audio thread sends Finished event, GUI handles next track
  • One: Audio thread restarts same track on completion
  • All: Audio thread sends Finished event, GUI plays next (with wraparound)

Thread Communication

GUI Thread                Audio Thread
    |                          |
    |-- SetVolume(0.5) ------->|
    |                          |-- Apply to sink
    |<-- VolumeChanged --------|
    |                          |
    |-- SetRepeatMode(One) --->|
    |                          |-- Update state
    |<-- RepeatModeChanged ----|

Testing

Run tests with:

cargo test --package oneamp-core
cargo test --package oneamp-desktop

Future Enhancements

Potential improvements for future phases:

  • Keyboard shortcuts for volume (Up/Down arrows)
  • Volume percentage display
  • Fade in/out on track changes
  • Remember volume per track/album
  • Crossfade between tracks (requires more complex implementation)

Compatibility

  • Linux: Tested with ALSA, PulseAudio, PipeWire
  • Volume Range: 0.0 (silent) to 1.0 (maximum)
  • Config Format: JSON (backward compatible)

Known Limitations

  1. Volume control is software-based (doesn't affect system volume)
  2. Repeat One mode restarts track from beginning (no seamless loop)
  3. No visual indicator for current repeat mode in minimal UI

Migration Notes

Existing configurations will automatically upgrade:

  • Missing playback section uses defaults (volume: 1.0, muted: false, repeat: Off)
  • Old configs remain compatible
  • No manual migration needed