feat: Add 10-band equalizer and custom accent colors#5
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (14)
📝 WalkthroughWalkthroughThe pull request introduces a comprehensive Equalizer feature to the Audiomatic audio player, including multi-band EQ with presets, preamp control, accent color customization, and a new library window UI for viewing tracks with metadata. Changes span audio processing service, UI components, settings persistence, theme system, and navigation flow. Changes
Sequence DiagramsequenceDiagram
participant User
participant MainWindow
participant AudioPlayerService
participant EqualizerService
participant SettingsManager
participant NAudio
User->>MainWindow: Click Equalizer button
MainWindow->>MainWindow: BuildEqualizerUI()
MainWindow->>MainWindow: Load EQ settings from UI
User->>MainWindow: Change EQ band slider
MainWindow->>SettingsManager: Save EQ band value
MainWindow->>AudioPlayerService: SetEqBand(index, gainDb)
AudioPlayerService->>EqualizerService: SetBand(index, gainDb)
EqualizerService->>EqualizerService: RebuildFilters() for all channels
User->>MainWindow: Load / Play Track
MainWindow->>AudioPlayerService: PlayTrackAsync(trackPath)
AudioPlayerService->>EqualizerService: Sync EQ state (enabled, gains, preamp)
AudioPlayerService->>NAudio: Create AudioFileReader + Equalizer chain
NAudio->>EqualizerService: Read(buffer, offset, count)
EqualizerService->>EqualizerService: Apply filters per channel/band
EqualizerService->>EqualizerService: Apply preamp scaling
EqualizerService->>NAudio: Return processed samples
NAudio->>User: Audio output with EQ applied
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Review Summary by QodoAdd 10-band equalizer, custom accent colors, and detached library window
WalkthroughsDescription• Add 10-band graphic equalizer with presets, per-band gain control, and preamp adjustment • Implement custom accent color support with 24 preset swatches and hex input • Route all file playback through NAudio to enable equalizer audio processing • Add detached library window with sortable columns for track management • Update app version to 0.0.5 and enhance theme system for accent color application Diagramflowchart LR
A["Audio Playback"] -->|"Always use NAudio"| B["Equalizer Service"]
B -->|"10 bands + preamp"| C["Audio Output"]
D["Settings Manager"] -->|"Store EQ state"| E["EQ UI Controls"]
E -->|"Update gains"| B
F["Theme Helper"] -->|"Apply accent color"| G["UI Resources"]
H["Main Window"] -->|"Open/sync"| I["Library Window"]
I -->|"Display sorted tracks"| J["Track List"]
File Changes1. Audiomatic/LibraryWindow.xaml.cs
|
Code Review by Qodo
1. Playback events unsubscribed
|
| // Set up audio player | ||
| _player.SetDispatcherQueue(DispatcherQueue); | ||
| _player.MediaOpened += OnMediaOpened; | ||
| _player.MediaEnded += OnMediaEnded; | ||
| _player.MediaFailed += OnMediaFailed; | ||
| _player.PositionChanged += OnPositionChanged; | ||
| _player.BufferingChanged += OnBufferingChanged; | ||
|
|
||
| // Load settings | ||
| var settings = SettingsManager.Load(); | ||
| VolumeSlider.Value = settings.Volume * 100; | ||
| _player.Volume = settings.Volume; | ||
| _sortBy = settings.SortBy; | ||
| _sortAscending = settings.SortAscending; | ||
| SortAscending.IsChecked = _sortAscending; | ||
| UpdateSortChecks(); | ||
|
|
||
| // Load EQ settings | ||
| _player.EqEnabled = settings.EqEnabled; | ||
| if (settings.EqBands is { Length: 10 }) | ||
| _player.SetEqAllBands(settings.EqBands); | ||
| _player.SetEqPreamp(settings.EqPreamp); |
There was a problem hiding this comment.
1. Playback events unsubscribed 🐞 Bug ✓ Correctness
MainWindow no longer subscribes to AudioPlayerService.MediaOpened/MediaEnded/MediaFailed/PositionChanged/BufferingChanged, so the playback UI (timeline enablement/position updates/buffering text) and queue auto-advance logic never execute. The handler methods still exist but are never invoked because no subscriptions remain in the file.
Agent Prompt
### Issue description
MainWindow defines playback event handlers (OnMediaOpened/OnMediaEnded/OnMediaFailed/OnPositionChanged/OnBufferingChanged) but no longer subscribes to the corresponding `AudioPlayerService` events, so these handlers never run.
### Issue Context
Without these subscriptions, the timeline slider won’t initialize/update, buffering text for streams won’t update, and end-of-track auto-advance won’t happen.
### Fix Focus Areas
- Audiomatic/MainWindow.xaml.cs[189-210]
- Audiomatic/MainWindow.xaml.cs[527-606]
### Implementation notes
- Add back:
- `_player.MediaOpened += OnMediaOpened;`
- `_player.MediaEnded += OnMediaEnded;`
- `_player.MediaFailed += OnMediaFailed;`
- `_player.PositionChanged += OnPositionChanged;`
- `_player.BufferingChanged += OnBufferingChanged;`
- Ensure these are unsubscribed on window close if needed (depending on service lifetime).
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| applyBtn.Click += (_, _) => | ||
| { | ||
| var text = customBox.Text.Trim(); | ||
| if (text.StartsWith('#') && text.Length == 7) | ||
| { | ||
| flyout.Hide(); | ||
| DispatcherQueue.TryEnqueue(() => ApplyAccentAndSave(text)); | ||
| } | ||
| }; | ||
|
|
||
| customGrid.Children.Add(customPreview); | ||
| customGrid.Children.Add(customBox); | ||
| customGrid.Children.Add(applyBtn); | ||
| panel.Children.Add(customGrid); | ||
|
|
||
| flyout.Content = panel; | ||
| flyout.ShowAt(anchor); | ||
| } | ||
|
|
||
| private void ApplyAccentAndSave(string hexColor) | ||
| { | ||
| var s = SettingsManager.Load(); | ||
| SettingsManager.Save(s with { AccentColor = hexColor }); | ||
|
|
||
| // Update accent resources in place (no remove/add — safe at runtime) | ||
| ThemeHelper.ApplyAccentColor(hexColor); | ||
|
|
There was a problem hiding this comment.
2. Invalid accent hex crash 🐞 Bug ⛯ Reliability
The custom accent Apply flow accepts any 7-character string starting with '#', but ThemeHelper.ParseHexColor throws on non-hex characters and the Apply path doesn’t catch exceptions. Entering an invalid value like "#GGGGGG" can crash the UI thread when applying/saving the accent color.
Agent Prompt
### Issue description
Custom accent input can crash because the Apply path doesn’t validate hex digits and `ThemeHelper.ParseHexColor` throws on invalid characters.
### Issue Context
UI only checks `StartsWith('#') && Length == 7` before calling `ApplyAccentAndSave`, which calls `ThemeHelper.ApplyAccentColor(hexColor)`.
### Fix Focus Areas
- Audiomatic/MainWindow.xaml.cs[4055-4063]
- Audiomatic/MainWindow.xaml.cs[4074-4081]
- Audiomatic/ThemeHelper.cs[209-220]
### Implementation notes
- Prefer adding a helper like `bool TryParseHexColor(string text, out Color c)` using `uint.TryParse(hex, NumberStyles.HexNumber, ...)`.
- In the Apply click handler:
- Only call `ApplyAccentAndSave` if parsing succeeds.
- Otherwise show an error (or disable Apply until valid).
- Make `ThemeHelper.ParseHexColor` robust (no throw) even if callers pass bad values (settings file corruption, manual edits).
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| _**User**_ | ||
|
|
||
| "C:\Users\Dev\AppData\Local\Programs\Inno Setup 6\ISCC.exe" installer.iss | ||
|
|
||
| --- | ||
|
|
||
| _**Agent (model composer-1.5, mode Agent)**_ | ||
|
|
||
|
|
||
|
|
||
| --- | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| --- | ||
|
|
||
| <tool-use data-tool-type="shell" data-tool-name="run_terminal_command_v2"> | ||
| <details><summary>Tool use: **run_terminal_command_v2** • Run command: "C:\Users\Dev\AppData\Local\Programs\Inno Setup 6\ISCC.exe" "c:\dev\Audiotomatic\installer.iss"</summary> | ||
|
|
||
| ```bash | ||
| "C:\Users\Dev\AppData\Local\Programs\Inno Setup 6\ISCC.exe" "c:\dev\Audiotomatic\installer.iss" | ||
| ``` |
There was a problem hiding this comment.
3. Tool artifacts committed 🐞 Bug ⛨ Security
The PR adds .specstory history and .cursor hook state files that are local editor artifacts and include absolute machine paths/state. These files add repo noise, can change frequently, and leak developer environment details.
Agent Prompt
### Issue description
Editor/tool artifacts (.specstory and .cursor state) were committed. They include machine-specific paths and volatile metadata and should not be part of the product repository.
### Issue Context
These files are auto-generated and will cause repeated noisy diffs and potential environment info leakage.
### Fix Focus Areas
- .specstory/history/2026-03-13_13-06Z-inno-setup-installer-script.md[1-60]
- .specstory/history/2026-03-13_11-23Z-untitled.md[1-18]
- .cursor/hooks/state/continual-learning.json[1-8]
### Implementation notes
- Delete these files from the commit.
- Add ignore rules (repo-root .gitignore) for:
- `.specstory/`
- `.cursor/`
- any other Cursor/SpecStory generated state directories
- If you want to keep documentation, extract only the relevant non-sensitive content into a proper docs/ markdown file.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
and per-band gain adjustment (-12 to +12 dB)
Test plan
Summary by CodeRabbit
Release Notes
New Features
Chores