diff --git a/launcher/Sources/AVLiveLauncher/ProcessManager.swift b/launcher/Sources/AVLiveLauncher/ProcessManager.swift index 9ca969c..1fb15a2 100644 --- a/launcher/Sources/AVLiveLauncher/ProcessManager.swift +++ b/launcher/Sources/AVLiveLauncher/ProcessManager.swift @@ -64,8 +64,12 @@ final class ProcessManager: ObservableObject { sclangPath = defaults.string(forKey: "sclangPath") ?? "/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") - ?? "\(avLive)/sound_algo/00_load.scd" + ?? (fm.fileExists(atPath: bootCandidate) ? bootCandidate : legacyCandidate) // openFrameworks Release produces a .app bundle in bin/. Default to the // executable inside the bundle, with fallback to the bare binary if @@ -215,6 +219,12 @@ final class ProcessManager: ObservableObject { func stopSclang() { 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 diff --git a/sound_algo/boot.scd b/sound_algo/boot.scd new file mode 100644 index 0000000..4130de8 --- /dev/null +++ b/sound_algo/boot.scd @@ -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; +) diff --git a/sound_algo/tracks/_index.scd b/sound_algo/tracks/_index.scd index f8dc410..2722aef 100644 --- a/sound_algo/tracks/_index.scd +++ b/sound_algo/tracks/_index.scd @@ -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 ( ~listTracks.(\A); ) // liste les 15 tracks de A ( ~listTracks.(\Q); ) // liste les 15 tracks de Q @@ -112,3 +116,4 @@ ( ~playAlbum.(\A); ) // album A en entier ( ~playAlbum.(\J); ) // album J ambient ( ~stopAlbum.(); ) // stop immediat +*/