Skip to content

feat: v0.0.2 — Visualizer, transitions, mini-player, metadata editor, media control#2

Merged
devohmycode merged 12 commits intomainfrom
0.0.2
Mar 11, 2026
Merged

feat: v0.0.2 — Visualizer, transitions, mini-player, metadata editor, media control#2
devohmycode merged 12 commits intomainfrom
0.0.2

Conversation

@devohmycode
Copy link
Owner

@devohmycode devohmycode commented Mar 11, 2026

Summary

  • Audio visualizer — real-time FFT spectrum analyzer with mirror mode and configurable FPS (30/60)
  • Animated view transitions — Fluent slide+fade animations (CubicEase) between all navigation views
  • Mini-player mode — ultra-compact 60px mode with album art, track info, and play/pause (3-state collapse cycling via Ctrl+L)
  • Inline metadata editor — edit title, artist, album, and artwork directly from track context menu via TagLibSharp
  • Media control tab — monitor and control all background system media sessions (SMTC) with per-session cards, timeline scrubbing, and playback controls
  • Cover detection — automatic folder cover art discovery
  • Spectrum analyzer optimization — sliding window cache instead of full audio decode
  • Installer update — per-user install (no admin required), version bump to 0.0.2

Test plan

  • Launch app and verify all navigation tabs work (Library, Playlists, Queue, Visualizer, Media)
  • Cycle collapse modes with Ctrl+L (Expanded → Compact → Mini → Expanded)
  • Verify mini-player shows album art, track info, and play/pause
  • Right-click a track → Edit Tags → modify title/artist/album and save
  • Right-click a track → Edit Tags → change/remove artwork
  • Play a track and verify visualizer displays spectrum
  • Play media in another app, switch to Media tab, verify session cards appear with controls
  • Verify timeline scrubbing works on media session cards
  • Run installer and verify per-user install path

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added mini-player ultra-compact mode for quick playback control
    • Integrated audio waveform visualizer with adjustable frame rates (30/60 FPS)
    • Added system media session monitor and playback controls
    • Implemented inline metadata editor for track information and artwork management
    • Added animated view transitions between app sections
    • Enabled three-state display mode cycling (Expanded, Compact, Mini)
  • Chores

    • Updated installer configuration and version

devohmycode and others added 12 commits March 11, 2026 12:08
Mirror visualizer using NAudio FFT on pre-decoded audio data.
Configurable 30/60 FPS in settings. Fix expand showing wrong view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ata editor

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Slide+fade transitions (120ms exit, 150ms enter) between Library/Playlists/Queue/Visualizer
- 3-state collapse cycling: expanded (710px) → compact (220px) → mini (60px)
- Mini-player shows cover art, title — artist, play/pause button
- Ctrl+L cycles through all three states

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New MetadataWriter service for TagLibSharp write-back
- Edit title, artist, album directly from track context menu
- Change or remove artwork via file picker
- Updates database and refreshes UI on save
- Error handling for locked files during playback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CustomTitleBar (32px) was consuming vertical space in the 60px
mini-player, pushing the play/pause button off screen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Queue restore now only updates track info display without setting
the Pause icon, since no playback is active at startup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integrates SMTC (System Media Transport Controls) to detect and control
all active system media sessions. Includes per-session cards with
thumbnail, metadata, timeline scrubbing, and playback controls.
Also optimizes spectrum analyzer to use sliding window cache instead
of full decode, and refactors SMTC artwork update.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This pull request introduces three major features to Audiomatic: a spectrum-based audio visualizer with configurable frame rates, a system media session control panel for monitoring active media playback, and an inline metadata editor for track tags and artwork. Supporting changes include a mini-player ultra-compact display mode, animated view transitions, enhanced album art handling, and new services for spectrum analysis, metadata writing, and media session management.

Changes

Cohort / File(s) Summary
UI Layout & Navigation
Audiomatic/MainWindow.xaml
Added MiniPlayerBar in Row 1 with album art, track info, and controls; added Visualizer and Media navigation buttons; introduced WaveformContainer (Row 7) for spectrum visualization and MediaContainer (Row 7) for media sessions.
Main Window Logic
Audiomatic/MainWindow.xaml.cs
Extended ViewMode enum with Visualizer and MediaControl; implemented spectrum-based visualization pipeline with timer-driven rendering; added media session integration with SMTC; implemented 3-state collapse cycle (Expanded/Compact/Mini); added animated view transitions; introduced metadata editor UI flow; enhanced album art extraction and mini-player sync; added helper methods for cover file discovery and session management.
Audio & Visualization Services
Audiomatic/Services/SpectrumAnalyzer.cs, Audiomatic/Services/AudioPlayerService.cs
SpectrumAnalyzer: new service for pre-decoding audio and computing frequency-band spectra using FFT with Hamming window and logarithmic band spacing. AudioPlayerService: added public methods for artwork management (UpdateSmtcArtwork), timer control (SuspendPositionTimer/ResumePositionTimer), and refactored SMTC update flow.
Media Session & Metadata Services
Audiomatic/Services/MediaSessionPanel.cs, Audiomatic/Services/MetadataWriter.cs, Audiomatic/Services/LibraryManager.cs
MediaSessionPanel: new UI component for rendering and controlling individual media sessions with playback controls and timeline seeking. MetadataWriter: new utility for writing track metadata and artwork via TagLib with structured error results. LibraryManager: added UpdateTrackMetadata method to persist metadata changes to database.
Settings & Configuration
Audiomatic/SettingsManager.cs, Audiomatic/SettingsWindow.xaml, Audiomatic/SettingsWindow.xaml.cs
Added VisualizerFps (int) setting with default value 30; extended SettingsWindow with RadioButton FPS selector (30/60 fps) and callback wiring; updated constructor signature to accept onFpsChanged callback.
Documentation & Installer
README.md, docs/superpowers/plans/..., docs/superpowers/specs/..., installer.iss
Updated README with new Visualizer, Metadata Editor, and Media Control feature descriptions; added comprehensive feature planning and design specification documents; bumped installer version to 0.0.2 and updated default install path and privilege requirements.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant MainWindow
    participant SpectrumAnalyzer
    participant Canvas
    participant Audio[Audio Subsystem]

    User->>MainWindow: Click Visualizer button
    MainWindow->>SpectrumAnalyzer: PrepareAsync(currentTrackPath)
    SpectrumAnalyzer->>Audio: Pre-decode audio to memory
    Audio-->>SpectrumAnalyzer: Mono float samples + sample rate
    SpectrumAnalyzer-->>MainWindow: Ready signal
    
    loop Every frame (30/60 fps)
        MainWindow->>SpectrumAnalyzer: GetSpectrum(currentPosition, bandCount)
        SpectrumAnalyzer->>SpectrumAnalyzer: Compute FFT + log-spaced bands
        SpectrumAnalyzer-->>MainWindow: float[] spectrum data
        MainWindow->>Canvas: Draw bars for each band
        Canvas-->>User: Visual spectrum display
    end
Loading
sequenceDiagram
    participant User
    participant MainWindow
    participant MediaSessionPanel
    participant SMTC[System Media Transport Controls]
    participant System[System Media App]

    MainWindow->>SMTC: Initialize SessionManager
    loop Monitor active sessions
        SMTC-->>MainWindow: Session state changes
        MainWindow->>MediaSessionPanel: Create panel for session
        MediaSessionPanel->>SMTC: Subscribe to session events
        
        User->>MediaSessionPanel: Click play/pause
        MediaSessionPanel->>SMTC: TryTogglePlayPauseAsync()
        SMTC->>System: Toggle playback
        System-->>SMTC: Status updated
        SMTC-->>MediaSessionPanel: MediaPropertiesChanged event
        MediaSessionPanel->>MediaSessionPanel: Update UI (title, art, timeline)
        MediaSessionPanel-->>User: Refresh display
    end
Loading
sequenceDiagram
    participant User
    participant MainWindow
    participant MetadataWriter
    participant FileSystem
    participant LibraryManager
    participant Database

    User->>MainWindow: Click Edit Tags in context menu
    MainWindow->>MainWindow: BuildMetadataEditorContent
    MainWindow-->>User: Show inline editor (Title, Artist, Album, Artwork)
    
    User->>MainWindow: Edit fields + Click Save
    MainWindow->>MetadataWriter: WriteTags(filePath, title, artist, album)
    MetadataWriter->>FileSystem: Open audio file via TagLib
    FileSystem-->>MetadataWriter: File handle
    MetadataWriter->>MetadataWriter: Set ID3/metadata tags
    MetadataWriter->>FileSystem: Save file
    FileSystem-->>MetadataWriter: Success
    MetadataWriter-->>MainWindow: WriteResult(Success=true)
    
    MainWindow->>LibraryManager: UpdateTrackMetadata(trackId, title, artist, album)
    LibraryManager->>Database: UPDATE tracks table
    Database-->>LibraryManager: Rows affected
    
    MainWindow->>MainWindow: Refresh UI + Now Playing display
    MainWindow-->>User: Show updated metadata
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Whiskers twitching with creative glee,
New visualizers dance for all to see,
Mini-mode slides, metadata takes flight,
Media sessions shimmer in UI light,
Hopping through features, what a delight!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the five main features added: visualizer, transitions, mini-player, metadata editor, and media control—all of which are substantiated by the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 0.0.2

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link

Review Summary by Qodo

v0.0.2 — Visualizer, transitions, mini-player, metadata editor, and media control

✨ Enhancement

Grey Divider

Walkthroughs

Description
• **Audio visualizer** — real-time FFT spectrum analyzer with logarithmic frequency mapping, Hamming
  window, and configurable FPS (30/60)
• **Animated view transitions** — Fluent slide+fade Storyboard animations (CubicEase) between all
  navigation views
• **Mini-player mode** — ultra-compact 60px window state with album art, track info, and play/pause
  button; 3-state collapse cycling via Ctrl+L (Expanded → Compact → Mini)
• **Inline metadata editor** — edit title, artist, album, and artwork directly from track context
  menu with TagLibSharp tag write-back
• **Media control tab** — monitor and control system media sessions (SMTC) with per-session cards,
  timeline scrubbing, and playback controls
• **Cover art detection** — automatic folder cover art discovery and SMTC artwork synchronization
• **Installer update** — per-user installation (no admin required), version bump to 0.0.2
• **Settings enhancement** — visualizer FPS preference persistence (30 or 60 FPS)
Diagram
flowchart LR
  A["Audio Player"] -->|"FFT Analysis"| B["Spectrum Analyzer"]
  B -->|"Magnitude Data"| C["Visualizer Tab"]
  A -->|"Metadata"| D["Metadata Writer"]
  D -->|"Tag Updates"| E["Library Manager"]
  A -->|"SMTC Events"| F["Media Session Panel"]
  F -->|"Playback Control"| A
  G["MainWindow"] -->|"State Management"| H["Mini-Player Mode"]
  G -->|"Animated Transitions"| I["Navigation Views"]
  J["Settings Manager"] -->|"FPS Config"| C
Loading

Grey Divider

File Changes

1. Audiomatic/MainWindow.xaml.cs ✨ Enhancement +914/-26

View transitions, mini-player mode, visualizer, and metadata editor

• Added animated view transitions with slide+fade Storyboard animations between navigation views
• Implemented 3-state collapse cycling (Expanded → Compact → Mini) with CollapseState enum
 replacing boolean _isCollapsed
• Added mini-player ultra-compact mode (60px) with album art, track info, and play/pause button
• Integrated visualizer and media control tabs with spectrum analyzer and SMTC session management
• Added inline metadata editor UI in track context menu with artwork picker and tag write-back
• Implemented cover art detection from folder files and SMTC artwork updates

Audiomatic/MainWindow.xaml.cs


2. Audiomatic/MainWindow.xaml ✨ Enhancement +72/-0

XAML layout for mini-player, visualizer, and media control UI

• Added MiniPlayerBar Grid layout in Row 1 with album art, track text, play/pause button, and
 close button
• Added Visualizer and Media navigation buttons to the nav tab row
• Added WaveformContainer Canvas for spectrum visualization display
• Added MediaContainer ScrollViewer for system media session cards

Audiomatic/MainWindow.xaml


3. Audiomatic/Services/SpectrumAnalyzer.cs ✨ Enhancement +158/-0

Real-time FFT spectrum analyzer service

• New service for real-time FFT spectrum analysis with pre-decoded audio buffering
• Implements logarithmic frequency band mapping with Hamming window and smoothing
• Provides GetSpectrum() method returning normalized magnitude values (0..1) for visualization
• Uses pre-allocated buffers to avoid per-frame allocations for performance

Audiomatic/Services/SpectrumAnalyzer.cs


View more (11)
4. Audiomatic/Services/MediaSessionPanel.cs ✨ Enhancement +397/-0

Media session card UI component for SMTC control

• New UI component for displaying and controlling individual SMTC media sessions
• Shows thumbnail, app name, title, artist, and timeline with scrubbing capability
• Provides play/pause, previous, next buttons with playback state synchronization
• Handles session lifecycle events and timeline updates with debouncing

Audiomatic/Services/MediaSessionPanel.cs


5. Audiomatic/Services/MetadataWriter.cs ✨ Enhancement +59/-0

Tag write-back service for metadata editing

• New service for writing audio metadata tags via TagLibSharp
• Provides WriteTags() method for title, artist, album updates
• Provides WriteArtwork() method for embedding or removing cover art
• Returns structured WriteResult with success status and error messages

Audiomatic/Services/MetadataWriter.cs


6. Audiomatic/Services/LibraryManager.cs ✨ Enhancement +16/-0

Database update method for metadata changes

• Added UpdateTrackMetadata() method to persist edited title, artist, and album to database
• Enables synchronization between file tags and library database after metadata edits

Audiomatic/Services/LibraryManager.cs


7. Audiomatic/Services/AudioPlayerService.cs ✨ Enhancement +54/-15

SMTC artwork updates and timer suspension for window visibility

• Added UpdateSmtcArtwork() method to set SMTC thumbnail from pre-read artwork data or file path
• Added SuspendPositionTimer() and ResumePositionTimer() for window visibility state management
• Added FindCoverFile() helper to detect folder cover art by common naming patterns

Audiomatic/Services/AudioPlayerService.cs


8. Audiomatic/SettingsManager.cs ⚙️ Configuration changes +1/-0

Settings property for visualizer FPS configuration

• Added VisualizerFps property to AppSettings record with default value of 30
• Enables persistence of visualizer frame rate preference (30 or 60 FPS)

Audiomatic/SettingsManager.cs


9. Audiomatic/SettingsWindow.xaml.cs ✨ Enhancement +18/-1

Settings UI for visualizer FPS selection

• Added _onFpsChanged callback parameter to constructor for visualizer FPS changes
• Added FpsRadio_SelectionChanged() handler to persist FPS selection and trigger callback
• Load visualizer FPS setting from SettingsManager on window initialization

Audiomatic/SettingsWindow.xaml.cs


10. Audiomatic/SettingsWindow.xaml ✨ Enhancement +13/-0

Settings UI layout for visualizer FPS option

• Added Visualizer section with RadioButtons for 30 FPS and 60 FPS selection
• Includes descriptive label for frame rate setting

Audiomatic/SettingsWindow.xaml


11. installer.iss ⚙️ Configuration changes +4/-4

Installer configuration for v0.0.2 per-user install

• Updated AppVersion from 0.0.1 to 0.0.2
• Changed DefaultDirName from {autopf} (Program Files) to {localappdata}\Programs for per-user
 installation
• Changed PrivilegesRequired from admin to lowest to eliminate admin requirement
• Updated desktop icon task flag from unchecked to checkedonce for better UX

installer.iss


12. docs/superpowers/plans/2026-03-11-transitions-miniplayer-metadata-editor.md 📝 Documentation +1058/-0

Implementation plan for transitions, mini-player, and metadata editor

• Comprehensive implementation plan with 8 tasks across 4 chunks for view transitions, mini-player,
 and metadata editor
• Detailed step-by-step instructions with code snippets and verification steps
• Covers file structure, architecture decisions, and integration points
• Includes test plan and commit messages for each task

docs/superpowers/plans/2026-03-11-transitions-miniplayer-metadata-editor.md


13. docs/superpowers/specs/2026-03-11-transitions-miniplayer-metadata-editor-design.md 📝 Documentation +135/-0

Design specification for new features

• Design specification for three features: animated transitions, mini-player mode, and metadata
 editor
• Details behavior, implementation approach, and file modifications for each feature
• Includes UI mockups, state diagrams, and error handling strategy
• Documents dependencies and potential risks

docs/superpowers/specs/2026-03-11-transitions-miniplayer-metadata-editor-design.md


14. README.md 📝 Documentation +24/-4

Documentation updates for new features

• Added Visualizer and Media Control tabs to navigation overview
• Added Metadata Editor section describing inline tag editing and artwork management
• Added Media Control section documenting SMTC session monitoring and playback control
• Updated window modes description to include mini-player (60px) and animated transitions
• Updated hotkey documentation for Ctrl+L to reflect 3-state cycling
• Added Visualizer FPS setting to Settings section

README.md


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 11, 2026

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Media timer keeps running 🐞 Bug ➹ Performance
Description
When the window is hidden to tray, SuspendTimers stops only the player position timer and spectrum
timer, leaving the MediaControl 1s tick timer running. Additionally, when sessions drop to zero,
RebuildMediaSessionList clears panels but never calls UpdateMediaTimer, so an already-running media
timer may never stop.
Code

Audiomatic/MainWindow.xaml.cs[R2643-2647]

+    private void SuspendTimers()
+    {
+        _player.SuspendPositionTimer();
+        _spectrumTimer?.Stop();
+    }
Evidence
SuspendTimers/ResumeTimers omit _mediaTickTimer, so the 1-second media updates continue while
hidden. RebuildMediaSessionList clears _mediaSessionPanels (making needsTimer false), but because it
doesn’t call UpdateMediaTimer after changes, the stop branch is never executed when sessions change
to zero.

Audiomatic/MainWindow.xaml.cs[2626-2654]
Audiomatic/MainWindow.xaml.cs[1701-1718]
Audiomatic/MainWindow.xaml.cs[1647-1652]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Media Control timeline tick (`_mediaTickTimer`) is not suspended when the window is hidden to tray, and it may keep running even after sessions drop to zero because `RebuildMediaSessionList()` doesn’t call `UpdateMediaTimer()`.

### Issue Context
- `_mediaTickTimer` is created/started in `UpdateMediaTimer()`.
- `SuspendTimers()`/`ResumeTimers()` currently only manage `_player` position timer and `_spectrumTimer`.
- `RebuildMediaSessionList()` clears `_mediaSessionPanels`, which should cause `needsTimer` to become false, but the stop logic only runs if `UpdateMediaTimer()` is called.

### Fix Focus Areas
- Audiomatic/MainWindow.xaml.cs[1643-1699]
- Audiomatic/MainWindow.xaml.cs[1701-1719]
- Audiomatic/MainWindow.xaml.cs[2643-2654]

### Implementation notes
- In `SuspendTimers()`: stop `_mediaTickTimer` (or call `UpdateMediaTimer()` after setting a flag like `_isVisible=false`).
- In `ResumeTimers()`: call `UpdateMediaTimer()` to restart if `_viewMode == MediaControl` and panels exist.
- At the end of `RebuildMediaSessionList()`: call `UpdateMediaTimer()` so the timer starts/stops based on the new panel count.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Metadata editor UI freeze 🐞 Bug ⛯ Reliability
Description
BuildMetadataEditorContent blocks the UI thread by calling writer.StoreAsync().AsTask().Result while
constructing the flyout, which can hang or severely stall the UI when embedded artwork is present.
The method also doesn’t dispose the DataWriter/stream it creates for the preview.
Code

Audiomatic/MainWindow.xaml.cs[R1359-1363]

+                var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
+                var writer = new Windows.Storage.Streams.DataWriter(stream.GetOutputStreamAt(0));
+                writer.WriteBytes(pic.Data.Data);
+                _ = writer.StoreAsync().AsTask().Result;
+                stream.Seek(0);
Evidence
The metadata editor constructs UI on the UI thread and performs a synchronous wait on an async WinRT
operation (.Result). This is a direct UI-thread blocking call in the flyout building path.

Audiomatic/MainWindow.xaml.cs[1355-1363]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The metadata editor flyout content builder synchronously blocks on `writer.StoreAsync().AsTask().Result` while on the UI thread, which can freeze the app when opening the editor for tracks with embedded artwork.

### Issue Context
`BuildMetadataEditorContent()` is called directly from a context-menu button click and constructs UI elements synchronously. It should not perform blocking waits.

### Fix Focus Areas
- Audiomatic/MainWindow.xaml.cs[1352-1377]

### Implementation notes
- Replace the synchronous wait with an async flow. Two viable approaches:
 1) Defer the artwork preview load:
    - Build the panel with placeholder initially.
    - Kick off an async method like `LoadArtworkPreviewAsync(track.Path, artPreview, artPlaceholder)` that `await`s `writer.StoreAsync()` and then updates the UI via `DispatcherQueue.TryEnqueue`.
 2) Avoid DataWriter/StoreAsync entirely for preview by using an alternative that doesn’t require blocking (still must remain non-blocking on UI).
- Dispose/close the `DataWriter` and stream (`using`/`await using` where applicable) after `BitmapImage.SetSource`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Track count overwritten 🐞 Bug ✓ Correctness
Description
RebuildMediaSessionList always writes TrackCountText to a session count, and SessionsChanged
triggers it regardless of the active view, so TrackCountText can show “N sessions” while the user is
in Library/Playlist/Queue until another code path restores it. This breaks the bottom bar’s count
display for non-media views.
Code

Audiomatic/MainWindow.xaml.cs[1698]

+        TrackCountText.Text = $"{sessions.Count} session{(sessions.Count != 1 ? "s" : "")}";
Evidence
Once Media Control is initialized, SessionsChanged enqueues RebuildMediaSessionList on any session
change. RebuildMediaSessionList unconditionally updates TrackCountText to sessions, while
ApplyFilterAndSort uses TrackCountText for track counts in other views—meaning the media handler can
overwrite the non-media display.

Audiomatic/MainWindow.xaml.cs[1632-1635]
Audiomatic/MainWindow.xaml.cs[1698-1699]
Audiomatic/MainWindow.xaml.cs[307-310]
Audiomatic/MainWindow.xaml[373-379]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RebuildMediaSessionList()` always sets `TrackCountText` to a session count, and it is triggered by `SessionsChanged` even when the user is not in the Media Control view. This can overwrite the normal track/playlist counts shown in the bottom bar.

### Issue Context
- `SessionsChanged` remains subscribed after Media Control is initialized.
- `ApplyFilterAndSort()` uses `TrackCountText` for track counts in Library/Playlist views.

### Fix Focus Areas
- Audiomatic/MainWindow.xaml.cs[1632-1635]
- Audiomatic/MainWindow.xaml.cs[1698-1699]
- Audiomatic/MainWindow.xaml.cs[307-310]

### Implementation notes
- Option A (minimal): wrap the `TrackCountText.Text = ...sessions...` assignment in `if (_viewMode == ViewMode.MediaControl)`.
- Option B (cleaner): introduce a separate TextBlock for session count in the Media container/header and leave `TrackCountText` exclusively for library/playlist/queue counts.
- If you keep SessionsChanged always active, ensure it does not mutate global UI state outside the Media view.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Visualizer OOM prealloc 🐞 Bug ⛯ Reliability
Description
SpectrumAnalyzer.PrepareAsync pre-allocates a List<float> capacity based on audio length, capped
only at int.MaxValue, which can trigger extremely large allocations (and OOM) for long files. This
can crash or destabilize the app when preparing the visualizer for long audio (e.g.,
podcasts/audiobooks).
Code

Audiomatic/Services/SpectrumAnalyzer.cs[R42-45]

+            // Estimate total mono samples for pre-allocation
+            long estimatedMono = reader.Length / (reader.WaveFormat.BitsPerSample / 8) / channels;
+            var mono = new List<float>((int)Math.Min(estimatedMono, int.MaxValue));
+
Evidence
The List<float> is constructed with a capacity derived from reader.Length (file length /
bytes-per-sample / channels). For very large inputs this can request enormous capacity, causing
allocation failures before any decoding loop runs.

Audiomatic/Services/SpectrumAnalyzer.cs[42-45]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The visualizer decoder pre-allocates a `List&lt;float&gt;` with capacity derived from the audio length and capped at `int.MaxValue`, which can still be a multi-GB allocation and can OOM for long files.

### Issue Context
This happens in `SpectrumAnalyzer.PrepareAsync()` before decoding samples.

### Fix Focus Areas
- Audiomatic/Services/SpectrumAnalyzer.cs[36-59]

### Implementation notes
- Remove the capacity pre-allocation (use `new List&lt;float&gt;()`) or clamp to a conservative cap (e.g., a few million samples).
- If long-file visualizer support is desired, consider redesigning `PrepareAsync` to decode only a sliding window around the current playback position rather than the entire file.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@devohmycode devohmycode merged commit ee0e76d into main Mar 11, 2026
1 check was pending
Comment on lines +2643 to +2647
private void SuspendTimers()
{
_player.SuspendPositionTimer();
_spectrumTimer?.Stop();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Media timer keeps running 🐞 Bug ➹ Performance

When the window is hidden to tray, SuspendTimers stops only the player position timer and spectrum
timer, leaving the MediaControl 1s tick timer running. Additionally, when sessions drop to zero,
RebuildMediaSessionList clears panels but never calls UpdateMediaTimer, so an already-running media
timer may never stop.
Agent Prompt
### Issue description
The Media Control timeline tick (`_mediaTickTimer`) is not suspended when the window is hidden to tray, and it may keep running even after sessions drop to zero because `RebuildMediaSessionList()` doesn’t call `UpdateMediaTimer()`.

### Issue Context
- `_mediaTickTimer` is created/started in `UpdateMediaTimer()`.
- `SuspendTimers()`/`ResumeTimers()` currently only manage `_player` position timer and `_spectrumTimer`.
- `RebuildMediaSessionList()` clears `_mediaSessionPanels`, which should cause `needsTimer` to become false, but the stop logic only runs if `UpdateMediaTimer()` is called.

### Fix Focus Areas
- Audiomatic/MainWindow.xaml.cs[1643-1699]
- Audiomatic/MainWindow.xaml.cs[1701-1719]
- Audiomatic/MainWindow.xaml.cs[2643-2654]

### Implementation notes
- In `SuspendTimers()`: stop `_mediaTickTimer` (or call `UpdateMediaTimer()` after setting a flag like `_isVisible=false`).
- In `ResumeTimers()`: call `UpdateMediaTimer()` to restart if `_viewMode == MediaControl` and panels exist.
- At the end of `RebuildMediaSessionList()`: call `UpdateMediaTimer()` so the timer starts/stops based on the new panel count.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +1359 to +1363
var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
var writer = new Windows.Storage.Streams.DataWriter(stream.GetOutputStreamAt(0));
writer.WriteBytes(pic.Data.Data);
_ = writer.StoreAsync().AsTask().Result;
stream.Seek(0);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Metadata editor ui freeze 🐞 Bug ⛯ Reliability

BuildMetadataEditorContent blocks the UI thread by calling writer.StoreAsync().AsTask().Result while
constructing the flyout, which can hang or severely stall the UI when embedded artwork is present.
The method also doesn’t dispose the DataWriter/stream it creates for the preview.
Agent Prompt
### Issue description
The metadata editor flyout content builder synchronously blocks on `writer.StoreAsync().AsTask().Result` while on the UI thread, which can freeze the app when opening the editor for tracks with embedded artwork.

### Issue Context
`BuildMetadataEditorContent()` is called directly from a context-menu button click and constructs UI elements synchronously. It should not perform blocking waits.

### Fix Focus Areas
- Audiomatic/MainWindow.xaml.cs[1352-1377]

### Implementation notes
- Replace the synchronous wait with an async flow. Two viable approaches:
  1) Defer the artwork preview load:
     - Build the panel with placeholder initially.
     - Kick off an async method like `LoadArtworkPreviewAsync(track.Path, artPreview, artPlaceholder)` that `await`s `writer.StoreAsync()` and then updates the UI via `DispatcherQueue.TryEnqueue`.
  2) Avoid DataWriter/StoreAsync entirely for preview by using an alternative that doesn’t require blocking (still must remain non-blocking on UI).
- Dispose/close the `DataWriter` and stream (`using`/`await using` where applicable) after `BitmapImage.SetSource`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant