stream-harmony.lisp:
- scan-music-library-files: use native-namestring instead of namestring
when collecting file paths, producing real OS paths without SBCL's
backslash escaping of brackets (e.g. [FLAC] not \[FLAC])
- Use parse-native-namestring for root directory entry point so dirs
with brackets are not treated as wildcard patterns
cl-streamer submodule updated to d57a268:
- play-file, read-audio-metadata, play-list retry: same native-namestring
fix to prevent double-escaping through parse-native-namestring
Fixes FLAC FILE slot unbound errors and SIGSEGV memory fault that
crashed the shuffle pipeline after consecutive failures on bracket paths.
- New make-pipeline function: single declarative call creates server,
mounts, encoders, and pipeline wiring from an output spec
- Pipeline owns encoder lifecycle (pipeline-encoders slot, auto-cleanup)
- Pipeline owns server when it creates one (pipeline-owns-server-p)
- Hook system wired: pipeline-add-hook fires on track-change and
playlist-change via pipeline-fire-hook
- stream-harmony.lisp slimmed: start is 1 make-pipeline + 2 hooks,
stop is 1 pipeline-stop call (cleanup automatic)
- Removed global encoder variables from Asteroid glue layer
- Backward-compatible: dj-session.lisp unchanged, cl-streamer:*server*
still set for legacy callers
Runtime verified: audio streams, metadata displays, crossfades work.
- Replace default float packer with int16 packer (mixed:make-packer :encoding :int16)
cl-mixed now handles float→s16 conversion in optimized C code instead of
per-sample Lisp loop. Halves pack buffer memory (2 vs 4 bytes/sample).
- Remove float-to-s16 helper (no longer needed)
- Fix resume-from-saved-state: when saved playlist differs from currently
scheduled playlist, use the scheduled one from the beginning instead of
continuing the old playlist. Prevents stale playlist playing after restart.
- Add *resumed-from-saved-state* flag to prevent scheduler's db:connected
trigger from overwriting resumed playlist position with full playlist
- Use sb-ext:parse-native-namestring in play-file to prevent SBCL from
interpreting brackets in directory names (e.g. [WEB FLAC]) as wildcard
patterns, which caused non-simple-string pathname components that broke
cl-flac's CFFI calls
- Prevent play-list thread death on scheduler playlist change:
drain-queue-into-remaining drains full scheduler queue at once,
updates loop-queue reference so repeat replays correct playlist,
top-level handler-case prevents thread from dying silently
- Fix taglib SIMPLE-ARRAY CHARACTER type errors:
ensure-simple-string coerces metadata strings and trims whitespace
- Fix FLAC::FILE slot unbound errors:
retry once with 200ms delay for transient init failures
- Improve playback state persistence:
save playlist path alongside track file so restart loads the
correct playlist instead of always falling back to stream-queue.m3u
- Startup now uses resume-from-saved-state to resolve saved playlist
and track position, falls back to stream-queue.m3u only if no state
- Delay metadata/track-change notification by 1s after crossfade completes
- Log 'Loading next:' instead of 'Now playing:' during crossfade prep
- Add diagnostic logging: track duration check, crossfade trigger time
- harmony-load-playlist defaults to skip=nil: scheduler queues tracks
without interrupting current playback
- Save current track to .playback-state.lisp on each track change,
resume from saved position on restart
- Replace ~50 format-t debug statements in auth with log:info/log:warn
- Remove password hash logging for security
- Add .playback-state.lisp to .gitignore
- Use total listener count across all mounts instead of per-mount
(asteroid.lisp icecast-status API, stream-harmony.lisp now-playing)
- Fix recently-played.lisp: equal -> = for ParenScript string comparison
- Remove non-existent asteroid-shuffle.mp3 mount from recently-played JS
- Map all mount references to existing asteroid.mp3/asteroid.aac
CORS fix (icy-protocol.lisp):
- Add Access-Control-Allow-Origin: * to stream response headers
- Browser audio player can now connect cross-origin (port 8080 -> 8000)
Auto-start (asteroid.lisp -main):
- Start cl-streamer pipeline automatically on boot
- Load stream-queue.m3u and begin playback immediately
- Wrapped in handler-case so streaming failure doesn't block web server
Mount names (stream-harmony.lisp):
- Renamed /stream.mp3 -> /asteroid.mp3, /stream.aac -> /asteroid.aac
- Matches existing frontend URLs, zero template changes needed
Icecast bypass (asteroid.lisp, listener-stats.lisp):
- Front page uses get-now-playing-stats instead of icecast-now-playing
- check-icecast-status returns cl-streamer status when pipeline is active
- check-liquidsoap-status returns N/A when using cl-streamer
- asteroid/icecast-status API returns cl-streamer data directly
- poll-and-store-stats uses cl-streamer listener counts directly
- Eliminates hanging HTTP requests to port 8000 for Icecast XML
Tested: full browser streaming working end-to-end