diff --git a/sound_algo/data_only/engine.scd b/sound_algo/data_only/engine.scd index 41480ff..87aa120 100644 --- a/sound_algo/data_only/engine.scd +++ b/sound_algo/data_only/engine.scd @@ -25,6 +25,15 @@ ~doMaster !? { ~doMaster.free }; ~doMasterGroup !? { ~doMasterGroup.free }; +// Setter de tempo unique et coordonne : une seule horloge +// (TempoClock.default). Tous les controleurs runtime passent par ici. +~setTempo = { |bpm| + ~bpm = bpm.clip(20, 300); + TempoClock.default.tempo = ~bpm / 60; + ("[tempo] " ++ ~bpm ++ " BPM").postln; + ~bpm; +}; + s.waitForBoot { var rate = s.sampleRate; diff --git a/sound_algo/engine.scd b/sound_algo/engine.scd index 006710a..6b09a6c 100644 --- a/sound_algo/engine.scd +++ b/sound_algo/engine.scd @@ -11,7 +11,17 @@ // 1. SETUP -- evalue UNE FOIS au demarrage de la session // ===================================================================== ( -s.waitForBoot { +// Setter de tempo unique et coordonne : une seule horloge +// (TempoClock.default). Tous les controleurs runtime passent par ici. +~setTempo = { |bpm| + ~bpm = bpm.clip(20, 300); + TempoClock.default.tempo = ~bpm / 60; + ("[tempo] " ++ ~bpm ++ " BPM").postln; + ~bpm; +}; + +// Protection defensive : evite la propagation si le boot reseau echoue +try { s.waitForBoot { // ----- Acid 303 ----- // Env ADSR sur l'amp avec doneAction:2 -- garanti pas de fuite @@ -294,6 +304,6 @@ s.waitForBoot { // (charges automatiquement par 00_load.scd > CHARGER TOUT) "=== setup OK -- lance le bloc PLAY ===".postln; -}; +} } { |e| ("[engine] avertissement boot serveur : " ++ e.errorString).postln }; ) diff --git a/sound_algo/tests/test_tempo.scd b/sound_algo/tests/test_tempo.scd new file mode 100644 index 0000000..0a1d091 --- /dev/null +++ b/sound_algo/tests/test_tempo.scd @@ -0,0 +1,16 @@ +// Headless test for ~setTempo. Run: sclang sound_algo/tests/test_tempo.scd +( +var ok = true; +// minimal: ~setTempo only needs TempoClock.default (always exists) +(thisProcess.nowExecutingPath.dirname.dirname ++ "/engine.scd").load; +~setTempo.(140); +if(~bpm != 140) { ok = false; "FAIL: bpm".postln }; +if(TempoClock.default.tempo.round(0.0001) != (140/60).round(0.0001)) { + ok = false; "FAIL: clock".postln }; +~setTempo.(9999); // clip high +if(~bpm != 300) { ok = false; "FAIL: clip hi".postln }; +~setTempo.(1); // clip low +if(~bpm != 20) { ok = false; "FAIL: clip lo".postln }; +if(ok) { "PASS test_tempo".postln } { "TESTS FAILED".postln }; +0.exit; +)