fix: sclang auto-boot via boot.scd
Context: launching sclang with 00_load.scd as argument was a no-op —
the file is split into ~32 IDE-friendly Cmd+Enter blocks and sclang's
parser only accepts ONE top-level expression per .load. So nothing
actually ran, the engine never came up on the MBP, and every web tab
that depends on /sync/* (Album, Mélodies, Kicks, Mixer real values,
…) was empty. Same problem hit tracks/_index.scd which has shortcut
blocks at the bottom : 'ERROR: syntax error, unexpected (, expecting
end of file' at line 104, which aborted the load and never populated
~albums.
Approach: a tiny single-block boot.scd that derives ~base from
thisProcess.nowExecutingPath and just .load's live/_load.scd (which
runs the whole engine + tracks + web_bridge chain). The launcher's
default soundAlgoLoadFile picks boot.scd if it exists, falls back to
00_load.scd otherwise. tracks/_index.scd's IDE shortcut blocks at the
bottom are wrapped in /* */ block comment so the file is .load-clean
while staying useful in the IDE (uncomment to use). stopSclang()
also runs pkill scsynth as a safety net so the next boot can grab
:57110 — sclang.terminate() doesn't reliably kill its scsynth child.
Changes:
- sound_algo/boot.scd : new entry point, single block, sets ~base
from disk location and loads live/_load.scd
- sound_algo/tracks/_index.scd : 9 IDE shortcut lines (lines 104-114)
wrapped in /* */ so .load no longer hits 'syntax error unexpected (,
expecting end of file'
- launcher/ProcessManager.swift :
* default soundAlgoLoadFile prefers <avLive>/sound_algo/boot.scd
over <avLive>/sound_algo/00_load.scd when both exist
* stopSclang() runs /usr/bin/pkill -f scsynth after sclang.terminate()
Impact: end-to-end verified on the Big Sur Intel MBP via SSH tunnel.
After launcher start the Album tab shows the 23 expected cards
(Acid Journey, Deep to Hard, …, Dub Techno) with working ▶ Album /
▶ Tracks buttons. scsynth :57110 is alive, web bridge is healthy
(3 WS clients), oscope-of receives /sync/album in its HUD.
This commit is contained in:
@@ -64,8 +64,12 @@ final class ProcessManager: ObservableObject {
|
|||||||
|
|
||||||
sclangPath = defaults.string(forKey: "sclangPath")
|
sclangPath = defaults.string(forKey: "sclangPath")
|
||||||
?? "/Applications/SuperCollider.app/Contents/MacOS/sclang"
|
?? "/Applications/SuperCollider.app/Contents/MacOS/sclang"
|
||||||
|
// Prefer boot.scd (single-block, auto-executable by sclang CLI) over
|
||||||
|
// 00_load.scd which is split into ~32 IDE-only Cmd+Enter blocks.
|
||||||
|
let bootCandidate = "\(avLive)/sound_algo/boot.scd"
|
||||||
|
let legacyCandidate = "\(avLive)/sound_algo/00_load.scd"
|
||||||
soundAlgoLoadFile = defaults.string(forKey: "soundAlgoLoadFile")
|
soundAlgoLoadFile = defaults.string(forKey: "soundAlgoLoadFile")
|
||||||
?? "\(avLive)/sound_algo/00_load.scd"
|
?? (fm.fileExists(atPath: bootCandidate) ? bootCandidate : legacyCandidate)
|
||||||
|
|
||||||
// openFrameworks Release produces a .app bundle in bin/. Default to the
|
// openFrameworks Release produces a .app bundle in bin/. Default to the
|
||||||
// executable inside the bundle, with fallback to the bare binary if
|
// executable inside the bundle, with fallback to the bare binary if
|
||||||
@@ -215,6 +219,12 @@ final class ProcessManager: ObservableObject {
|
|||||||
|
|
||||||
func stopSclang() {
|
func stopSclang() {
|
||||||
sclangProc?.terminate()
|
sclangProc?.terminate()
|
||||||
|
// sclang's terminate doesn't always tear scsynth down cleanly —
|
||||||
|
// run a belt-and-braces pkill so the next boot can grab :57110.
|
||||||
|
let kill = Process()
|
||||||
|
kill.executableURL = URL(fileURLWithPath: "/usr/bin/pkill")
|
||||||
|
kill.arguments = ["-f", "scsynth"]
|
||||||
|
try? kill.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - oscope-of
|
// MARK: - oscope-of
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// =====================================================================
|
||||||
|
// boot.scd -- Entry point auto-executable for sclang CLI
|
||||||
|
//
|
||||||
|
// 00_load.scd is split into ~32 IDE-friendly top-level blocks
|
||||||
|
// (Cmd+Enter per block in SCIDE), which means it does NOT auto-run
|
||||||
|
// when sclang is launched with `sclang 00_load.scd`. This file wraps
|
||||||
|
// the actual boot sequence in ONE single top-level block so the
|
||||||
|
// launcher (or any `sclang boot.scd` invocation) brings the engine
|
||||||
|
// + palette + live wrappers + tracks + web bridge up automatically.
|
||||||
|
//
|
||||||
|
// Execution order :
|
||||||
|
// 1. derive ~base from this file's location
|
||||||
|
// 2. .load live/_load.scd (which itself loads engine, synth, fx,
|
||||||
|
// palette, setup, ~setupAll, tracks/_index, web_bridge, then
|
||||||
|
// starts the Pdef sequencers)
|
||||||
|
//
|
||||||
|
// Usage :
|
||||||
|
// sclang /path/to/AV-Live/sound_algo/boot.scd
|
||||||
|
// OR (in IDE)
|
||||||
|
// Cmd+Enter on this block.
|
||||||
|
// =====================================================================
|
||||||
|
(
|
||||||
|
~base = (thisProcess.nowExecutingPath !? { |p| p.dirname ++ "/" })
|
||||||
|
?? { File.getcwd ++ "/" };
|
||||||
|
|
||||||
|
("[boot] ~base = " ++ ~base).postln;
|
||||||
|
|
||||||
|
(~base ++ "live/_load.scd").load;
|
||||||
|
)
|
||||||
@@ -98,9 +98,13 @@
|
|||||||
|
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// RACCOURCIS LIVE -- Cmd+Entree sur la ligne souhaitee
|
// RACCOURCIS LIVE -- Cmd+Entree sur la ligne souhaitee dans l'IDE.
|
||||||
|
// Commentes pour permettre `.load` de ce fichier sans erreur de parse :
|
||||||
|
// sclang refuse plusieurs blocs `(...)` top-level dans un meme load.
|
||||||
|
// Decommenter au besoin dans l'IDE.
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
|
/*
|
||||||
( ~listAlbums.(); ) // liste les 23 albums
|
( ~listAlbums.(); ) // liste les 23 albums
|
||||||
( ~listTracks.(\A); ) // liste les 15 tracks de A
|
( ~listTracks.(\A); ) // liste les 15 tracks de A
|
||||||
( ~listTracks.(\Q); ) // liste les 15 tracks de Q
|
( ~listTracks.(\Q); ) // liste les 15 tracks de Q
|
||||||
@@ -112,3 +116,4 @@
|
|||||||
( ~playAlbum.(\A); ) // album A en entier
|
( ~playAlbum.(\A); ) // album A en entier
|
||||||
( ~playAlbum.(\J); ) // album J ambient
|
( ~playAlbum.(\J); ) // album J ambient
|
||||||
( ~stopAlbum.(); ) // stop immediat
|
( ~stopAlbum.(); ) // stop immediat
|
||||||
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user