# audio.rs Analysis and Refactoring Plan
## Overview
`player/audio.rs` is the core audio playback engine, managing 545 lines of code. It handles file loading, playback control, format conversion, and real-time sample streaming for visualization.
## Public Interface
### Core AudioEngine Methods
```rust
impl AudioEngine {
pub fn new() -> AudioEngineResult
pub fn load_file(&mut self, path: &Path) -> Result<(), Box<dyn Error>>
pub fn play(&self)
pub fn pause(&self)
pub fn is_paused(&self) -> bool
pub fn volume(&self) -> f32
pub fn set_volume(&self, volume: f32)
pub fn get_progress(&self) -> f32
pub fn seek_relative(&mut self, seconds: f32) -> Result<(), Box<dyn Error>>
}
```
## Current Structure Analysis
### Strengths
- Clear separation between WAV and FLAC handling
- Thread-safe progress tracking using atomics
- Real-time sample streaming for visualization
- Good error handling with Result types
### Areas for Improvement
1. **Format Handling**
- `load_file` method could delegate to format-specific loaders
- Common audio source traits could reduce duplication
- Format detection could be more robust
2. **Seeking Implementation**
- Current implementation recreates the entire playback pipeline
- Could benefit from a more efficient seeking strategy
- Error handling for seek operations needs improvement
3. **Sample Processing**
- Normalization logic is duplicated between formats
- Channel handling could be abstracted
- Sample rate conversion might be needed for consistency
## Refactoring Opportunities
### 1. Extract Format Handling
Create a trait for audio format loaders:
```rust
trait AudioFormatLoader {
fn can_load(path: &Path) -> bool;
fn load(path: &Path, tx: mpsc::Sender<Vec<f32>>) -> Result<Box<dyn Source>, Box<dyn Error>>;
}
```
### 2. Improve Seeking
- Cache file information to avoid reloading
- Implement seek tables for better performance
- Add seek_to_position method (not just relative)
### 3. Enhance Error Types
Replace `Box<dyn Error>` with specific error types:
```rust
enum AudioError {
UnsupportedFormat(String),
FileNotFound(PathBuf),
DecodingError(String),
PlaybackError(String),
SeekError(String),
}
```
## Test Requirements
### Unit Tests Needed
1. **Initialization Tests**
- `test_new_audio_engine()`
- `test_audio_engine_initial_state()`
2. **File Loading Tests**
- `test_load_wav_file()`
- `test_load_flac_file()`
- `test_load_nonexistent_file()`
- `test_load_invalid_format()`
- `test_load_corrupted_file()`
3. **Playback Control Tests**
- `test_play_pause_toggle()`
- `test_volume_control()`
- `test_playback_state_transitions()`
4. **Progress Tracking Tests**
- `test_progress_during_playback()`
- `test_progress_after_seek()`
- `test_progress_at_boundaries()`
5. **Seeking Tests**
- `test_seek_forward()`
- `test_seek_backward()`
- `test_seek_beyond_end()`
- `test_seek_before_start()`
- `test_rapid_seeking()`
6. **Sample Monitoring Tests**
- `test_sample_channel_delivery()`
- `test_stereo_sample_handling()`
- `test_mono_sample_handling()`
- `test_sample_normalization()`
### Integration Tests Needed
1. **End-to-End Playback**
- Load → Play → Pause → Seek → Resume → Complete
- Format switching during session
- Multiple file loading
2. **Error Recovery**
- Graceful handling of audio device loss
- Recovery from decode errors
- Channel overflow handling
## Implementation Priority
1. **High Priority**
- Add basic unit tests for public API
- Improve error handling with specific types
- Document sample format expectations
2. **Medium Priority**
- Refactor format handling to reduce duplication
- Optimize seeking implementation
- Add comprehensive integration tests
3. **Low Priority**
- Implement seek tables for large files
- Add support for more audio formats
- Performance benchmarking
## Metrics
### Current State
- Lines of code: 545
- Public methods: 9
- Test coverage: 0%
- Largest method: 42 lines (play_wav)
### Target State
- Reduce largest method to <30 lines
- Achieve 80%+ test coverage
- Zero clippy warnings
- Clear separation of concerns