Commit graph

30 commits

Author SHA1 Message Date
Dallas Groot
fc69d8a3cf CPU: Remove @Published from AudioPlayer time properties
Replace @Published var currentTime/duration with plain vars and drive
progress bars via TimelineView(.periodic) instead of SwiftUI
observation. This stops objectWillChange from firing 20x/second on
AudioPlayer, eliminating continuous body re-evaluation on
NowPlayingView, MiniPlayerBar, and MyMusicView regardless of
visualizer state.
2026-04-11 16:44:56 -07:00
Dallas Groot
3b56626d6d debugging high cpu usages 2026-04-11 16:15:27 -07:00
Dallas Groot
0730fa11f8 bug fixes 2026-04-11 15:09:06 -07:00
Dallas Groot
f3b9483b23 overhaul
AUDIT-036 — Slider/button fixes (direct Liquid Glass cause)
scheduleFlush() now runs Task { @MainActor } instead of bare Task. The
pendingSaves dictionary is now only ever read/written on the main
thread. Before this fix, a UserDefaults write could race with a slider
didSet, causing values to snap back or write the wrong value — which
is exactly why buttons were switching state unexpectedly.
AUDIT-034 — 60fps idle Canvas (direct Liquid Glass cause)
TimelineView now uses isRenderingActive ? settings.effectiveFPS : 2.0.
When paused or not visible, the Canvas drops from 60fps to 2fps. This
stops the continuous GPU wakeups that were fighting Liquid Glass
gesture tracking, which is why sliders needed multiple attempts.
AUDIT-001 — FFT real-time heap allocation
processFFT no longer allocates any heap memory. The Hann window is
computed once in init(). All four scratch buffers (fftWindow,
fftWindowed, fftRealp/fftImagp, fftMagnitudes) are pre-allocated and
reused every render callback — zero allocations on the real-time audio
thread.
AUDIT-002 — WatchOfflineStore data race
taskToSongId and pendingSongs now protected by a dedicated serial
storeQueue. URLSession delegate reads and main thread writes are
serialised.
AUDIT-019 — URLSession per AsyncCoverArt render
CompanionAPIService() no longer instantiated per render. Companion
cover art URLs now built directly from
CompanionSettings.shared.baseURL — no URLSession created.
AUDIT-020 — Synchronous disk read on main thread
CachedImageLoader now uses memoryOnlyImage (sync, no I/O) for the
first check, then cachedImageAsync (disk read on ioQueue) for the
second. Main thread never blocks on disk I/O.
AUDIT-033 — Lost star/unstar actions offline
Star/unstar now routes through OptimisticActionQueue — actions survive
Tailscale reconnection and are retried automatically.
AUDIT-035 — OptimisticActionQueue flush race
flush() Task is now @MainActor — pendingActions only ever touched on
main thread, no more race between rapid taps and in-flight flushes.
AUDIT-038 — O(n²) deduplication
deduplicateAlbums now O(n) using a frequency dictionary. For 843
albums: ~7.1M string comparisons/second during playback → ~1,700.
AUDIT-026, AUDIT-015 — Duplicate setResourceValue removed, cacheSize
now uses totalSize directly
2026-04-11 11:17:40 -07:00
Dallas Groot
0e6f4852e5 visualizer fix 2026-04-10 19:44:55 -07:00
Dallas Groot
f43fe73769 quick final fix (fingers crossed this time) 2026-04-10 19:29:42 -07:00
Dallas Groot
188a46d49c quickfix build error 2026-04-10 19:09:12 -07:00
Dallas Groot
a4103c8250 bug fixes and ready to upload to testflight 2026-04-10 19:05:45 -07:00
Dallas Groot
9a613ff2ab final cpu fix 2026-04-10 18:23:58 -07:00
Dallas Groot
16fd347b44 fixes hopefully 2026-04-10 18:05:10 -07:00
Dallas Groot
3cfcf026d7 fixes 2026-04-10 17:50:26 -07:00
Dallas Groot
80b6835dc7 squashed a cpu hogging bug 2026-04-10 17:39:46 -07:00
Dallas Groot
7d448e79de bug fixes 2026-04-10 17:05:12 -07:00
Dallas Groot
2bdac607b4 bug fixes
Songs Tab (SearchView.swift)
Default state now loads all songs alphabetically from the library via
getAlbumList2 → per-album song fetch, cached under "all_songs_sorted"
so subsequent opens are instant. The Download All banner shows song
count + already-downloaded count and queues only non-downloaded songs.
Every row uses .contextMenu (the long-press menu) with Play Now, Play
Next, Add to Queue, Download/Remove, Send to Watch, and Add to
Playlist — same pattern as Favourites. Watch and download badges
appear on each row. Searching ≥2 chars runs the server search and
shows artists/albums/songs in sections, then clears back to the full
list when the field is empty.
Keyboard Done Button
A single keyboardDoneButton() View extension in AsyncCoverArt.swift
calls UIApplication.shared.sendAction(resignFirstResponder:...)
globally — no @FocusState needed. Applied to: LoginView (all 4
fields), CompanionSettingsView (host/port), TrackEditorView
(checkField helper covers all tag fields), BatchAlbumEditorSheet
(editField helper), RadioView (name/URL), PlaylistsView (name fields),
MyMusicView (search), SearchView (via @FocusState + toolbar directly).
ShazamKit MTAudioProcessingTap
Primary path: MTAudioProcessingTap installed on AVPlayerItem.audioMix
— works for HLS, radio, and any AVPlayer stream without touching the
microphone. The prepare callback captures the source format and builds
an AVAudioConverter to 16kHz mono. The C-style shazamTapProcess free
function (required by the API) calls
MTAudioProcessingTapGetSourceAudio then dispatches to a serial
analysisQueue — the render thread is never blocked. convertAndMatch
wraps the raw AudioBufferList in an AVAudioPCMBuffer, converts it, and
feeds SHSession.matchStreamingBuffer. Fallback to microphone
(AVAudioEngine) is kept for the local engine path where no
AVPlayerItem exists. NSMicrophoneUsageDescription is only needed if
the mic fallback is ever hit.
2026-04-10 16:55:09 -07:00
Dallas Groot
b1101a6ea3 More Fixes and Radio improvements 2026-04-09 23:39:52 -07:00
Dallas Groot
9bf94c90b7 Imrpved Nowplaying/Visualizer 2026-04-09 23:11:40 -07:00
Dallas Groot
75a4343ad1 more fixes 2026-04-05 12:05:20 -07:00
Dallas Groot
bbb7faf488 ... 2026-04-05 09:02:56 -07:00
Dallas Groot
989412fda5 improvong the settings tab 2026-04-05 08:23:07 -07:00
Dallas Groot
f1f98fbf7d Finaly fixed Visualizer tweaks to make it more jello-y 2026-04-04 23:17:47 -07:00
Dallas Groot
df70a99279 Update from NavidromePlayer.zip (2026-04-04 19:00) 2026-04-04 19:00:31 -07:00
Dallas Groot
cf84c60159 more fixes for radio 2026-04-04 18:45:10 -07:00
Dallas Groot
6ac81a8dc1 Update from NavidromePlayer.zip (2026-04-04 18:41) 2026-04-04 18:41:21 -07:00
Dallas Groot
98bd66a9e5 radio fixes 2026-04-04 18:25:41 -07:00
Dallas Groot
7094ffab16 Update from NavidromePlayer.zip (2026-04-04 16:12) 2026-04-04 16:12:28 -07:00
Dallas Groot
274b5dfe02 Update from NavidromePlayer.zip (2026-04-04 07:42) 2026-04-04 07:42:23 -07:00
Dallas Groot
4787e2a5d4 Update from NavidromePlayer.zip (2026-04-04 00:14) 2026-04-04 00:14:41 -07:00
Dallas Groot
f39eaff281 3-Dot Menu Grid Layout — Replaced List-based sheet with a grid of button pairs: Instant Mix | Add to Playlist, Go to Album | Go to Artist, Download/Remove | Send to Watch, Get Info | Edit Tags. 2026-04-03 15:48:37 -07:00
Dallas Groot
b1b7d4b695 Favourites tab, artist cover change, ArtistCoverStore 2026-03-31 11:35:42 -07:00
Dallas Groot
d8041c0019 NavidromePlayer: iOS + watchOS Navidrome/Subsonic music player
Features:
- Dual-AVPlayer Smart DJ crossfade with LUFS normalization
- Mitsuha-style FFT visualizer (real-time + offline pre-computed)
- Companion API integration (Smart DJ, tag editing, vis frames)
- Offline-first SyncEngine with delta sync and album detail pre-caching
- Audio pre-fetcher for gapless queue playback
- Optimistic action queue (star/unstar with background retry)
- ShazamKit recognition with MusicKit preview playback
- Radio streaming with HLS/PLS/M3U support and buffer seek
- Watch app with Crown Sequencer and Ultra speaker support
- Batch metadata editing with album_artist fix for split albums
- Cache-first UI pattern across all views
- NWPathMonitor offline detection with reactive song greying
2026-03-28 20:49:47 +00:00