Eliminate *server* global: update dj-session + stream-harmony to protocol generics

dj-session.lisp:
- Replace pipeline-harmony-server + harmony:*server* binding with
  pipeline-play-voice / pipeline-stop-voice protocol generics
- Replace volume-ramp with pipeline-volume-ramp
- Replace read-audio-metadata / format-display-title with
  pipeline-read-metadata / pipeline-format-title
- Replace update-all-mounts-metadata with pipeline-update-metadata
- pipeline-stop-all-voices now a protocol generic (was defun)

stream-harmony.lisp:
- Replace cl-streamer:get-listener-count (global-dependent) with
  cl-streamer:pipeline-listener-count (pipeline-scoped)

Build verified.
This commit is contained in:
Glenn Thompson 2026-03-08 12:43:05 +03:00
parent 8d9d2b33b1
commit 3e6b496340
4 changed files with 21 additions and 28 deletions

@ -1 +1 @@
Subproject commit e1f113976b146894f8ac5e8fea5ba34c953db7e0 Subproject commit c0f9c0e161e2076f7dde8fdcbcb0f701d02cc35b

View File

@ -92,14 +92,14 @@
(when *harmony-pipeline* (when *harmony-pipeline*
(let ((state (list :playlist-path (when *current-playlist-path* (let ((state (list :playlist-path (when *current-playlist-path*
(namestring *current-playlist-path*)) (namestring *current-playlist-path*))
:current-track (cl-streamer/harmony:pipeline-current-track :current-track (cl-streamer:pipeline-current-track
*harmony-pipeline*)))) *harmony-pipeline*))))
;; 1. Clear the queue so play-list has nothing to advance to ;; 1. Clear the queue so play-list has nothing to advance to
(cl-streamer/harmony:pipeline-clear-queue *harmony-pipeline*) (cl-streamer:pipeline-clear-queue *harmony-pipeline*)
;; 2. Set skip flag so the play-list loop exits its wait ;; 2. Set skip flag so the play-list loop exits its wait
(cl-streamer/harmony:pipeline-skip *harmony-pipeline*) (cl-streamer:pipeline-skip *harmony-pipeline*)
;; 3. Immediately silence and stop all voices on the mixer ;; 3. Immediately silence and stop all voices on the mixer
(cl-streamer/harmony:pipeline-stop-all-voices *harmony-pipeline*) (cl-streamer:pipeline-stop-all-voices *harmony-pipeline*)
(log:info "Auto-playlist paused for DJ session") (log:info "Auto-playlist paused for DJ session")
state))) state)))
@ -183,15 +183,13 @@
(unless *dj-session* (unless *dj-session*
(error "No active DJ session")) (error "No active DJ session"))
(let* ((deck (get-deck *dj-session* deck-id)) (let* ((deck (get-deck *dj-session* deck-id))
(pipeline *harmony-pipeline*) (pipeline *harmony-pipeline*))
(server (cl-streamer/harmony:pipeline-harmony-server pipeline))
(org.shirakumo.fraf.harmony:*server* server))
;; Stop current track if playing ;; Stop current track if playing
(when (member (deck-state deck) '(:playing :paused)) (when (member (deck-state deck) '(:playing :paused))
(stop-deck-internal deck)) (stop-deck-internal deck))
;; Read metadata ;; Read metadata
(let* ((tags (cl-streamer/harmony:read-audio-metadata file-path)) (let* ((tags (cl-streamer:pipeline-read-metadata pipeline file-path))
(display-title (cl-streamer/harmony:format-display-title file-path)) (display-title (cl-streamer:pipeline-format-title pipeline file-path))
(track-info (list :file file-path (track-info (list :file file-path
:display-title display-title :display-title display-title
:artist (getf tags :artist) :artist (getf tags :artist)
@ -209,16 +207,14 @@
(error "No active DJ session")) (error "No active DJ session"))
(let* ((session *dj-session*) (let* ((session *dj-session*)
(deck (get-deck session deck-id)) (deck (get-deck session deck-id))
(pipeline *harmony-pipeline*) (pipeline *harmony-pipeline*))
(server (cl-streamer/harmony:pipeline-harmony-server pipeline))
(org.shirakumo.fraf.harmony:*server* server))
(ecase (deck-state deck) (ecase (deck-state deck)
(:empty (:empty
(error "Deck ~A has no track loaded" deck-id)) (error "Deck ~A has no track loaded" deck-id))
(:loaded (:loaded
;; Create a new voice and start playing ;; Create a new voice and start playing
(let ((voice (org.shirakumo.fraf.harmony:play (let ((voice (cl-streamer:pipeline-play-voice pipeline
(sb-ext:parse-native-namestring (deck-file-path deck)) (deck-file-path deck)
:mixer :music :mixer :music
:on-end :disconnect))) :on-end :disconnect)))
(setf (deck-voice deck) voice (setf (deck-voice deck) voice
@ -264,11 +260,9 @@
(defun stop-deck-internal (deck) (defun stop-deck-internal (deck)
"Internal: stop a deck's voice and reset state." "Internal: stop a deck's voice and reset state."
(when (deck-voice deck) (when (deck-voice deck)
(let* ((pipeline *harmony-pipeline*) (let ((pipeline *harmony-pipeline*))
(server (cl-streamer/harmony:pipeline-harmony-server pipeline))
(org.shirakumo.fraf.harmony:*server* server))
(handler-case (handler-case
(org.shirakumo.fraf.harmony:stop (deck-voice deck)) (cl-streamer:pipeline-stop-voice pipeline (deck-voice deck))
(error (e) (error (e)
(log:debug "Error stopping deck voice: ~A" e))))) (log:debug "Error stopping deck voice: ~A" e)))))
(setf (deck-voice deck) nil (setf (deck-voice deck) nil
@ -282,7 +276,7 @@
(member (deck-state deck) '(:playing :paused))) (member (deck-state deck) '(:playing :paused)))
(handler-case (handler-case
(progn (progn
(cl-streamer/harmony:volume-ramp (deck-voice deck) 0.0 duration) (cl-streamer:pipeline-volume-ramp *harmony-pipeline* (deck-voice deck) 0.0 duration)
(stop-deck-internal deck)) (stop-deck-internal deck))
(error (e) (error (e)
(log:debug "Error fading deck: ~A" e) (log:debug "Error fading deck: ~A" e)
@ -343,10 +337,8 @@
"Internal: disconnect external input voice." "Internal: disconnect external input voice."
(when (session-external-input session) (when (session-external-input session)
(handler-case (handler-case
(let* ((pipeline *harmony-pipeline*) (let ((pipeline *harmony-pipeline*))
(server (cl-streamer/harmony:pipeline-harmony-server pipeline)) (cl-streamer:pipeline-stop-voice pipeline (session-external-input session)))
(org.shirakumo.fraf.harmony:*server* server))
(org.shirakumo.fraf.harmony:stop (session-external-input session)))
(error (e) (error (e)
(log:debug "Error stopping external input: ~A" e))) (log:debug "Error stopping external input: ~A" e)))
(setf (session-external-input session) nil) (setf (session-external-input session) nil)
@ -379,7 +371,7 @@
(let ((title (or (session-metadata-override *dj-session*) (let ((title (or (session-metadata-override *dj-session*)
(auto-detect-dj-metadata *dj-session*)))) (auto-detect-dj-metadata *dj-session*))))
(when title (when title
(cl-streamer/harmony:update-all-mounts-metadata *harmony-pipeline* title))))) (cl-streamer:pipeline-update-metadata *harmony-pipeline* title)))))
(defun auto-detect-dj-metadata (session) (defun auto-detect-dj-metadata (session)
"Determine ICY metadata from the louder deck. "Determine ICY metadata from the louder deck.

View File

@ -385,7 +385,8 @@
(defun poll-and-store-stats () (defun poll-and-store-stats ()
"Single poll iteration: fetch listener counts from cl-streamer and store." "Single poll iteration: fetch listener counts from cl-streamer and store."
(dolist (mount '("/asteroid.mp3" "/asteroid.aac")) (dolist (mount '("/asteroid.mp3" "/asteroid.aac"))
(let ((listeners (cl-streamer:get-listener-count mount))) (let ((listeners (when *harmony-pipeline*
(cl-streamer:pipeline-listener-count *harmony-pipeline* mount))))
(when (and listeners (> listeners 0)) (when (and listeners (> listeners 0))
(store-listener-snapshot mount listeners) (store-listener-snapshot mount listeners)
(log:debug "Stored snapshot: ~a = ~a listeners" mount listeners)))) (log:debug "Stored snapshot: ~a = ~a listeners" mount listeners))))

View File

@ -193,7 +193,7 @@
(cl-streamer/harmony:pipeline-current-track *harmony-pipeline*)) (cl-streamer/harmony:pipeline-current-track *harmony-pipeline*))
(let* ((track-info (cl-streamer/harmony:pipeline-current-track *harmony-pipeline*)) (let* ((track-info (cl-streamer/harmony:pipeline-current-track *harmony-pipeline*))
(display-title (or (getf track-info :display-title) "Unknown")) (display-title (or (getf track-info :display-title) "Unknown"))
(listeners (cl-streamer:get-listener-count)) (listeners (cl-streamer:pipeline-listener-count *harmony-pipeline*))
(track-id (or (find-track-by-title display-title) (track-id (or (find-track-by-title display-title)
(find-track-by-file-path (getf track-info :file))))) (find-track-by-file-path (getf track-info :file)))))
`((:listenurl . ,(format nil "~A/~A" *stream-base-url* mount)) `((:listenurl . ,(format nil "~A/~A" *stream-base-url* mount))
@ -284,7 +284,7 @@
"Get current pipeline status." "Get current pipeline status."
(if *harmony-pipeline* (if *harmony-pipeline*
(let ((track (cl-streamer/harmony:pipeline-current-track *harmony-pipeline*)) (let ((track (cl-streamer/harmony:pipeline-current-track *harmony-pipeline*))
(listeners (cl-streamer:get-listener-count))) (listeners (cl-streamer:pipeline-listener-count *harmony-pipeline*)))
(list :running t (list :running t
:current-track (getf track :display-title) :current-track (getf track :display-title)
:artist (getf track :artist) :artist (getf track :artist)