Phase 2 adds advanced playback controls and comprehensive playlist management to OneAmp, bringing it closer to Winamp Modern feature parity.
-
PlaylistEntry: Represents individual tracks with metadata
- Path, title, artist, album, duration
- Display name fallback to filename
-
Playlist: Full-featured playlist with:
- Add/remove entries
- Current index tracking
- Shuffle mode with reproducible seeds
- Sort by: Title, Artist, Album, Path, Duration
- Search functionality (title, artist, album)
- Next/Previous track navigation (shuffle-aware)
-
PlayQueue: Temporary play queue
- Enqueue at end or front (play next)
- FIFO dequeue
- Independent from main playlist
-
M3U Format Support:
- Save:
#EXTM3Uformat with metadata - Load: Parse EXTINF tags for duration/title
- Save:
-
PLS Format Support:
- Save: Standard PLS format with File/Title/Length
- Load: Parse numbered entries
- Reproducible Shuffle: Uses seed-based Fisher-Yates algorithm
- Seed Management: Configurable seed for consistent shuffle order
- Integration: Works with repeat modes and playlist navigation
- Regeneration: Auto-regenerates on playlist changes
- New commands:
SetShuffle(bool),SetShuffleSeed(u64) - New events:
ShuffleUpdated(bool) - State persistence in
AudioEngineState
- Range: 0.5x to 2.0x
- Default: 1.0x (normal speed)
- Clamping: Automatic clamping to valid range
- Command:
SetPlaybackSpeed(f32) - Event:
PlaybackSpeedUpdated(f32) - Note: Actual audio resampling not yet implemented
- Placeholder for future DSP integration
- Will require audio processing pipeline enhancement
- Tracking: Last 20 files by default (configurable)
- Metadata: Last played timestamp, play count
- Persistence: JSON serialization
- Management: Add, remove, clear operations
- Smart Updates: Moves existing files to front, increments play count
let mut recent = RecentFiles::new();
recent.add_file(PathBuf::from("song.mp3"));
recent.save("recent.json")?;pub struct PlaybackConfig {
pub volume: f32,
pub muted: bool,
pub repeat_mode: RepeatModeConfig,
pub playback_speed: f32, // NEW
pub shuffle_enabled: bool, // NEW
pub shuffle_seed: u64, // NEW
}- All settings saved to config file
- Restored on application restart
- Backward compatible with Phase 1 configs
All playlist and playback logic is in oneamp-core, making it:
- Reusable across different UIs
- Compatible with .wsz theme system
- Testable independently
- Easy to integrate with future frontends
All state changes emit events:
ShuffleUpdated(bool)PlaybackSpeedUpdated(f32)- Enables reactive UI updates
- Supports theme system integration
- Core: Playlist logic, audio commands
- Desktop: UI integration, configuration
- Audio Thread: Playback state management
- State Exposure: All playback state available via events
- Command Interface: Theme UI can send any AudioCommand
- Metadata Access: Playlist entries include all display metadata
- Flexible Layout: Core doesn't dictate UI structure
// Themes can:
// 1. Display playlist
for entry in playlist.entries() {
render_playlist_item(entry);
}
// 2. Control shuffle
engine.send_command(AudioCommand::SetShuffle(true));
// 3. Show playback speed
match event {
AudioEvent::PlaybackSpeedUpdated(speed) => {
update_speed_display(speed);
}
}
// 4. Access recent files
let recent = RecentFiles::load("recent.json")?;
for file in recent.files() {
render_recent_item(file);
}- ✅ Playlist creation and manipulation
- ✅ Shuffle mode reproducibility
- ✅ Next/Previous navigation
- ✅ Search functionality
- ✅ Sort operations
- ✅ Queue management
- ✅ Recent files tracking
- ✅ M3U/PLS save/load
- Full playback with shuffle
- Playlist persistence across restarts
- Speed control with actual audio
- Theme system integration
- Crossfade: Smooth transitions between tracks
- Gapless Playback: Eliminate silence between tracks
- Advanced Seek: Frame-accurate seeking
- Speed Implementation: Actual audio resampling
- Pitch Preservation: Maintain pitch at different speeds
- Quality Settings: Configurable resampling quality
- Smart Playlists: Dynamic filtering
- Playlist Groups: Organize multiple playlists
- Auto-Playlists: Based on metadata criteria
AudioCommand::SetPlaybackSpeed(f32) // 0.5 - 2.0
AudioCommand::SetShuffle(bool) // Enable/disable
AudioCommand::SetShuffleSeed(u64) // Set seedAudioEvent::PlaybackSpeedUpdated(f32)
AudioEvent::ShuffleUpdated(bool)Playlist // Main playlist
PlaylistEntry // Single track
PlayQueue // Temporary queue
SortOrder // Sort criteria
RecentFiles // History manager
RecentFile // History entry- Update
oneamp-coredependency - Add new config fields (auto-defaults)
- Handle new events in UI
- Optional: Integrate playlist UI
Old configs are automatically upgraded:
{
"playback": {
"volume": 0.8,
"muted": false,
"repeat_mode": "Off"
// New fields auto-default
}
}- Add/Remove: O(1) amortized
- Search: O(n) linear scan
- Sort: O(n log n) standard sort
- Shuffle: O(n) Fisher-Yates
- Playlist: ~200 bytes per entry
- Recent Files: ~150 bytes per entry
- Shuffle Order: 8 bytes per entry
- Lazy metadata loading
- Playlist indexing for search
- Incremental shuffle updates
- Playback Speed: Command exists but audio resampling not implemented
- Large Playlists: No virtualization yet (>10k entries may be slow)
- Metadata: Not automatically extracted on add (requires manual update)
- Crossfade: Not implemented in Phase 2
- ✅ Shuffle mode
- ✅ Playlist management
- ✅ M3U/PLS support
- ✅ Recent files
⚠️ Playback speed (partial)- ❌ Crossfade (Phase 3)
- ❌ Gapless (Phase 3)
- ✅ M3U (Extended)
- ✅ PLS
- ❌ M3U8 (UTF-8) - Future
- ❌ XSPF - Future
- ❌ WPL - Future
- Add to
oneamp-corefirst - Emit events for state changes
- Add unit tests
- Update this documentation
- Consider theme integration
- Follow existing patterns
- Document public APIs
- Include examples in docs
- Add tests for new functionality
Phase 2 establishes a solid foundation for advanced playback features while maintaining compatibility with the upcoming .wsz theme system. The architecture is designed to be extensible and theme-agnostic, allowing for flexible UI implementations.
Next Phase: Audio Processing (EQ, Effects, Gapless)