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
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 stateSetMute(bool)- Set mute state explicitlySetRepeatMode(RepeatMode)- Set repeat mode
New AudioEvent variants:
VolumeChanged(f32, bool)- Volume and mute state changedRepeatModeChanged(RepeatMode)- Repeat mode changed
New State:
struct AudioEngineState {
volume: f32,
is_muted: bool,
repeat_mode: RepeatMode,
}Volume Control:
- Volume commands update the
RodioOutputsink 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 playlistRepeatMode::One- Restarts the same track automaticallyRepeatMode::All- Requests next track (playlist loops via modulo)
New Methods:
pub fn set_volume(&self, volume: f32) // Set volume (0.0-1.0)
pub fn volume(&self) -> f32 // Get current volumeNew 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 RepeatModeFrom<RepeatMode> for RepeatModeConfig
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 stateAudioEvent::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
test_repeat_mode_variants()- Tests all repeat mode variantstest_volume_command_creation()- Tests volume commandtest_mute_commands()- Tests mute commandstest_repeat_mode_command()- Tests repeat mode commandtest_volume_changed_event()- Tests volume eventtest_repeat_mode_changed_event()- Tests repeat mode eventtest_volume_bounds()- Tests volume range validationtest_repeat_mode_equality()- Tests repeat mode comparisontest_repeat_mode_copy()- Tests repeat mode copy semantics
test_playback_config_default()- Tests default playback configtest_repeat_mode_conversion()- Tests enum conversiontest_repeat_mode_roundtrip()- Tests bidirectional conversiontest_volume_bounds()- Tests volume validationtest_config_with_playback()- Tests full config with playback
- Adjust Volume: Use the volume slider in the control panel
- Mute/Unmute: Click the speaker icon (🔊/🔇)
- Keyboard: Volume changes are applied immediately
- Off: Tracks play once, then stop (or move to next in playlist)
- One: Current track repeats indefinitely
- All: Playlist loops continuously
Click the desired repeat mode button to activate it.
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"
}- 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
- Off: Audio thread sends
Finishedevent, GUI handles next track - One: Audio thread restarts same track on completion
- All: Audio thread sends
Finishedevent, GUI plays next (with wraparound)
GUI Thread Audio Thread
| |
|-- SetVolume(0.5) ------->|
| |-- Apply to sink
|<-- VolumeChanged --------|
| |
|-- SetRepeatMode(One) --->|
| |-- Update state
|<-- RepeatModeChanged ----|
Run tests with:
cargo test --package oneamp-core
cargo test --package oneamp-desktopPotential 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)
- Linux: Tested with ALSA, PulseAudio, PipeWire
- Volume Range: 0.0 (silent) to 1.0 (maximum)
- Config Format: JSON (backward compatible)
- Volume control is software-based (doesn't affect system volume)
- Repeat One mode restarts track from beginning (no seamless loop)
- No visual indicator for current repeat mode in minimal UI
Existing configurations will automatically upgrade:
- Missing
playbacksection uses defaults (volume: 1.0, muted: false, repeat: Off) - Old configs remain compatible
- No manual migration needed