Commit b407cc0f by PLN (Algolia)

live: latest tracks, backlog, perf + analysis tooling

Sync-up of the workspace: edits across nova/collab tracks
(quand_on_decolle, take_5_drops, punkachien, jeudrill,
sunny_side_up, plosive, wap, perfect, techno_orage, ...),
new collab/solo pieces (mains_libres, the_revolution_will_be_sampled,
bois_bumbum, do_it_right, bullet_train), backlog/CLAUDE.md
project notes, perf.sh (CPU governor helper), and the
analyze_samples / fan_check / shipowiz tools.
parent ad30f3d5
# Sound/Tidal
ParVagues' main livecoding workspace.
## Layout
- `live/` — current set material; per-collab subdirs (`raph/`, `micka/`, `cookie/`, `baba/`, `ccc/`, `nova/`, `rhadamanthe/`)
- `copycat/` — algoraoke (cover/remix) sketches
- `tools/` — perf scripts, sample analyzers (analyze_samples, shipowiz, fan_check)
- `backlog.md` — track backlog, setlists, gig prep notes
- `perf.sh` — performance-mode optimizer (CPU governor, etc.)
- `test.tidal` — scratchpad
## Sister projects
- **`../tidal-ears/`** — audio analysis + **post-prod mastering** tooling
(Python). See `../tidal-ears/MASTERING.md` for the canonical mastering
recipe; `tidal-ears master {analyze,boundaries,mix}` is the workflow.
- `../Ardour/Tidal Multi/` — single Ardour session, records all orbits as stems
- `../Prod/` — Audacity projects + rendered masters
- `../../Tools/pulsar-parvagues-hud/` — Pulsar HUD package
## Conventions
- Channel/orbit mapping documented in `live/` patterns; LCXL CC map in memory
- Stems exported from Ardour as `Montreuil26_Tidal 01.wav` style (one per orbit)
- Visuals composited in post; OBS captures clean code only
- Rhadamanthe's master-chain notes: `live/collab/rhadamanthe/layering.tidal`
## See also
`../tidal-ears/CLAUDE.md` for the analysis/post-prod tooling docs.
...@@ -41,13 +41,6 @@ soir noir ...@@ -41,13 +41,6 @@ soir noir
-- August -- August
-- Vendredi saint & Samedi -- Vendredi saint & Samedi
# Recipe # Recipe
# To make a ParVagues live # To make a ParVagues live
...@@ -71,18 +64,17 @@ Instructions ...@@ -71,18 +64,17 @@ Instructions
4. PROFIT 4. PROFIT
# Work in progress⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ # Work in progress⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
## 26 lettres de noblesses ## 26 lettres de noblesses
## Mai fait ce qu'il te plait
-- Do it Right
-- Bois BUMBUM
## Avril la musique tient a un fil
-- Sweet Revolution
## Mars Eclosion ## Mars Eclosion
-- Bazurto
--La Cle des champs --La Cle des champs
Drums Architecte Drums Architecte
## Fevrier Vide ## Fevrier Vide
...@@ -1527,6 +1519,8 @@ url: "/home/pln/Work/Art/GLITCHWAVE/outputs/glitch_ocean_compressed.gif" ...@@ -1527,6 +1519,8 @@ url: "/home/pln/Work/Art/GLITCHWAVE/outputs/glitch_ocean_compressed.gif"
# SETLIST
# GZ AlgoRave 2025 # GZ AlgoRave 2025
...@@ -1798,7 +1792,7 @@ Sept1 ...@@ -1798,7 +1792,7 @@ Sept1
## INTRO ## INTRO
-- Quand on décolle -- Quand on décolle
-- Because it's there -- Because it's there
- Ere de jeu -- Ere de jeu
## TECHNO HIGH ## TECHNO HIGH
-- Sunny -- Sunny
-- TechnOrage -- TechnOrage
...@@ -1857,9 +1851,45 @@ Sept1 ...@@ -1857,9 +1851,45 @@ Sept1
# Montreuil Algorave V3: Mai Floral
_TechnoJazz_
BONSOIR <3
ParVagues et Shipow
[120] **Quand on Decolle** [transition into]
[124] Piment Bresilien [fade out?]
[124] *Take 5 Drops* [4+3]
[120] *Super Sunny Side* up -> [silence into 5]
[133] *W.A.P.*
[81->162] *'Plosive*
[140] **Jeudrill*
[160] *ARIA*
[170] *PunkAchien* [170-180bpm->down pure 8 breaks]
[166] *You My Sunshine*
[124] *Desire*
[124] *Blue Gold* [gagne du temps]
[~120] 6mn Sept1 <3
[104] 8m *Techno Orage*
-- Silence --
[101] 5mn **Outro: Sweet Revolution**
## Images ## Images
-- "/home/pln/Work/Art/GLITCHWAVE/outputs/digital_flow.gif" url: "/home/pln/Work/Art/GLITCHWAVE/outputs/digital_flow.gif"
-- url: "/home/pln/Work/Art/GLITCHWAVE/outputs/decolle.gif" url: "/home/pln/Work/Art/GLITCHWAVE/outputs/decolle.gif"
url: "/home/pln/Work/Web/www/next/public/images/parvagues/bg_live.gif" url: "/home/pln/Work/Web/www/next/public/images/parvagues/bg_live.gif"
url: "/home/pln/Downloads/PerfectSunriseLoop.gif" url: "/home/pln/Downloads/PerfectSunriseLoop.gif"
url: "/home/pln/Work/Art/GLITCHWAVE/outputs/bg_live4.gif" url: "/home/pln/Work/Art/GLITCHWAVE/outputs/bg_live4.gif"
......
do
setcps (120/60/4)
let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>"))
let gMute1 = (midiOn "^73" (mask "f*16"))
let gMute2 = (midiOn "^74" (mask "f*16"))
let gMute3 = (midiOn "^75" (mask "f*16"))
let gM1 = gMask . gMute1
let gM2 = gMask . gMute2
let gM3 = gMask . gMute3
let gF1 = (# djfbus 1 (range 0.05 0.95 "^49"))
let gF2 = (# djfbus 2 (range 0.05 0.95 "^50"))
let gF3 = (# djfbus 3 (range 0.05 0.95 "^51"))
let modIndex = pF "modIndex"
d1 $ gF1 $ gM1
$ "k k k k*<1 2>"
# "jazz"
# gain 1.3
d3 $ gF1 $ gM1
$ "hh*8"
# "h2ogmhh:1" # cut 3
d2 $ gF1 $ gM1
$ fast "<1!8 2!24>"
$ "~ [snare:20,cp]"
d4
$ slow 2
$ arp "updown"
$ note ("<c2 g2 c2 e2>"
+ "c'min'4/4"
)
# "bassWarsaw"
d8 $ gF1 $ gM1
$ midiOn "^60" (mask "t(4,8,1)")
$ loopAt 2
$ "jungle_breaks:45"
...@@ -183,7 +183,7 @@ d4 -- Brass voice ...@@ -183,7 +183,7 @@ d4 -- Brass voice
"", "c6@2 ~!3" -- bad "", "c6@2 ~!3" -- bad
-- 76 TODO fin -- 76 TODO fin
]) ])
# "brass" # "moogBass" -- FIXME RESTORE BRASS SAMPLES! # "moogBass" -- FIXME RESTORE BRASS SAMPLES!
# legato "<0.75!7 1>" # legato "<0.75!7 1>"
# room 0.2 # room 0.2
# gain 0.7 # gain 0.7
......
...@@ -19,6 +19,7 @@ d1 $ gF1 $ gM2 ...@@ -19,6 +19,7 @@ d1 $ gF1 $ gM2
$ fix ((|* gain 0.9) . (# lpf 1000)) "jazz" $ fix ((|* gain 0.9) . (# lpf 1000)) "jazz"
$ fix ((# att 0.02) . (# rel 0.5) . (# lpf 400)) "kick:4" $ fix ((# att 0.02) . (# rel 0.5) . (# lpf 400)) "kick:4"
$ "[808bd:1,808bd:2,jazz,kick:4]" $ "[808bd:1,808bd:2,jazz,kick:4]"
# gain 1.4
d2 $ gF1 $ gM $ "~ sn <~ [~ sn]> sn" # note "0 0 -1 0" # legato "1 1 0.75 1" d2 $ gF1 $ gM $ "~ sn <~ [~ sn]> sn" # note "0 0 -1 0" # legato "1 1 0.75 1"
# "[snare:5,snare:19]" # "[snare:5,snare:19]"
# room 0.4 # sz 0.1 # dry 1.1 # room 0.4 # sz 0.1 # dry 1.1
......
...@@ -74,7 +74,7 @@ d8 $ gF1 $ gM1 -- Break multi-facette, assez complexe, comme chacun d'entre nous ...@@ -74,7 +74,7 @@ d8 $ gF1 $ gM1 -- Break multi-facette, assez complexe, comme chacun d'entre nous
$ midiOn "^60" (mask "t(4,8,<1!3 0>)" . chop 8) $ midiOn "^60" (mask "t(4,8,<1!3 0>)" . chop 8)
$ midiOn "^36" (id . (loopAt 0.5 . (# "jungle_breaks:130"))) $ midiOn "^36" (id . (loopAt 0.5 . (# "jungle_breaks:130")))
$ midiOn "^92" (mask "t(16,32)" . ply "2 2 <4 8 16 16> 2") $ midiOn "^92" (mask "t(16,32)" . ply "2 2 <4 8 16 16> 2")
$ midiOn "^56" (loopAt 2 . (# n 12)) $ midiOn "^56" (loopAt 2 . (# n 141))
$ chop 16 $ chop 16
$ loopAt 2 $ loopAt 2
$ "jungle_breaks:1" # cut 8 $ "jungle_breaks:1" # cut 8
......
do do
resetCycles -- resetCycles
setcps (160/60/4) setcps (160/60/4)
let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>")) let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>"))
let gMute1 = (midiOn "^73" (mask "f*16")) let gMute1 = (midiOn "^73" (mask "f*16"))
......
...@@ -40,7 +40,7 @@ d3 $ gF1 $ gM1 ...@@ -40,7 +40,7 @@ d3 $ gF1 $ gM1
d4 $ gF2 $ gM3 d4 $ gF2 $ gM3
$ struct "t ~ t t ~ t ~ t?" -- Offbeat groove with probability $ struct "t ~ t t ~ t ~ t?" -- Offbeat groove with probability
$ chordsRoot -- Auto-switches at bar 32! $ chordsRoot -- Auto-switches at bar 32!
|+| n "0 7 0 <4 2> 7 0 <[0 12] [7 4]>" -- Melodic bass line |+| n "0 7 0 <4 2> 7 0 <[0 12] [7 4]>" -- Melodic bass linep
-- |+| n "0 7 4 <0 2> 7 <0 4> [7|12] 0" -- Alt: More melodic movement -- |+| n "0 7 4 <0 2> 7 <0 4> [7|12] 0" -- Alt: More melodic movement
-- |+| n "0 ~ 7 ~ [4|0] ~ 7 <0 2>" -- Alt: Sparser, half-time feel -- |+| n "0 ~ 7 ~ [4|0] ~ 7 <0 2>" -- Alt: Sparser, half-time feel
# "bassWarsaw" # "bassWarsaw"
......
do
-- resetCycles
setcps (120/60/4)
let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>"))
let gMute1 = (midiOn "^73" (mask "f*16"))
let gMute2 = (midiOn "^74" (mask "f*16"))
let gMute3 = (midiOn "^75" (mask "f*16"))
let gM1 = gMask . gMute1
let gM2 = gMask . gMute2
let gM3 = gMask . gMute3
let gF1 = (# djfbus 1 (range 0.05 0.95 "^49"))
let gF2 = (# djfbus 2 (range 0.05 0.95 "^50"))
let gF3 = (# djfbus 3 (range 0.05 0.95 "^51"))
let modIndex = pF "modIndex"
d1 $ gMute2 $ gF1 -- Kick solide
$ fix ((|* gain 0.9) . (# lpf 1000)) "jazz"
$ fix ((# att 0.02) . (# rel 0.5) . (# lpf 5000)) "kick:4"
$ midiOn "^42" (struct "t t t t*<1!6 2 2>")
$ midiOff "^42" (<| "k . ~ <~!3 k> ~ ~")
$ "[jazz,kick:4]"
# gain 1.2
-- # midiG' "^78" 0 1.5
d2$ gMute1 $ gF1 -- snare contretemps variable
$ fix ((|* gain 0.8) . (# legato 0.05)) "cp"
$ midiOn "^43" (<| "~ cp ~ cp*<1 1 2 <1 2>>")
$ midiOff "^43" (<| "~ [cp*<1!3 <2 <4 [4 2]>>> ~]")
$ "[vec1_claps:10]"
-- # pan 0.65
# gain 1.5
-- # legato 0.22
d3 $ gM1 $ gF1
$ "~ d ~ d ~ d ~ <d!12 [~ d]!3 [d d]>"
# "jazz:4"
# gain 1.4
# legato 0.3
# cut 3
d4 $ gF1 $ gM1
$ note ("<e3 b3 e3 g3>" - 12)
# "bassWarsaw"
# gain 1.3
# crushbus 41 (range 16 3.5 "^53")
# octersubbus 42 (range 0 1.5 "^33")
d5 $ gF1 $ gM1
-- $ midiOn "^90" (ply "4")
$ midiOn "^90" (stut 4 0.9 "q")
$ midiOn "^58" (slice 8 "<4 4 <4 5> 6>") -- Phase 2
$ midiOff "^58" (slice 16 "<[1 2] [1 2] [1 2] [3 4]>") -- Phase1
$ "latin:0"
# cut 5
# gain 1.2 # room 0.3 # sz 0.9 # lpf 4000
-- # begin 0.05
d8 $ gF1 $ gM1
$ midiOn "^92" (ply "1 <2!3 4>")
$ midiOff "^60" (mask "t(4,8,1)") -- Techno drum mask
$ midiOn ("^36" - "^56") ((# n "22")) -- Hmmm Break
$ midiOn "^56" ((# n "23")) -- Raise COMEON!
$ chop 16
$ loopAt 2
$ "jungle_breaks:45"
# cut 8
# gain 1.5
do
-- resetCycles
let gF1 = (# djfbus 1 (range 0.1 0.9 "^49"))
let gF2 = (# djfbus 2 (range 0.05 0.95 "^50"))
let gF3 = (# djfbus 3 (range 0.05 0.95 "^51"))
let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>"))
let gMute = (midiOn "^73" (mask "f*16"))
let gMute2 = (midiOn "^74" (mask "f*16"))
let gMute3 = (midiOn "^75" (mask "f*16"))
let gM1 = gMask . gMute
let gM2 = gMask . gMute2
let gM3 = gMask . gMute3
let gMaskEnd16 = mask "<t!7 [<t f> <f t> ]>"
setcps (165/60/4)
-- d1 $ gF1 $ gM2
d1
$ gF1 $ gMute2
-- $ midiOff "^42" (<| "<k [~!7 k*<1 2>]>")
$ midiOff "^42" (<| "k . ~ k ~ ~")
$ midiOn "^42" (<| "k k . k <k [~ k] k k*2>")
$ "popkick:2"
-- # lpf 300 -- TODO Sound design this kick <3
-- # cut 1
# gain 2
d2 $ gF1 $ gM1
$ midiOff "^43" (<| "~ s ~ s*<1!3 2>")
$ midiOn "^43" (<| "~ . s*<1!3 2> ~")
$ "[realclaps:0]"
-- # "h2ogmcp"
-- # gain (1.0 * "<[1]!16 [1 <1 <1 [1 0.93] 1 [0.9]>>]!16>")
# gain 1.2
-- # room 0.5 # dry 1.1
-- # delay "<0!15 0.6!1>"
-- # delayt 0.25
d3 $ gF1 $ gM1
$ "~ h ~ h*<1!8 2!8> ~ h*<1 1 1> ~ h"
-- $ "h(3,8) h(3,8)"
-- # pan "0.2 0.8"
# "h2ogmhh:2"
# gain 1.3
# hpf 1500
-- # att 0.03 # rel 0.9
-- # legato (range 0.05 0.9 "^32")
d4 $ gF2 $ gM2
$ note ("<cs4 <c4 f4> [gs3@3 <~ bf3>] f3>" -12)
# "bassWarsaw"
# gain 1.3
# cut 4
# room 0.3
d5 $ gF2 $ gM2
$ note (
"<cs4 c4 [gs3@3 bf3] f3>"
+ (arp "up" "c'maj'4 c'maj'4")
)
# "FMRhodes1"
# modIndex (range 0 16 "^54")
# gain 1.3
# cut 5
# room 0.3
d8 $ gF1 $ gM1 $ loopAt 2
$ chop 8 $ "jungle_breaks:74" # cut 8
d4 $ gF2 $ gM3
-- $ midiOn "^57" (
-- superimpose (("e" ~>) .(|+ note 12) . (# cut 41)))
$ note ("0(3,8) . 0(3,8)" + "d"
+ "<0 0 0 0 7 7 5 0>"
)
-- # "moog:1"
# "bassWarsaw" |- note 36
# crushbus 41 (range 16 3.5 "^53")
# pan 0.4
# cut 4
# gain 1.5
d5 $ gF3 $ gM3 -- Les ptites keys de fin de session tranquilou
-- $ midiOn "^90" (ply "4 <8 16>")
$ slow 2
$ slice 8 "<0 1 2 3 4 5 6 7>"
$ "gfunk_lead:13" # cut 4
# gain 1.8
# crushbus 51 (range 16 3.5 "^54")
# pan 0.9
# room 0.3
d7 $ gF3 $ gM3 $ "trance_amb:0/2" # cut 7
d8 $ gF1 $ gM1
$ midiOff "^60" (mask "t(4,8,1)") -- Techno drum mask
$ midiOn "^36 " (loopAt 4 . (# "jungle_breaks:22")) -- Raise COMEON!
$ midiOn "^56" (loopAt 4 . (# "jungle_breaks:23")) -- Raise COMEON!
$ midiOn "^92" ( -- Bouton Nassim <3
slice 16 "[0 .. 7] . <[0 .. 7]!3 [0 1 . [2 3]]>"
. loopAt 1 . (# "breaks165")
-- . (# octer 0.4) . ( octersubsub 4)
. (# lpf 2500)
. (# room 0)
)
$ chop 16
$ loopAt 1
$ "breaks165"
# cut 8
# octersub 0.5
# gain 1.2
d9 $ gF3 $ gM3
$ midiOn "^19" (ply "4 8")
$ midiOff "^18" (mask "<f!3 t>")
$ "ouais" # n (slow 4 "<0 1 2 3>" )
# cut 9
# end "<1!12 0.47!3 1>"
# room 0.4
# gain 1.4
once $ "rampleS21:0"
...@@ -31,7 +31,7 @@ d3 $ gF1 $ gM1 ...@@ -31,7 +31,7 @@ d3 $ gF1 $ gM1
) )
$ midiOn "^44" (<| "~ h ~ h ~ h*<1!3 2> ~ h*<1 [1|2]>") $ midiOn "^44" (<| "~ h ~ h ~ h*<1!3 2> ~ h*<1 [1|2]>")
$ "h2ogmhh" # n "<0!4 1!3 2>" $ "h2ogmhh" # n "<0!4 1!3 2>"
# gain (1.4 * (range 0.9 1.2 perlin)) # gain (0.9 * (range 0.9 1.2 perlin))
d4 $ gF2 $ gM3 d4 $ gF2 $ gM3
$ midiOn "^89" (ply 4) $ midiOn "^89" (ply 4)
$ slow 2 $ note ("<[e3@7 f3]!4 [b2@7 c2]!4>") $ slow 2 $ note ("<[e3@7 f3]!4 [b2@7 c2]!4>")
...@@ -58,10 +58,12 @@ d5 $ gF2 $ gM3 -- ...@@ -58,10 +58,12 @@ d5 $ gF2 $ gM3 --
# gain 1.4 # gain 1.4
# squizbus 51 (range 0 2.5 "^54") # squizbus 51 (range 0 2.5 "^54")
d7 $ gF3 $ gM3 d7 $ gF3 $ gM3
$ midiOn "^89" (ply 4) $ midiOn "^91" (ply 4)
-- $ slow 2 -- $ slow 2
$ note ( $ note (
"<e3!4 b2!4>") "<e3!4 b2!4>"
+ (arp "up" "c'majPent'4")
)
# "acidOto3091" # "acidOto3091"
# cut 4 # cut 4
# crushbus 41 (range 16 2.5 "^53") # crushbus 41 (range 16 2.5 "^53")
......
do do
-- resetCycles resetCycles
setcps (129/60/4) setcps (129/60/4)
d1 $ gF1 $ gMute2 -- KICK: Sub thud, 4otf with flourish (NTO: deepens over time) d1 $ gF1 $ gMute2 -- KICK: Sub thud, 4otf with flourish (NTO: deepens over time)
$ midiOn "^42" (<| "k k k <k k*2 k [~ k]>") -- ON: 4otf + flourish variations $ midiOn "^42" (<| "k k k <k k*2 k [~ k]>") -- ON: 4otf + flourish variations
......
...@@ -36,7 +36,7 @@ d3 $ gF1 $ gM1 ...@@ -36,7 +36,7 @@ d3 $ gF1 $ gM1
-- $ "h(3,8) h(3,8)" -- $ "h(3,8) h(3,8)"
# pan "0.2 0.8" # pan "0.2 0.8"
# drumFrom "rolandtr909" "hh:2" # cut 3 # drumFrom "rolandtr909" "hh:2" # cut 3
# gain 1.2 # gain 1.3
# legato (range 0.05 0.9 "^32") # legato (range 0.05 0.9 "^32")
d9 -- Bogdan the Grime sample provider d9 -- Bogdan the Grime sample provider
$ whenmod 16 12 ( -- I'm from Cardiff! $ whenmod 16 12 ( -- I'm from Cardiff!
...@@ -91,8 +91,8 @@ d5 $ gM3 $ gF3 -- Marimba fondamental ...@@ -91,8 +91,8 @@ d5 $ gM3 $ gF3 -- Marimba fondamental
# rel 1 # rel 1
-- # squizbus 51 (range 0 2.5 "^54") -- # squizbus 51 (range 0 2.5 "^54")
-- # delay 0 # delayfb 0.8 # delayt 0.25 -- # delay 0 # delayfb 0.8 # delayt 0.25
# pan 0.9 # pan 0.8
# gain 1.6 # gain 2
# room 0.3 # room 0.3
d10 $ gF3 $ gM3 -- Menace d10 $ gF3 $ gM3 -- Menace
$ someCyclesBy "<1!16 1!32 0!16>" (>| note "<b3 ~ ~ <[~!7 c4] [~!5 c4 ef4 <c4 fs4>]>>") $ someCyclesBy "<1!16 1!32 0!16>" (>| note "<b3 ~ ~ <[~!7 c4] [~!5 c4 ef4 <c4 fs4>]>>")
......
...@@ -22,7 +22,7 @@ d2 $ gF1 $ gM1 ...@@ -22,7 +22,7 @@ d2 $ gF1 $ gM1
# octersub 0 # octersub 0
# octersubsub 0 # octersubsub 0
# pan 0.25 # pan 0.25
-- # lpf 3000 -- # lpf 3000
d3 $ gF1 $ gM1 d3 $ gF1 $ gM1
$ midiOn "^76" (ply 2) $ midiOn "^76" (ply 2)
$ sometimesBy "0 <0.5!3 2>" (mask "t(<12!3 2>,16)") $ sometimesBy "0 <0.5!3 2>" (mask "t(<12!3 2>,16)")
......
...@@ -16,20 +16,24 @@ d1 $ gF1 $ gM2 ...@@ -16,20 +16,24 @@ d1 $ gF1 $ gM2
# gain 1.7 # gain 1.7
# lpf 400 # lpf 400
d2 $ gF1 $ gM1 d2 $ gF1 $ gM1
$ midiOn "^43" (mask "[t <f t!3>] [t <f t>]" . fast 2)
$ "~ s ~ [s*<1 2> <~ s*<2 [4 2]>>]" $ "~ s ~ [s*<1 2> <~ s*<2 [4 2]>>]"
# "vec1_claps" # n 10 # "vec1_claps" # n 10
# gain 1.3 # gain 1.3
# lpf 2000 # lpf 2000
d3 $ gF1 $ gM1 d3 $ gF1 $ gM1
$ midiOn "^44" (<| "[~ h*<1!3 <1 2 [4 2] 1?>>]*4" ) $ midiOn "^44" (<| "[~ h*<1!3 <1 2 [4 2] 1?>>]*4" )
$ midiOff "^44" (<| "h(4,8,1)") $ midiOff "^44" (<| "h(3,8) h([3 1 3],8)")
$ "h2ogmhh" $ "h2ogmhh"
# gain 1.4 # gain 1.4
# room 0.3 # room 0.3
# dry (slow 16 $ range 0.2 1.8 perlin) # dry (slow 16 $ range 0.2 1.8 perlin)
# legato (range 0.05 2 "^52")
# sz 0.4 # sz 0.4
d4 $ gF3 $ gM3 d4 $ gF2 $ gM3
$ struct "t . t(<1 3 5>,8)" $ midiOn "^89" (struct "t . t(<1 3 5>,8)")
$ midiOn "^57" (struct "t . t(<1 3 5>,8)")
$ midiOff "^57" (struct "<t!3 t*[<4 8> [8 <8 16>]]>")
$ note ( $ note (
"<bf2 bf2 bf2 [bf2@7 cs3]>" "<bf2 bf2 bf2 [bf2@7 cs3]>"
+ "[0,12]" + "[0,12]"
...@@ -39,6 +43,7 @@ d4 $ gF3 $ gM3 ...@@ -39,6 +43,7 @@ d4 $ gF3 $ gM3
-- |+ note 12 -- |+ note 12
# room 0.3 # room 0.3
# crushbus 41 (range 16 3.5 "^53") # crushbus 41 (range 16 3.5 "^53")
# octerbus 42 (range 0 1.85 "^33")
# room 0.2 # dry 1.2 # sz 0.7 # room 0.2 # dry 1.2 # sz 0.7
# gain 1.4 # gain 1.4
d5 $ gF3 $ gM3 -- LE PIMENT BRESILIEN d5 $ gF3 $ gM3 -- LE PIMENT BRESILIEN
...@@ -51,7 +56,7 @@ d5 $ gF3 $ gM3 -- LE PIMENT BRESILIEN ...@@ -51,7 +56,7 @@ d5 $ gF3 $ gM3 -- LE PIMENT BRESILIEN
# gain 1.7 # gain 1.7
# room 0.3 # room 0.3
# octerbus 51 (range 0 1.4 "^54") # octerbus 51 (range 0 1.4 "^54")
# octersubbus 52 (range 0 2 "^34") # octersubbus 52 (range 0 4 "^34")
d7 $ gF3 $ gM3 d7 $ gF3 $ gM3
$ midiOn "^91" (ply 2) $ midiOn "^91" (ply 2)
$ note ("[f3 cs3 c3 cs3 f3 cs3 <c3 f3> <cs3 fs3>]" $ note ("[f3 cs3 c3 cs3 f3 cs3 <c3 f3> <cs3 fs3>]"
...@@ -83,6 +88,7 @@ d8 $ gF1 $ gM1 -- La Boite à breaks de ParVagues <3 ...@@ -83,6 +88,7 @@ d8 $ gF1 $ gM1 -- La Boite à breaks de ParVagues <3
$ "jungle_breaks:45" $ "jungle_breaks:45"
# cut 8 # cut 8
# gain 1.4 # gain 1.4
# pan "0.5!3 <0.2 0.8>"
-- --
-- --
-- --
......
...@@ -81,7 +81,7 @@ d8 $ gF1 $ gM1 ...@@ -81,7 +81,7 @@ d8 $ gF1 $ gM1
. (# lpf 2500) . (# lpf 2500)
. (# room 0) . (# room 0)
) )
$ midiOff "^60" (mask "f(8,16)" . chop 16) $ midiOn "^60" (mask "f(8,16)" . chop 16)
$ midiOn "^56" (# "jungle_breaks:7") $ midiOn "^56" (# "jungle_breaks:7")
$ midiOn "^36" (# "jungle_breaks:37") $ midiOn "^36" (# "jungle_breaks:37")
$ chop 16 $ "jungle_breaks:101" $ chop 16 $ "jungle_breaks:101"
......
-- url: "/home/pln/Work/Art/GLITCHWAVE/outputs/decolle.gif" -- url: "/home/pln/Work/Art/GLITCHWAVE/outputs/decolle.gif"
do do
resetCycles -- resetCycles
setcps (120/60/4) setcps (120/60/4)
let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>")) let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>"))
let gMute = (midiOn "^73" (mask "f*16")) let gMute = (midiOn "^73" (mask "f*16"))
...@@ -16,7 +16,7 @@ d1 $ gF1 $ gM2 ...@@ -16,7 +16,7 @@ d1 $ gF1 $ gM2
$ fix ((|* gain 0.9) . (# lpf 1000)) "jazz" $ fix ((|* gain 0.9) . (# lpf 1000)) "jazz"
-- $ fix ((# att 0.02) . (# rel 0.5) . (# lpf 400)) "kick:4" -- $ fix ((# att 0.02) . (# rel 0.5) . (# lpf 400)) "kick:4"
$ "[jazz,kick:4]" $ "[jazz,kick:4]"
# gain 1.1 # gain 1.4
# lpf 300 # lpf 300
d2 $ gF1 $ gM1 d2 $ gF1 $ gM1
$ midiOff "^43" (<| "~ . s@3 <~ s*<1 <2 [4 2]>>>") $ midiOff "^43" (<| "~ . s@3 <~ s*<1 <2 [4 2]>>>")
...@@ -33,7 +33,7 @@ d3 $ gF1 $ gM1 ...@@ -33,7 +33,7 @@ d3 $ gF1 $ gM1
# att (slow 32 $ range 0.4 0.04 saw) # att (slow 32 $ range 0.4 0.04 saw)
# rel 2 # rel 2
# room 0.2 # dry 1.3 # room 0.2 # dry 1.3
# gain 1.6 # gain 1.9
d4 $ gF2 $ gM3 d4 $ gF2 $ gM3
$ midiOn "^57" (sometimesBy 0.5 ((|- note 12) . (# cut 41))) $ midiOn "^57" (sometimesBy 0.5 ((|- note 12) . (# cut 41)))
$ midiOn "^89" (ply 2) $ midiOn "^89" (ply 2)
...@@ -60,13 +60,13 @@ d5 $ gF3 $ gM3 ...@@ -60,13 +60,13 @@ d5 $ gF3 $ gM3
# room 0.4 # sz 0.8 # dry 1.1 # room 0.4 # sz 0.8 # dry 1.1
-- # crushbus 51 (range 16 3.5 "^54") -- # crushbus 51 (range 16 3.5 "^54")
d7 $ gF3 $ gM3 d7 $ gF3 $ gM3
-- $ midiOn "^91" (ply "<2 4 <8 [16 8]>>") $ midiOn "^91" (ply "<2 4 <8 [16 8]>>")
-- $ slow 4 -- $ slow 4
$ midiOn "^55" (slow 4) $ midiOn "^59" (slow 4)
-- $ slice 16 (run 6) -- $ slice 16 (run 6)
$ slice 16 (8 + (slow 2 $ "<0 4 8 12>")) $ slice 16 (8 + (slow 2 $ "<0 4 8 12>"))
$ "airports" # cut 5 # speed 0.5 $ "airports" # cut 5 # speed 0.5
# gain 1.2 # gain 1.4
# room 0.4 # room 0.4
# att 0.02 # att 0.02
# rel 2 # rel 2
......
...@@ -27,6 +27,7 @@ d2$ gMute1 $ gF1 -- snare contretemps variable ...@@ -27,6 +27,7 @@ d2$ gMute1 $ gF1 -- snare contretemps variable
$ midiOff "^43" (<| "~ [cp*<1!3 <2 <4 [4 2]>>> ~]") $ midiOff "^43" (<| "~ [cp*<1!3 <2 <4 [4 2]>>> ~]")
$ "[cp,snare:24]" $ "[cp,snare:24]"
# pan 0.65 # pan 0.65
# gain 1.4
-- # legato 0.22 -- # legato 0.22
d3 $ gM1 $ gF1 d3 $ gM1 $ gF1
$ "~ d ~ d ~ d ~ <d!12 [~ d]!3 [d d]>" $ "~ d ~ d ~ d ~ <d!12 [~ d]!3 [d d]>"
......
do do
resetCycles -- resetCycles
setcps (120/60/4) setcps (120/60/4)
let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>")) let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>"))
let gMute1 = (midiOn "^73" (mask "f*16")) let gMute1 = (midiOn "^73" (mask "f*16"))
......
...@@ -21,7 +21,7 @@ d2 $ gF1 $ gM1 -- Snare FOU ...@@ -21,7 +21,7 @@ d2 $ gF1 $ gM1 -- Snare FOU
$ midiOn ("^43" - "^75") (<| "~ s ~ <s s*<1!7 2> s s*2>") $ midiOn ("^43" - "^75") (<| "~ s ~ <s s*<1!7 2> s s*2>")
$ midiOff ("^43"- "^75") (<| "~ s") $ midiOff ("^43"- "^75") (<| "~ s")
$ "[sn:25,gretsch:4]" $ "[sn:25,gretsch:4]"
# note (range "-4" 4 "^51") show # note (range "-4" 4 "^51")
# gain 0.7 # gain 0.7
d3 $ gF1 $ gM1 d3 $ gF1 $ gM1
$ midiOn "^44" (ply "1 2 1 <2 <1 4>>") $ midiOn "^44" (ply "1 2 1 <2 <1 4>>")
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
once $ "xplosive" -- RIFF once $ "xplosive" -- RIFF
# cut 1 -- # cut 6
# orbit 4
# lpf 400 # lpf 400
# room 1 # room 1
-- # freeze 0.2 -- # freeze 0.2
...@@ -17,7 +18,7 @@ once $ "xplosive" -- RIFF ...@@ -17,7 +18,7 @@ once $ "xplosive" -- RIFF
once $ "xplosive:3" -- HOES once $ "xplosive:3" -- HOES
# gain 0.9 # cut 7 # gain 0.9 # orbit 4
-- REAL SMOKERS -- REAL SMOKERS
do do
...@@ -88,7 +89,7 @@ d7 $ gF3 $ gM3 -- VOICES ...@@ -88,7 +89,7 @@ d7 $ gF3 $ gM3 -- VOICES
# gain 1.2 # gain 1.2
d8 $ gF1 $ gM1 d8 $ gF1 $ gM1
$ midiOff "^60" (mask "t(8,16,1)" . chop 8) $ midiOff "^60" (mask "t(8,16,1)" . chop 8)
$ chop 8 $ chop 8
$ loopAt 0.5 $ loopAt 0.5
$ midiOn "^36" (loopAt 2 . (# "jungle_breaks:39")) $ midiOn "^36" (loopAt 2 . (# "jungle_breaks:39"))
$ midiOn "^56" (loopAt 2 . (# "jungle_breaks:42")) $ midiOn "^56" (loopAt 2 . (# "jungle_breaks:42"))
......
...@@ -31,7 +31,6 @@ d4 $ gF2 $ gM3 -- WAP BASS ...@@ -31,7 +31,6 @@ d4 $ gF2 $ gM3 -- WAP BASS
$ midiOn "^57" ( $ midiOn "^57" (
slice 8 ("~ 0 <~ ~ 5 5> 3 <~ 0!3> <~!4 0!10 ~ 0*4> 5 <~ 5>") slice 8 ("~ 0 <~ ~ 5 5> 3 <~ 0!3> <~!4 0!10 ~ 0*4> 5 <~ 5>")
-- $ (0.125 ~>) : -- $ (0.125 ~>) :
. (# gain 1.3 ) . (# gain 1.3 )
. (# crushbus 43 (range 16 3.4 "^53") ) . (# crushbus 43 (range 16 3.4 "^53") )
. (# lpf 3000) . (# lpf 3000)
...@@ -55,7 +54,7 @@ d5 $ gF3 $ gMute3 -- WAP HOES v1 magic repeat ...@@ -55,7 +54,7 @@ d5 $ gF3 $ gMute3 -- WAP HOES v1 magic repeat
$ midiOn "^58" (stut "4" 0.9 (fast 4 "e")) $ midiOn "^58" (stut "4" 0.9 (fast 4 "e"))
$ midiOn "^90" ( $ midiOn "^90" (
ply "[1!3 4]*4" . chop 4 . -- Magic Repeat: next segment instead ply "[1!3 4]*4" . chop 4 . -- Magic Repeat: next segment instead
stut "4" 0.9 (fast 4 "s") -- Magic Repeat: repeater stut "2" 0.9 (fast 2 "s") -- Magic Repeat: repeater
. (# att 0.08) . (# att 0.08)
. (# rel 10) . (# rel 10)
) )
......
do
-- resetCycles
setcps (114/60/4)
d1 $ gF1 $ gM2
$ sometimesBy "^30" (fast 2)
$ midiOn "^42" (<| "k k k k*2")
$ midiOff "^42" (<| "k . k(3,8)")
$ stack [
"kick:5" # gain 1.4 # lpf 200, -- character (KICK16, click+body)
"bd:5" # gain 1.0 # lpf 90 # hpf 25 -- sub thump (90% sub @ 43Hz)
]
-- alt punchier replacement: "hardkick:5" (sub + 9% mid click, distorted)
d2 $ gF1 $ gM1
$ midiOn "^43" (<| "~ <s!4 [~ s] s s s*2> ~ <s [s s*<1 2>]>")
$ midiOff "^43" (<| "~ s")
$ stack [
"cp:1" # gain 1.05 # speed 0.95, -- 80s hand clap (HANDCLPA)
"snare:54" # gain 0.65 # hpf 280, -- existing snare, crack only
"808sd:5" # gain 0.5 # hpf 180 -- 808 body underneath
]
-- # room 0.45 # sz 0.55
-- # delay 0.2 # delayt "e" # delayfb 0.25
d3 $ gF1 $ gM1
$ stack [
-- light closed offbeats, velocity-layered
"~ h ~ h ~ h ~ h*<1 1 2 [2 4]>"
# n "<2 3 4 3>" -- Med/Soft/Softest closed
# gain (range 0.42 0.62 (slow 5 sine)),
-- open hat once every 4 cycles, last 8th note (NTO breath)
"~ ~ ~ ~ ~ ~ ~ <~!3 1>"
# n 7 -- HatOpen-Med
|* gain 0.65
]
# s "h2ogmhh"
# gain 1.4
d4 $ gF2 $ gM3
$ midiOn "^57" (# n 3)
$ midiOff "^57" ( -- MONTEE
whenmod 16 12 (# n "<[1 2] 2*2>"))
$ midiOff "^57" (slice 4 "<[0 1] [2 3]>")
$ "like_sugar:0" # cut 4
# gain 1.4
-- # room 0.3 # sz 0.3
-- # delay 0.6 # delayt 0.01 # delayfb 0.2
# crushbus 41 (range 16 3.5 "^53")
# bandf (range 50 1200 "^33")
d5 $ gF3 $ gM3
$ slow 2 -- Adjusted to Sugar rhytm <3
$ midiOn "^90" (ply "<4!3 8>" . (# begin "0 <0 0.25> 0.5 0.5"))
-- $ ply 4
-- $ slow 4
$ fix (# begin "<0 0 [0@3 0.7] 0.7>") (n 12) -- Sex appeal
$ fix (# begin "<0!3 [0.7!3 0.55]>") (n 13) -- Sex appeal
$ n (cat [
"0", "~" , "0" , "~ [0*[4 2] ~]", -- Brother
"1", "1 2", "2 0", "2", -- You can't plug out
"~", "~", "3", "~", -- Lose yourself
"4", "~", "<5 <19 21>>", "~", -- Revolution
"6", "~", "6", "~", -- Commercials
"7", "8", "9", "10", -- Nixon
"31", "~", "~", "~", -- NOT BE TELEVISED
"11", "12", "12@3 12", "12*[4 4 [4 8] [8 16]]", -- Sex Sex!!
"13", "~", "13", "13*[4 4 8 4]", -- The Nubs
"14", "15", "~", "0", -- Not five pounds thinner
"16", "17", "18", "19" -- STOLEN AMBULANCE
])
# "the_revolution"
# cut 5
# gain 1.5
-- # end 0.6
-- # begin 0.65
-- # begin 0.82
# room 0.4
# sz 0.4
# delayt "q"
# delay (slow 8 $ range 0 0.9 perlin)
# delayfb (slow 16 $ range 0 0.24 perlin)
# pan 0.8
d7 $ gF2 $ gM3 -- LEAD: Rhodes arp in D Dorian (i7 → IV7 → bIII → v)
$ midiOn "^59" (jux rev)
$ midiOff "^59" (degradeBy 0.15)
$ sometimesBy "^31" (# squiz "<1 2 3 1>")
$ fast 2
$ arp "<up updown down converge up updown thumbup converge>"
$ note "<d3'min7 g3'7 f3'maj7 a3'min7>"
# s "FMRhodes1"
# cutoff (range 1200 4500 "^54")
# resonance (range 0.1 0.3 "^55")
# room 0.6 # sz 0.5
# delay 0.5 # delayt "q" # delayfb 0.35
# pan 0.3
# gain 1.1
# modIndex (slow 16 $ range 0.4 2.5 perlin)
# legato 0.9
d8 $ gF1 $ gM1
$ midiOn "^92" (ply "<2 <4 [4 8]>>")
$ midiOff "^60" (mask "t(8,16,1)" . chop 16)
$ chop 16
$ loopAt 2
$ midiOn "^36" (# n "102")
$ midiOn "^56" (loopAt 0.5 . (# n "42"))
$ "jungle_breaks:45"
# cut 8
# gain 1.3
# lpf 4000
d9 $ gF3 $ gM3 -- SUGAR CHOIR
$ "like_sugar/2"
# n (slow 2 "<9 10 11 12 9 10 11 12 12 12 12 13 12 14 15 16>")
# cut 9
# room 0.4 # sz 0.3
d10 $ gF3 $ gM3 -- SUGAR KEY SWEET TRIGGER
$ "like_sugar:21"
-- # end 0.92 # speed 1.2
# room 0.4 # sz 0.4 # dry 0.9
# cut 10
d11 $ gF3 $ gM2 -- SUGAR GLITCH: stuttered chops + bitcrush
-- $ midiOn "^61" (stut 4 0.6 0.125)
-- $ sometimesBy "^31" (hurry "<1 2 0.5 [2 4]>")
$ every 4 (rev . chop 32)
$ chop "<8 16 [16 32] 8>"
$ "like_sugar/2"
# n "<10 11 12 9 13 14 15 16>"
# cut 11
-- # coarse (slow 4 $ range 0 10 sine)
-- # squiz "<1 1 2 1>"
-- # crush (range 12 6 "^59")
# room 0.3 # sz 0.5
# delay 0.3 # delayt "e" # delayfb 0.4
# pan "<0.35 0.65>"
# gain 1.0
d12 -- HEY HEY!
$ chop 8
$ "like_sugar:20/4"
# room 0.5
# gain 0.8
# pan "[0.2 0.8]*8"
once $ "bumbum"
do
setcps (135/60/4)
d1 $ gF1 $ gM2
$ midiOn "^41" (mask "<t f> <f!3 [f t]>")
$ midiOn "^42" (<| "k k k k")
$ midiOff "^42" (<| "k . k(<3!7 8>,<9 8 8 9>)")
$ "[rampleK2,jazz]"
# gain 1.3
d2 $ gM1 $ gF1
$ "~ s ~ <s <s*2 [s s s ~]>>"
# "[rhadamanthe_fx:187,realclaps]" -- POPPING SNARE
# begin 0.048 # end 0.055
# gain 3
# room 0.4 # sz 0.8 # dry 1
d3 $ gM1 $ gF1 $ "hh(3,8) hh(3,8)"
# "rampleS20:3"
# gain 1.8
d4 $ note "<as2 [a2@3 <~ [cs2 c3]>]>"
# "bassWarsaw"
# gain 1.3
d5 $ gF3 $ gM3
-- $ slice 2 "<0 1>" $ n "<8!4 9!4>" # "bumbum" -- WAIT
$ slice 2 "<0 1>" $ n (slow 2 $ "<4 5 6 7>") # "bumbum" -- RUN
# cut 5
# gain 1.4
d7 $ gF3 $ gMute3
$ midiOn "^91" (ply 4)
$ midiOn "^35" ((>| "bumbum:25") . (# begin 0.08))
$ fix ("s" <~) (n 10) -- Calage
$ fix (0.5 ~>) (n 11) -- Calage
$ fix (0.25 ~>) (n 12) -- Calage
$ fix (0.25 ~>) (n 13) -- Calage
$ fix (0.25 ~>) (n 14) -- Calage
$ slice 2 "<0 1>"
-- $ n (slow 2 $ "<10 11 12 13 14 15 16 17>" ) -- Wait1
-- $ n (slow 2 $ "<13 13 ~ ~ 15 16 15 16>") -- Wait2
-- $ n (slow 2 $ "<17 17 18 18 17 17 18 19>") -- CALL
-- $ n (slow 2 $ "<<20 21> <20 22> 20 <19 21 24 25>>") -- BOM BOM
-- $ n (slow 2 $ "<<20 21> <20 22> 20 <19 21 24 25>>") -- BOM BOM
$ n (slow 2 $ "<10 11 12 13 14 15 16 17 13 13 ~ ~ 15 16 15 16 17 17 17 17 18 18 17 17 18 19 20 20 20 19 21 22 23 24>") -- CALL
# "bumbum"
-- # cut 7
# gain 1.3
d8 $ gF1 $ gM1 $ loopAt 4
$ chop 16
$ "jungle_breaks:123"
# gain 1.2
d9 $ gF3
$ mask "t <f t>"
$ ply 2
$ n "<0 ~ ~ 1 0 ~ 3 ~ 0 <1 3> <[2 3 2 3] [~@3 2*2]> 3 ~>"
# "bumbum" # cut 9
# gain 1.3
...@@ -16,7 +16,7 @@ let lagTime = pF "lagTime" ...@@ -16,7 +16,7 @@ let lagTime = pF "lagTime"
let filterRange = pF "filterRange" let filterRange = pF "filterRange"
d1 $ gF1 $ gM2 d1 $ gF1 $ gM2
$ midiOn "^42" (<| "k k k k*2") $ midiOn "^42" (<| "k k k k*2")
$ midiOff "^42" (<| "k") $ midiOff "^42" (<| "k . ~!3 <~ [~|k?]!6 k>")
-- $ fix ((|* gain 0.9) . (# lpf 1000)) "jazz" -- $ fix ((|* gain 0.9) . (# lpf 1000)) "jazz"
$ fix ((# att 0.02) . (# rel 0.5) . (# lpf 400)) "kick:4" $ fix ((# att 0.02) . (# rel 0.5) . (# lpf 400)) "kick:4"
$ "[kick:4,jazz]" $ "[kick:4,jazz]"
...@@ -40,7 +40,7 @@ d3 $ gF1 $ gM -- Hats closed legers ...@@ -40,7 +40,7 @@ d3 $ gF1 $ gM -- Hats closed legers
|* gain 1.5 * ("~ 1 ~ 0.9 ~ 1 ~ 0.8") |* gain 1.5 * ("~ 1 ~ 0.9 ~ 1 ~ 0.8")
d6 $ gF1 $ gM -- Hats closed legers d6 $ gF1 $ gM -- Hats closed legers
$ midiOff "^44" (mask "t(4,8)") $ midiOff "^44" (mask "t(4,8)")
$ "h2ogmhh:5*8" $ "h2ogmhh:5*8" -- FIXME: "C'est pas le meilleur celui-la -- DJ Micka"
# legato 0.5 # legato 0.5
# note "<2!2 -1!2>" # note "<2!2 -1!2>"
# room 0.3 # sz 0.13 # dry 1.1 # room 0.3 # sz 0.13 # dry 1.1
...@@ -98,7 +98,7 @@ d7 $ gM3 $ gF2 -- LA ACID BASS ARE YOU SUNNY NOW ?? <3 ...@@ -98,7 +98,7 @@ d7 $ gM3 $ gF2 -- LA ACID BASS ARE YOU SUNNY NOW ?? <3
-- "[0*4]*<2!2 <2 4> [2 4]>" -- Mechanic rhytm -- "[0*4]*<2!2 <2 4> [2 4]>" -- Mechanic rhytm
"0(3,8) 0(<3!3 5>,8)" "0(3,8) 0(<3!3 5>,8)"
+ "f gs c g" + "f gs c g"
+ 12 -- + 12
-- + 1 -- Calage -- + 1 -- Calage
) )
-- # "vec1_acid:21" |+ note 1 -- Option 1: Samples ACIDES -- # "vec1_acid:21" |+ note 1 -- Option 1: Samples ACIDES
......
do do
-- resetCycles
setcps (124/60/4) setcps (124/60/4)
let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>")) let gMask = (midiOn "^41" (mask "t . <f t f <f t>> <t f f <t f>>"))
let gMute1 = (midiOn "^73" (mask "f*16")) let gMute1 = (midiOn "^73" (mask "f*16"))
...@@ -9,6 +10,7 @@ let gM2 = gMask . gMute2 ...@@ -9,6 +10,7 @@ let gM2 = gMask . gMute2
let gM3 = gMask . gMute3 let gM3 = gMask . gMute3
d1 $ gF1 $ gM2 d1 $ gF1 $ gM2
$ midiOn "^42" (<| "k k k <k [<~!3 k> k]>") $ midiOn "^42" (<| "k k k <k [<~!3 k> k]>")
$ midiOn "^42" (<| "k k k <k [<~!3 k> k]>")
$ midiOff "^42" (<| "k . <[~ k] k(<3 5>,8)>") $ midiOff "^42" (<| "k . <[~ k] k(<3 5>,8)>")
$ "[techno:0,808bd:2,909,kick:4]" $ "[techno:0,808bd:2,909,kick:4]"
-- $ "kick:5" -- $ "kick:5"
...@@ -21,8 +23,8 @@ d2 $ gF1 $ gM1 ...@@ -21,8 +23,8 @@ d2 $ gF1 $ gM1
# gain 1.3 # gain 1.3
# lpf 2000 # lpf 2000
d3 $ gF1 $ gM1 d3 $ gF1 $ gM1
$ midiOn "^44" (<| "[~ h*<1!3 <1 2 [4 2] 1?>>]*4" ) $ midiOn "^44" (ply 2 . (<| "h(4,8,1)"))
$ midiOff "^44" (<| "h(4,8,1)") $ midiOff "^44" (<| "[~ h*<1!3 <1 2 [4 2] 1?>>]*4" )
$ "h2ogmhh" $ "h2ogmhh"
# gain 1.4 # gain 1.4
# room 0.5 # room 0.5
...@@ -30,7 +32,7 @@ d3 $ gF1 $ gM1 ...@@ -30,7 +32,7 @@ d3 $ gF1 $ gM1
# sz 0.4 # sz 0.4
# legato (range 0.3 2 "^52") # legato (range 0.3 2 "^52")
d5 $ gF3 $ gM3 d5 $ gF3 $ gM3
$ midiOn "^18" (fast 2) $ midiOn "^18" (# n "15")
$ midiOn "^90" (ply "<2 2 1 2 2 4 [4 2 8 4] 8>") $ midiOn "^90" (ply "<2 2 1 2 2 4 [4 2 8 4] 8>")
$ slice 4 "<0 1 2 3*<1!3 <2 4 [4 1]>>>" $ slice 4 "<0 1 2 3*<1!3 <2 4 [4 1]>>>"
$ midiOn "^34" ( $ midiOn "^34" (
...@@ -48,7 +50,7 @@ d5 $ gF3 $ gM3 ...@@ -48,7 +50,7 @@ d5 $ gF3 $ gM3
# dry (slow 4 $ 1 + 0.4 * perlin) # dry (slow 4 $ 1 + 0.4 * perlin)
# pan 0.8 # pan 0.8
d4 -- BASSLINE GENERATIVE d4 -- BASSLINE GENERATIVE
$ gF3 $ gM3 $ gF2 $ gM3
$ midiOn "^57" (superimpose ( $ midiOn "^57" (superimpose (
degradeBy "0 <0!3 0.2>!6 <0.2!3 0.5>" . degradeBy "0 <0!3 0.2>!6 <0.2!3 0.5>" .
(|+| note "[0 7 2 12]*4") (|+| note "[0 7 2 12]*4")
...@@ -91,13 +93,14 @@ d11 $ gF3 $ gM3 -- THE FLUTIST ...@@ -91,13 +93,14 @@ d11 $ gF3 $ gM3 -- THE FLUTIST
$ n (slow 8 $ "<13 14>") $ n (slow 8 $ "<13 14>")
# "take5" # cut 11 # "take5" # cut 11
# room 0.3 # sz 0.5 # dry 0.2 # room 0.3 # sz 0.5 # dry 0.2
# gain 1.3 # gain 0.8
d12 $ gF3 $ gM3 -- THE SLEEPWALKER d12 $ gF3 $ gM3 -- THE SLEEPWALKER
$ slice 4 "<0 1 2 3>" $ slice 4 "<0 1 2 3>"
$ n (slow 8 $ "<18 19 20 31 22 23 24 24>") $ n (slow 8 $ "<18 19 20 31 22 23 24 24>")
# "take5" # cut 11 # "take5" # cut 11
# room 0.3 # sz 0.5 # dry 0.2 # room 0.3 # sz 0.5 # dry 0.2
# gain 1.5 # pan 0.2
# gain 1.1
d8 $ gF1 $ gM1 -- La Boite à breaks de ParVagues <3 d8 $ gF1 $ gM1 -- La Boite à breaks de ParVagues <3
$ midiOn "^92" (ply "1 <2!3 4>") $ midiOn "^92" (ply "1 <2!3 4>")
$ midiOff "^60" (mask "t(4,8,1)") -- Techno drum mask $ midiOff "^60" (mask "t(4,8,1)") -- Techno drum mask
......
...@@ -128,6 +128,7 @@ d8 $ gF1 $ gM1 ...@@ -128,6 +128,7 @@ d8 $ gF1 $ gM1
$ "breaks165" $ "breaks165"
# cut 8 # cut 8
# gain 1.2 # gain 1.2
# pan (slow 4 $ range 0.9 0.1 sine)
d9 $ gF2 $ gM3-- slow arpeggiated synth, high register d9 $ gF2 $ gM3-- slow arpeggiated synth, high register
$ mask "t <f!8 t!8> <f!4 t!4> <f!8 t!8>" $ mask "t <f!8 t!8> <f!4 t!4> <f!8 t!8>"
$ fast 4 $ fast 4
...@@ -138,7 +139,7 @@ d9 $ gF2 $ gM3-- slow arpeggiated synth, high register ...@@ -138,7 +139,7 @@ d9 $ gF2 $ gM3-- slow arpeggiated synth, high register
# delay 0.5 # delaytime (1/3) # delayfb 0.4 # delay 0.5 # delaytime (1/3) # delayfb 0.4
# lpf 1400 # lpf 1400
# cut 9 # cut 9
d10 -- Euclidian mid arps d10 -- Euclidian mid arpss
$ struct "t(5,8,2)" $ struct "t(5,8,2)"
$ note (slow 2 $ "<bf3 cs4 ef3 bf3>" + "<0 7 12>") $ note (slow 2 $ "<bf3 cs4 ef3 bf3>" + "<0 7 12>")
# s "moogBass" # s "moogBass"
......
...@@ -60,6 +60,7 @@ d4 $ gF2 $ gM3 -- BASS <3 ...@@ -60,6 +60,7 @@ d4 $ gF2 $ gM3 -- BASS <3
# crushbus 41 (range 16 4 "^53") # crushbus 41 (range 16 4 "^53")
# octerbus 42 (range 0 0.93 "^33") # octerbus 42 (range 0 0.93 "^33")
d5 $ gF3 $ gM3 -- Rain piano <3 d5 $ gF3 $ gM3 -- Rain piano <3
$ (0.05 ~>)
$ midiOn "^41" (mask "<t f>")-- Mask norepeat $ midiOn "^41" (mask "<t f>")-- Mask norepeat
$ midiOn "^90" (slice 2 "<0 0 1 1>") $ midiOn "^90" (slice 2 "<0 0 1 1>")
$ midiOn "^34" ((>| n "<<4!4 34 4!3> 4 33 <34 4>>")) -- ORAGE INFINI $ midiOn "^34" ((>| n "<<4!4 34 4!3> 4 33 <34 4>>")) -- ORAGE INFINI
...@@ -118,10 +119,10 @@ d7 $ gF3 $ gM3 -- Voices ...@@ -118,10 +119,10 @@ d7 $ gF3 $ gM3 -- Voices
$ n (cat [ $ n (cat [
-- "<0 ~ 1 ~ 2 ~ 3 ~>" -- Riders 1 -- "<0 ~ 1 ~ 2 ~ 3 ~>" -- Riders 1
-- "<0 ~ ~ ~ 1 ~ ~ ~ 4 ~ ~ 4 5 ~ ~ ~>" -- Riders 2 -- "<0 ~ ~ ~ 1 ~ ~ ~ 4 ~ ~ 4 5 ~ ~ ~>" -- Riders 2
"<<0 6> ~ ~ ~>" -- Road Killer -- "<<0 6> ~ ~ ~>" -- Road Killer
-- "<~ ~ <0 1 7 ~> ~>" -- Squirming Brain -- "<~ ~ <0 1 7 ~> ~>" -- Squirming Brain
-- "<8 8 9 8>" -- Children Holiday -- "<8 8 9 8>" -- Children Holiday
-- "<11!6 12 <~ 13>>" -- Love "<11!6 12 <~ 13>>" -- Love
-- "11" -- Love -- "11" -- Love
] ]
+ 45) + 45)
......
do
-- resetCycles
setcps (89/60/4)
d1 $ fast 2
$ gF1 $ gMute2
-- $ midiOff "^42" (<| "<k [~!7 k*<1 2>]>")#
$ midiOn "^30" (# "jazz:0")
$ midiOff "^42" (<| "k . ~ k ~ ~")
$ midiOn "^42" (<| "k k . k <k [~ k] k k*2>")
$ "popkick:2"
# lpf 300 -- TODO Sound design this kick <3
-- # cut 1
# gain 2
-- # midiG' "^78" 0 1.5
d2 $ fast 2 $ gF1 $ gM1
$ midiOn "^43" (<| "~ s ~ s*<1!3 <2 [4 2]>>")
$ midiOff "^43" (<| "~ . s*<1!3 2> ~")
$ "[realclaps:0]"
-- # "h2ogmcp"
-- # gain (1.0 * "<[1]!16 [1 <1 <1 [1 0.93] 1 [0.9]>>]!16>")
# gain 1.2
-- # room 0.5 # dry 1.1
-- # delay "<0!15 0.6!1>"
-- # delayt 0.25
d3 $ gM1 $ gF1
$ fast "<1!8 2!6 4>"
$ "~ d ~ d ~ d ~ <d!12 [~ d]!3 [d d]>"
# "snare:34"
# hpf 7000
# gain 1.4
d4 $ gF2 $ gM3
$ note "[<as2 cs3 f3 cs3> <b2 ef3 fs3 b2>@7]"
# "bassWarsaw" # cut 4
# room 0.4 # sz 0.8 # dry 0.9
# octersubbus 42 (range 0 1.8 "^33")
# crushbus 41 (range 10 4.5 "^53")
# gain 1.5
d5 $ gF3 $ gM3
$ midiOn "^90" ((# begin "0 0.5") . ply "<4!7 [8 16]>")
$ slice 4 "<0 1 2 3 4 5 6 7>"
$ "daft" # n "<0!8 1!8>"
# cut 5
# gain 1.3
# dry 1.3 # sz 0.8 # room 0.4
# pan "0.3!3 0.7"
# octersubbus 51 (range 0 0.8 "^34")
# octerbus 52 (range 0 0.4 "^34")
# crushbus 53 (range 16 5 "^54")
d7 $ gF3 $ gM3
$ midiOn "^35" (# n 3)
$ midiOn "^91" (ply "<4!3 [8 16]>")
$ slice 4 "<0 1 2 3 4 5 6 7>"
$ "daft" # n "2"
# cut 7
# gain 1.3
# dry 1.3 # sz 0.8 # room 0.4
# pan "0.7!3 <0.6 0.4>"
# room 0.3 # sz 0.4
d8 $ gF1
$ gM1
$ midiOn "^92" (ply "<2 2 2 <4 8>>")
$ midiOff "^60" (mask "t(8,16,1)" . chop 16)
$ chop 8
$ loopAt 1
$ midiOn "^36" (loopAt 0.5 . (# n 135))
$ midiOn "^56" (# n 55)
$ "jungle_breaks:74"
# cut 8
d12 $ gF3 $ gM3
$ arp "up"
$ note ("c'min7 c'min7"
+ (slow 2 "<gs ef>")
+ "<0 12>"
)
# "FMRhodes1"
# modIndex (range 0 16 "^31")
# room 0.5
# sz 0.4
# gain 1.2
# pan 0.7
#!/bin/bash
# Simple TidalCycles Performance Optimizer
# This script optimizes an existing TidalCycles setup for performance
# Set variables
SAVED_CPU_GOVERNOR="/tmp/saved_cpu_governor.txt"
# Display help
show_help() {
echo "Simple TidalCycles Performance Optimizer"
echo ""
echo "Usage: $0 [option]"
echo ""
echo "Options:"
echo " --optimize Apply standard performance optimizations to running processes"
echo " --extreme Apply extreme performance optimizations (for live performance)"
echo " --stop Reset system to normal operation"
echo " --check Check current system load and running processes"
echo " --diagnose Run diagnostics to investigate audio stutters"
echo " --help Show this help message"
echo ""
echo "Example: $0 --extreme"
echo ""
echo "IMPORTANT: Launch your applications (SuperCollider, Ardour, OBS, etc.) FIRST,"
echo "then run this script to optimize performance."
}
# Check if running as root
check_root() {
if [ "$EUID" -ne 0 ]; then
echo "This script requires root permissions."
echo "Please run with sudo: sudo $0 $1"
exit 1
fi
}
# Check system load before making changes
check_system_load() {
echo "=== CURRENT SYSTEM LOAD ==="
echo ""
echo "Top CPU-consuming processes:"
ps aux --sort=-%cpu | head -15
echo ""
echo "Memory usage:"
free -h
echo ""
echo "Real-time priorities (FIFO/RR):"
ps -eLo rtprio,cls,pid,pri,nice,cmd | grep -v " - " | head -20
echo ""
echo "I/O priorities:"
for pid in $(ps -eo pid --sort=-%cpu | head -10 | grep -v PID); do
echo -n "PID $pid ($(ps -p $pid -o comm= 2>/dev/null)): "
ionice -p $pid 2>/dev/null || echo "Failed to get I/O priority"
done
echo ""
echo "Current CPU governor:"
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor | uniq
echo ""
}
# Run diagnostics to investigate audio stutters
run_diagnostics() {
check_root "--diagnose"
echo "========================================"
echo "RUNNING AUDIO STUTTER DIAGNOSTICS"
echo "========================================"
echo "Looking for potential causes of audio stutters..."
# Check if CPU scaling is causing issues
echo -e "\n=== CPU SCALING STATUS ==="
echo "Current CPU governor:"
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor | uniq
if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
echo "CPU Turbo status (1=disabled, 0=enabled):"
cat /sys/devices/system/cpu/intel_pstate/no_turbo
fi
if [ -d "/sys/devices/system/cpu/intel_pstate" ]; then
echo "Min performance percentage:"
cat /sys/devices/system/cpu/intel_pstate/min_perf_pct 2>/dev/null
fi
# Check for excessive disk I/O
echo -e "\n=== DISK I/O STATUS ==="
if command -v iostat >/dev/null 2>&1; then
iostat -x 1 2
else
echo "iostat not available. Install sysstat package for disk I/O diagnostics."
fi
# Check for memory pressure
echo -e "\n=== MEMORY STATUS ==="
free -h
echo "Memory pressure indicators:"
grep -E "pgpgin|pgpgout|pgmajfault" /proc/vmstat
# Check for active processes
echo -e "\n=== CHECKING FOR BACKGROUND JOBS ==="
echo "Recently started tasks:"
ps -eo start_time,pid,cmd --sort=start_time | tail -n 20
# Check for interrupt conflicts
echo -e "\n=== INTERRUPT ACTIVITY ==="
echo "Top 10 interrupts by count:"
cat /proc/interrupts | head -n 1
cat /proc/interrupts | sort -k2 -nr | head -n 10
# Check PipeWire status
echo -e "\n=== PIPEWIRE STATUS ==="
echo "PipeWire processes:"
ps -ef | grep pipewire | grep -v grep
# Check for processes with realtime priority
echo -e "\n=== REALTIME PRIORITY PROCESSES ==="
ps -eLo rtprio,cls,pid,pri,nice,cmd | grep -v " - " | head -n 15
# Check system uptime and load
echo -e "\n=== SYSTEM LOAD ==="
uptime
# Check CPU throttling due to thermal issues
echo -e "\n=== CPU THERMAL STATUS ==="
if [ -d /sys/devices/system/cpu/cpu0/thermal_throttle ]; then
echo "Thermal throttling events (non-zero indicates potential performance issues):"
cat /sys/devices/system/cpu/cpu*/thermal_throttle/core_throttle_count
else
echo "Thermal throttling info not available"
fi
# Check for powersave settings on USB devices
echo -e "\n=== USB POWER MANAGEMENT ==="
echo "USB devices with power management (may cause audio interface dropouts):"
for usb in /sys/bus/usb/devices/*/power/control; do
if [ -f "$usb" ]; then
echo "$usb: $(cat $usb)"
fi
done
# Check for system logging activity
echo -e "\n=== SYSTEM LOGGING ACTIVITY ==="
echo "Journal activity:"
journalctl --disk-usage
# Check audio settings
echo -e "\n=== AUDIO INTERFACE SETTINGS ==="
echo "PipeWire sample rate and buffer settings:"
if command -v pw-metadata >/dev/null 2>&1; then
pw-metadata 0 | grep buffer || echo "No buffer metadata found"
pw-metadata 0 | grep rate || echo "No rate metadata found"
else
echo "pw-metadata not available"
fi
echo -e "\n=== RECOMMENDATIONS ==="
echo "Based on the diagnostics, here are some possible causes of audio stutters:"
echo "1. Check if any thermal throttling is occurring"
echo "2. Ensure USB power management is disabled for audio interfaces"
echo "3. Consider increasing buffer size in PipeWire if needed"
echo "4. Run 'sudo $0 --extreme' before performance to apply maximum optimizations"
}
# Function to apply standard performance optimizations
optimize_standard() {
check_root "--optimize"
echo "========================================"
echo "APPLYING STANDARD PERFORMANCE OPTIMIZATIONS"
echo "========================================"
# Save current CPU governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor > $SAVED_CPU_GOVERNOR
# Stop non-essential services
echo "Stopping non-essential services..."
USER=$(logname || whoami)
systemctl --user -M $USER@ stop kde-baloo.service 2>/dev/null
systemctl --user -M $USER@ stop plasma-baloorunner.service 2>/dev/null
systemctl --user -M $USER@ stop app-geoclue-demo-agent@autostart.service 2>/dev/null
systemctl --user -M $USER@ stop app-firewall-applet@autostart.service 2>/dev/null
echo "✓ Non-essential services stopped"
# Set CPU governor to performance
echo "Setting CPU governor to performance mode..."
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
echo "✓ CPU governor set to performance"
# Disable CPU Turbo - can cause audio stutters when frequency changes
if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
echo "Disabling CPU Turbo (to avoid frequency changes)..."
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
echo "✓ CPU Turbo disabled"
fi
# Apply IRQ thread priorities
echo "Setting IRQ thread priorities..."
for irq in $(find /proc/irq/*/smp_affinity -type f 2>/dev/null | grep -v self); do
irq_num=$(echo $irq | cut -d '/' -f 4)
name=$(cat /proc/irq/$irq_num/name 2>/dev/null)
# Check if this is an audio-related IRQ
if [[ "$name" == *"snd"* ]] || [[ "$name" == *"audio"* ]] || [[ "$name" == *"hda"* ]]; then
echo "Setting audio IRQ $irq_num ($name) affinity"
echo 1 > /proc/irq/$irq_num/smp_affinity 2>/dev/null
fi
done
# Reduce kernel printk level to minimize logging impact
echo "Reducing kernel logging level..."
echo 1 > /proc/sys/kernel/printk
echo "✓ Kernel logging reduced"
# Set process priorities with standard mode
set_priorities standard
echo "✅ Standard performance optimizations applied. Your audio should be more stable now."
echo "To reset when done, run: sudo $0 --stop"
}
# Function to apply extreme performance optimizations
optimize_extreme() {
check_root "--extreme"
echo "========================================"
echo "APPLYING EXTREME PERFORMANCE OPTIMIZATIONS"
echo "========================================"
# Save current CPU governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor > $SAVED_CPU_GOVERNOR
# Stop more services
echo "Stopping non-essential services..."
USER=$(logname || whoami)
systemctl --user -M $USER@ stop kde-baloo.service 2>/dev/null
systemctl --user -M $USER@ stop plasma-baloorunner.service 2>/dev/null
systemctl --user -M $USER@ stop app-geoclue-demo-agent@autostart.service 2>/dev/null
systemctl --user -M $USER@ stop app-firewall-applet@autostart.service 2>/dev/null
systemctl --user -M $USER@ stop kaccess.service 2>/dev/null
systemctl --user -M $USER@ stop plasma-ksystemstats.service 2>/dev/null
systemctl --user -M $USER@ stop plasma-dolphin.service 2>/dev/null
echo "✓ Non-essential services stopped"
# Stop system services that can cause stutters
echo "Stopping potentially interfering system services..."
systemctl stop packagekit.service 2>/dev/null
systemctl mask packagekit.service 2>/dev/null
# Reduce journald rate instead of killing it (need logs if something crashes)
echo "RateLimitBurst=10" > /run/systemd/journald.conf.d/perf.conf 2>/dev/null || true
systemctl reload systemd-journald.service 2>/dev/null
echo "✓ System services stopped/throttled"
# Set CPU governor to performance
echo "Setting CPU governor to performance mode..."
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
echo "✓ CPU governor set to performance"
# Disable CPU Turbo and set min performance
echo "Disabling CPU Turbo and frequency scaling..."
if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
echo "✓ CPU Turbo disabled"
fi
if [ -d "/sys/devices/system/cpu/intel_pstate" ]; then
echo 100 > /sys/devices/system/cpu/intel_pstate/min_perf_pct 2>/dev/null
echo "✓ Intel CPU min performance set to 100%"
fi
# Disable NMI watchdog (can cause stutters)
echo "Disabling NMI watchdog..."
echo 0 > /proc/sys/kernel/nmi_watchdog
echo "✓ NMI watchdog disabled"
# Apply IRQ thread priorities
echo "Setting IRQ thread priorities..."
for irq in $(find /proc/irq/*/smp_affinity -type f 2>/dev/null | grep -v self); do
irq_num=$(echo $irq | cut -d '/' -f 4)
name=$(cat /proc/irq/$irq_num/name 2>/dev/null)
# Check if this is an audio-related IRQ
if [[ "$name" == *"snd"* ]] || [[ "$name" == *"audio"* ]] || [[ "$name" == *"hda"* ]]; then
echo "Setting audio IRQ $irq_num ($name) affinity"
echo 1 > /proc/irq/$irq_num/smp_affinity 2>/dev/null
fi
done
# Reduce kernel printk level to minimize logging impact
echo "Reducing kernel logging level (silence non-critical messages)..."
echo 1 > /proc/sys/kernel/printk
echo "✓ Kernel logging reduced"
# NOTE: UI process priority is handled in set_priorities() below
# Disable VM swappiness to prevent swapping during performance
echo "Reducing swap aggressiveness..."
echo 1 > /proc/sys/vm/swappiness
echo "✓ Set swappiness to minimum (1)"
# Set buffer drops to extremely high to prevent buffer underruns
echo "Setting VM settings for audio performance..."
echo 20000000 > /proc/sys/vm/dirty_bytes
echo 40000000 > /proc/sys/vm/dirty_background_bytes
echo "✓ Set VM buffer parameters for better audio performance"
# Set process priorities with extreme mode
set_priorities extreme
echo "⚠️ WARNING: UI may be less responsive during extreme performance mode."
echo "✅ Extreme performance optimizations applied. Your audio should be more stable now."
echo "To reset when done, run: sudo $0 --stop"
}
# Function to set process priorities
set_priorities() {
mode=$1
echo "Setting process priorities (mode: $mode)..."
# Find SuperCollider processes
SC_SERVER=$(pgrep scsynth)
SC_LANG=$(pgrep sclang)
if [ ! -z "$SC_SERVER" ]; then
# Set realtime priority
chrt -f -p 90 $SC_SERVER
# Protect from OOM killer
echo -17 > /proc/$SC_SERVER/oom_adj 2>/dev/null || echo -1000 > /proc/$SC_SERVER/oom_score_adj 2>/dev/null
# Lock memory to prevent swapping
prlimit --pid $SC_SERVER --memlock=unlimited 2>/dev/null
echo "✓ Set scsynth (PID $SC_SERVER) to real-time FIFO priority 90"
else
echo "⚠ scsynth process not found - make sure SuperCollider is running"
fi
if [ ! -z "$SC_LANG" ]; then
chrt -f -p 85 $SC_LANG
echo -17 > /proc/$SC_LANG/oom_adj 2>/dev/null || echo -1000 > /proc/$SC_LANG/oom_score_adj 2>/dev/null
prlimit --pid $SC_LANG --memlock=unlimited 2>/dev/null
echo "✓ Set sclang (PID $SC_LANG) to real-time FIFO priority 85"
else
echo "⚠ sclang process not found - make sure SuperCollider is running"
fi
# Find Ardour process and all its children - use more patterns
ARDOUR=$(pgrep -f "ardour-8|/ardour|ardour8")
if [ ! -z "$ARDOUR" ]; then
chrt -f -p 80 $ARDOUR
ionice -c 1 -n 0 -p $ARDOUR
echo -17 > /proc/$ARDOUR/oom_adj 2>/dev/null || echo -1000 > /proc/$ARDOUR/oom_score_adj 2>/dev/null
prlimit --pid $ARDOUR --memlock=unlimited 2>/dev/null
echo "✓ Set Ardour (PID $ARDOUR) to real-time priority 80"
# Find child processes of Ardour
for child in $(pgrep -P $ARDOUR); do
chrt -f -p 79 $child
ionice -c 1 -n 0 -p $child
echo " ✓ Set Ardour child (PID $child) to priority 79"
done
else
echo "ℹ️ Ardour process not found - skipping"
fi
# Find PipeWire/WirePlumber processes and boost their priority
PIPEWIRE_PIDS=$(pgrep pipewire)
if [ ! -z "$PIPEWIRE_PIDS" ]; then
for PW_PID in $PIPEWIRE_PIDS; do
chrt -f -p 95 $PW_PID
echo -17 > /proc/$PW_PID/oom_adj 2>/dev/null || echo -1000 > /proc/$PW_PID/oom_score_adj 2>/dev/null
done
echo "✓ Set PipeWire (PID $PIPEWIRE_PIDS) to real-time priority 95"
fi
WIREPLUMBER_PID=$(pgrep wireplumber)
if [ ! -z "$WIREPLUMBER_PID" ]; then
chrt -f -p 95 $WIREPLUMBER_PID
echo -17 > /proc/$WIREPLUMBER_PID/oom_adj 2>/dev/null || echo -1000 > /proc/$WIREPLUMBER_PID/oom_score_adj 2>/dev/null
echo "✓ Set WirePlumber (PID $WIREPLUMBER_PID) to real-time priority 95"
fi
# Find QjackCtl if running
QJACKCTL_PID=$(pgrep qjackctl)
if [ ! -z "$QJACKCTL_PID" ]; then
chrt -f -p 75 $QJACKCTL_PID
echo "✓ Set QjackCtl (PID $QJACKCTL_PID) to priority 75"
fi
# Find OBS Studio if running
OBS_PID=$(pgrep obs)
if [ ! -z "$OBS_PID" ]; then
if [ "$mode" = "extreme" ]; then
renice -n 5 -p $OBS_PID
ionice -c 2 -n 5 -p $OBS_PID
else
renice -n 0 -p $OBS_PID
ionice -c 2 -n 3 -p $OBS_PID
fi
echo "✓ Set OBS (PID $OBS_PID) to appropriate priority for $mode mode"
fi
# Find ASEQ processes
ASEQ_PID=$(pgrep aseqdump)
if [ ! -z "$ASEQ_PID" ]; then
chrt -f -p 80 $ASEQ_PID
echo "✓ Set aseqdump (PID $ASEQ_PID) to real-time priority 80"
fi
# Find Pulsar editor processes and set lower priority
PULSAR_PIDS=$(pgrep -f pulsar)
# DWIM: if no Pulsar, launch it in the script's directory using the user's session env
if [ -z "$PULSAR_PIDS" ]; then
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REF_PID=$(pgrep -u "$USER" -x kwin_wayland | head -1)
[ -z "$REF_PID" ] && REF_PID=$(pgrep -u "$USER" -x kwin_x11 | head -1)
[ -z "$REF_PID" ] && REF_PID=$(pgrep -u "$USER" -x plasmashell | head -1)
if [ -n "$REF_PID" ] && [ -r "/proc/$REF_PID/environ" ]; then
echo "ℹ️ Pulsar not running — launching in $SCRIPT_DIR..."
get_env_var() { tr '\0' '\n' < "/proc/$1/environ" | grep "^$2=" | head -1 | cut -d= -f2-; }
sudo -u "$USER" env \
DISPLAY="$(get_env_var "$REF_PID" DISPLAY)" \
WAYLAND_DISPLAY="$(get_env_var "$REF_PID" WAYLAND_DISPLAY)" \
XDG_RUNTIME_DIR="$(get_env_var "$REF_PID" XDG_RUNTIME_DIR)" \
DBUS_SESSION_BUS_ADDRESS="$(get_env_var "$REF_PID" DBUS_SESSION_BUS_ADDRESS)" \
XDG_SESSION_TYPE="$(get_env_var "$REF_PID" XDG_SESSION_TYPE)" \
nohup pulsar "$SCRIPT_DIR" </dev/null >/dev/null 2>&1 &
for _ in $(seq 1 20); do
PULSAR_PIDS=$(pgrep -f pulsar)
[ -n "$PULSAR_PIDS" ] && break
sleep 0.5
done
if [ -n "$PULSAR_PIDS" ]; then
echo "✓ Pulsar launched — giving renderer 2s to spawn before prioritizing..."
sleep 2
PULSAR_PIDS=$(pgrep -f pulsar)
else
echo "⚠ Pulsar didn't appear within 10s — skipping priority set"
fi
else
echo "⚠ No user session detected (no kwin/plasma) — skipping Pulsar auto-launch"
fi
fi
if [ ! -z "$PULSAR_PIDS" ]; then
if [ "$mode" = "extreme" ]; then
# Extreme: low but NOT idle — keeps editor usable while livecoding
for PID in $PULSAR_PIDS; do
renice -n 10 -p $PID >/dev/null 2>&1
ionice -c 2 -n 6 -p $PID >/dev/null 2>&1
done
echo "✓ Set Pulsar processes to low priority (nice 10, best-effort I/O 6)"
else
# Standard mode: slightly lower
for PID in $PULSAR_PIDS; do
renice -n 5 -p $PID >/dev/null 2>&1
ionice -c 2 -n 5 -p $PID >/dev/null 2>&1
done
echo "✓ Set Pulsar processes to slightly lower priority (nice 5)"
fi
else
echo "ℹ️ Pulsar processes not found - skipping"
fi
# Adjust desktop environment components
# KDE Window Manager (X11 or Wayland)
KWIN_PID=$(pgrep -x kwin_x11 || pgrep -x kwin_wayland)
if [ ! -z "$KWIN_PID" ]; then
if [ "$mode" = "extreme" ]; then
renice -n 10 -p $KWIN_PID >/dev/null 2>&1
ionice -c 2 -n 6 -p $KWIN_PID >/dev/null 2>&1
echo "✓ Set KWin (PID $KWIN_PID) to nice 10 (low but not starved)"
else
renice -n 5 -p $KWIN_PID >/dev/null 2>&1
echo "✓ Set KWin (PID $KWIN_PID) to nice 5"
fi
fi
# Plasma Shell
PLASMA_PID=$(pgrep -x plasmashell)
if [ ! -z "$PLASMA_PID" ]; then
if [ "$mode" = "extreme" ]; then
renice -n 15 -p $PLASMA_PID >/dev/null 2>&1
ionice -c 2 -n 7 -p $PLASMA_PID >/dev/null 2>&1
echo "✓ Set Plasma Shell (PID $PLASMA_PID) to nice 15"
else
renice -n 5 -p $PLASMA_PID >/dev/null 2>&1
echo "✓ Set Plasma Shell (PID $PLASMA_PID) to nice 5"
fi
fi
# Display server — keep at normal priority always
# Demoting Xorg/Xwayland just makes every window repaint laggy
DISPLAY_PID=$(pgrep -x Xorg || pgrep -x Xwayland)
if [ ! -z "$DISPLAY_PID" ]; then
renice -n 0 -p $DISPLAY_PID >/dev/null 2>&1
echo "✓ Keeping display server (PID $DISPLAY_PID) at normal priority"
fi
echo "Priority setup complete!"
}
# Function to stop performance mode and revert settings
reset_system() {
check_root "--stop"
echo "========================================="
echo "RESTORING NORMAL SYSTEM SETTINGS"
echo "========================================="
# Restore CPU governor
if [ -f "$SAVED_CPU_GOVERNOR" ]; then
echo "Restoring CPU governor to previous mode..."
previous_governor=$(cat $SAVED_CPU_GOVERNOR)
echo $previous_governor | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
echo "✓ CPU governor restored to $previous_governor"
rm $SAVED_CPU_GOVERNOR
else
echo "Restoring CPU governor to default mode..."
echo ondemand | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
echo "✓ CPU governor restored to ondemand"
fi
# Restore swappiness
echo "Restoring swap settings..."
echo 60 > /proc/sys/vm/swappiness
echo "✓ Swappiness restored to default (60)"
# Restore VM settings
echo "Restoring VM settings..."
echo 0 > /proc/sys/vm/dirty_bytes
echo 0 > /proc/sys/vm/dirty_background_bytes
echo "✓ VM buffer parameters restored"
# Restore Intel pstate if needed
if [ -f "/sys/devices/system/cpu/intel_pstate/no_turbo" ]; then
echo 0 > /sys/devices/system/cpu/intel_pstate/no_turbo
echo "✓ CPU Turbo re-enabled"
fi
if [ -d "/sys/devices/system/cpu/intel_pstate" ]; then
echo 0 > /sys/devices/system/cpu/intel_pstate/min_perf_pct 2>/dev/null
echo "✓ Intel CPU min performance reset"
fi
# Restore NMI watchdog
echo 1 > /proc/sys/kernel/nmi_watchdog
echo "✓ NMI watchdog restored"
# Restore kernel logging level
echo 7 4 1 7 > /proc/sys/kernel/printk
echo "✓ Kernel logging level restored"
# Restart system services
echo "Restarting system services..."
systemctl unmask packagekit.service 2>/dev/null
systemctl start packagekit.service 2>/dev/null
rm -f /run/systemd/journald.conf.d/perf.conf 2>/dev/null
systemctl reload systemd-journald.service 2>/dev/null
echo "✓ System services restarted"
# Restore nice values for processes - you can keep your apps running
echo "Restoring process priorities..."
# Reset SuperCollider priorities if running
SC_SERVER=$(pgrep scsynth)
SC_LANG=$(pgrep sclang)
if [ ! -z "$SC_SERVER" ]; then
chrt -o -p 0 $SC_SERVER
echo 0 > /proc/$SC_SERVER/oom_score_adj 2>/dev/null
echo "✓ Reset scsynth (PID $SC_SERVER) to normal priority"
fi
if [ ! -z "$SC_LANG" ]; then
chrt -o -p 0 $SC_LANG
echo 0 > /proc/$SC_LANG/oom_score_adj 2>/dev/null
echo "✓ Reset sclang (PID $SC_LANG) to normal priority"
fi
# Find Ardour process if running
ARDOUR=$(pgrep -f "ardour-8|/ardour|ardour8")
if [ ! -z "$ARDOUR" ]; then
chrt -o -p 0 $ARDOUR
ionice -c 2 -n 4 -p $ARDOUR
echo 0 > /proc/$ARDOUR/oom_score_adj 2>/dev/null
echo "✓ Reset Ardour (PID $ARDOUR) to normal priority"
fi
# Reset nice values for UI processes
KWIN_PID=$(pgrep -x kwin_x11 || pgrep -x kwin_wayland)
if [ ! -z "$KWIN_PID" ]; then
renice -n 0 -p $KWIN_PID
ionice -c 2 -n 4 -p $KWIN_PID
echo "✓ Reset KWin (PID $KWIN_PID) to normal priority"
fi
PLASMASHELL_PID=$(pgrep -x plasmashell)
if [ ! -z "$PLASMASHELL_PID" ]; then
renice -n 0 -p $PLASMASHELL_PID
ionice -c 2 -n 4 -p $PLASMASHELL_PID
echo "✓ Reset Plasma Shell (PID $PLASMASHELL_PID) to normal priority"
fi
DISPLAY_PID=$(pgrep -x Xorg || pgrep -x Xwayland)
if [ ! -z "$DISPLAY_PID" ]; then
renice -n 0 -p $DISPLAY_PID
echo "✓ Reset display server (PID $DISPLAY_PID) to normal priority"
fi
# Reset Pulsar processes if running
PULSAR_PIDS=$(pgrep -f pulsar)
if [ ! -z "$PULSAR_PIDS" ]; then
for PID in $PULSAR_PIDS; do
renice -n 0 -p $PID
ionice -c 2 -n 4 -p $PID
done
echo "✓ Reset Pulsar processes to normal priority"
fi
# Restart services
echo "Restarting services..."
USER=$(logname || whoami)
systemctl --user -M $USER@ start kde-baloo.service 2>/dev/null
systemctl --user -M $USER@ start plasma-baloorunner.service 2>/dev/null
systemctl --user -M $USER@ start app-geoclue-demo-agent@autostart.service 2>/dev/null
systemctl --user -M $USER@ start app-firewall-applet@autostart.service 2>/dev/null
systemctl --user -M $USER@ start kaccess.service 2>/dev/null
systemctl --user -M $USER@ start plasma-ksystemstats.service 2>/dev/null
systemctl --user -M $USER@ start plasma-dolphin.service 2>/dev/null
echo "✓ Services restarted"
echo "System restored to normal operation. You can continue using your apps."
}
# Main script execution
USER=$(logname || whoami)
case "$1" in
--optimize)
optimize_standard
;;
--extreme)
optimize_extreme
;;
--stop)
reset_system
;;
--check)
check_system_load
;;
--diagnose)
run_diagnostics
;;
--help|*)
show_help
;;
esac
\ No newline at end of file
...@@ -127,3 +127,10 @@ once $ "impulseSync" ...@@ -127,3 +127,10 @@ once $ "impulseSync"
once $ note "[c4 g4 c4 d4]*4" # "acidOto3091" once $ note "[c4 g4 c4 d4]*4" # "acidOto3091"
once $ "ai_welcome:0" # cut 2 once $ "ai_welcome:0" # cut 2
d1 $ slow 4
$ arp "up"
$ note "c3'maj'4"
# "sine"
/home/pln/Work/Sound/tidal-ears/src/tidal_ears/analyze_samples.py
\ No newline at end of file
#!/bin/bash
# Validate both laptop fans spin and ramp under thermal load.
# Stresses CPU, samples fan RPM + core temp over time, then idles and watches ramp-down.
# Verdict: both fans must climb under load, stay in lockstep, and drop on idle.
# Usage: sudo ./fan_check.sh
set -u
rebind() {
HWMON=$(echo /sys/devices/platform/dell_smm_hwmon/hwmon/hwmon*)
PWM1="$HWMON/pwm1"; PWM2="$HWMON/pwm2"
PWM1E="$HWMON/pwm1_enable"; PWM2E="$HWMON/pwm2_enable"
FAN1="$HWMON/fan1_input"; FAN2="$HWMON/fan2_input"
}
rebind
if [ "$EUID" -ne 0 ]; then
echo "needs root: sudo $0"
exit 1
fi
NCPU=$(nproc)
STRESS_S=30
COOLDOWN_MAX_S=120 # cap on cooldown wait
COOL_TEMP=65 # °C — CPU must sit below this...
COOL_HOLD_S=10 # ...for this long before we trust the steady state
SAMPLE_DT=2
cpu_temp() {
sensors coretemp-isa-0000 | awk '/Package id 0/{gsub(/[+°C]/,"",$4); print $4; exit}'
}
sample() {
printf " t=%2ds fan1=%4s fan2=%4s Δ=%4s cpu=%s°C pwm=%s/%s\n" \
"$1" "$(cat "$FAN1")" "$(cat "$FAN2")" \
"$(( $(cat "$FAN1") - $(cat "$FAN2") ))" \
"$(cpu_temp)" "$(cat "$PWM1")" "$(cat "$PWM2")"
}
# Background CPU stress. Prefer stress-ng, fall back to N busy-yes loops.
start_load() {
if command -v stress-ng >/dev/null 2>&1; then
stress-ng --cpu "$NCPU" --timeout "${STRESS_S}s" >/dev/null 2>&1 &
LOAD_PID=$!
LOAD_KIND=stress-ng
else
LOAD_KIND="yes×$NCPU"
LOAD_PIDS=()
for _ in $(seq "$NCPU"); do
yes > /dev/null &
LOAD_PIDS+=("$!")
done
fi
}
stop_load() {
if [ "${LOAD_KIND:-}" = "stress-ng" ]; then
wait "$LOAD_PID" 2>/dev/null || true
else
for p in "${LOAD_PIDS[@]:-}"; do kill "$p" 2>/dev/null || true; done
wait 2>/dev/null || true
fi
}
trap 'stop_load 2>/dev/null || true' EXIT INT TERM
echo "=== baseline (idle, 6s) ==="
for t in 0 2 4 6; do sample "$t"; sleep "$SAMPLE_DT"; done
BASE_F1=$(cat "$FAN1"); BASE_F2=$(cat "$FAN2"); BASE_T=$(cpu_temp)
echo
echo "=== LOAD ${STRESS_S}s ($NCPU cores via $(command -v stress-ng >/dev/null && echo stress-ng || echo 'yes×N')) ==="
start_load
PEAK_F1=$BASE_F1; PEAK_F2=$BASE_F2; PEAK_T=$BASE_T
for t in $(seq 0 "$SAMPLE_DT" "$STRESS_S"); do
sample "$t"
f1=$(cat "$FAN1"); f2=$(cat "$FAN2"); tt=$(cpu_temp)
[ "$f1" -gt "$PEAK_F1" ] && PEAK_F1=$f1
[ "$f2" -gt "$PEAK_F2" ] && PEAK_F2=$f2
# tt is float ("68.0") — compare via awk
PEAK_T=$(awk -v a="$PEAK_T" -v b="$tt" 'BEGIN{print (b>a)?b:a}')
sleep "$SAMPLE_DT"
done
stop_load
echo
echo "=== COOLDOWN (wait until CPU < ${COOL_TEMP}°C for ${COOL_HOLD_S}s, max ${COOLDOWN_MAX_S}s) ==="
held=0; t=0; END_F1=0; END_F2=0; END_T=0
while [ "$t" -le "$COOLDOWN_MAX_S" ]; do
sample "$t"
tt=$(cpu_temp)
below=$(awk -v a="$tt" -v b="$COOL_TEMP" 'BEGIN{print (a<b)?1:0}')
if [ "$below" = "1" ]; then
held=$(( held + SAMPLE_DT ))
else
held=0
fi
if [ "$held" -ge "$COOL_HOLD_S" ]; then
echo " [cooled] CPU sat below ${COOL_TEMP}°C for ${held}s — capturing end state"
END_F1=$(cat "$FAN1"); END_F2=$(cat "$FAN2"); END_T="$tt"
break
fi
sleep "$SAMPLE_DT"
t=$(( t + SAMPLE_DT ))
done
if [ "$END_F1" = "0" ]; then
echo " [timeout] never settled below ${COOL_TEMP}°C — using last sample"
END_F1=$(cat "$FAN1"); END_F2=$(cat "$FAN2"); END_T=$(cpu_temp)
COOL_TIMEOUT=1
else
COOL_TIMEOUT=0
fi
echo
echo "=== VERDICT ==="
printf " baseline: fan1=%s fan2=%s cpu=%s°C\n" "$BASE_F1" "$BASE_F2" "$BASE_T"
printf " peak load: fan1=%s fan2=%s cpu=%s°C\n" "$PEAK_F1" "$PEAK_F2" "$PEAK_T"
printf " post-cool: fan1=%s fan2=%s cpu=%s°C\n" "$END_F1" "$END_F2" "$END_T"
DELTA_F1=$(( PEAK_F1 - BASE_F1 ))
DELTA_F2=$(( PEAK_F2 - BASE_F2 ))
PEAK_DIFF=$(( PEAK_F1 - PEAK_F2 ))
[ "$PEAK_DIFF" -lt 0 ] && PEAK_DIFF=$(( -PEAK_DIFF ))
# Climb test: both fans must gain meaningfully (>=300 RPM) under load.
if [ "$DELTA_F1" -ge 300 ]; then echo " [OK] fan1 climbed +$DELTA_F1 RPM under load"
else echo " [!!] fan1 only +$DELTA_F1 RPM — weak response"; fi
if [ "$DELTA_F2" -ge 300 ]; then echo " [OK] fan2 climbed +$DELTA_F2 RPM under load"
else echo " [!!] fan2 only +$DELTA_F2 RPM — weak response"; fi
# Lockstep: peak RPMs should match within ~150 RPM.
if [ "$PEAK_DIFF" -le 150 ]; then echo " [OK] fans in lockstep (peak Δ=$PEAK_DIFF RPM)"
else echo " [!!] fans diverged at peak (Δ=$PEAK_DIFF RPM) — one may be obstructed"; fi
# Ramp-down: only meaningful if we reached the cooled steady state.
if [ "$COOL_TIMEOUT" = "1" ]; then
echo " [skip] ramp-down check (CPU never settled below ${COOL_TEMP}°C in ${COOLDOWN_MAX_S}s — try again with no background load)"
else
[ "$END_F1" -lt "$PEAK_F1" ] && echo " [OK] fan1 ramped down ($PEAK_F1 -> $END_F1)" \
|| echo " [!!] fan1 did not ramp down ($PEAK_F1 -> $END_F1)"
[ "$END_F2" -lt "$PEAK_F2" ] && echo " [OK] fan2 ramped down ($PEAK_F2 -> $END_F2)" \
|| echo " [!!] fan2 did not ramp down ($PEAK_F2 -> $END_F2)"
fi
# Thermal recovery: end temp should be lower than peak (using awk for float).
RECOV=$(awk -v p="$PEAK_T" -v e="$END_T" 'BEGIN{print (e<p)?"yes":"no"}')
if [ "$RECOV" = "yes" ]; then echo " [OK] CPU cooled $PEAK_T°C -> $END_T°C"
else echo " [!!] CPU did not cool ($PEAK_T°C -> $END_T°C)"; fi
echo
echo "done."
#!/usr/bin/env python3
"""
shipowiz.py — audio-reactive Shipow backdrop renderer.
Maps bass kick → subtle zoom pulse, highs → brightness flash.
Optional: cross-fade through several Shipow loops (sinusoidal blend).
Usage:
tools/shipowiz.py -a MASTER.mp4 -s ~/Videos/Shipow/nb3.mp4 -o OUT.mp4
tools/shipowiz.py -a take_five.flac -s nb1.mp4 nb3.mp4 nb7.mp4 -o OUT.mp4
tools/shipowiz.py -a M.mp4 -s nb*.mp4 --opacity 0.35 --zoom 0.05 --flash 0.8
If -a has video, the rendered backdrop is screen-blended onto it.
If -a is audio-only, the backdrop becomes the video and audio is muxed.
"""
from __future__ import annotations
import argparse
import subprocess
import sys
import tempfile
import wave
from pathlib import Path
import numpy as np
from PIL import Image
FPS = 30
SR = 48000
W, H = 1920, 1080 # final composite resolution
BG_W, BG_H = 960, 540 # backdrop render resolution (upscaled at composite)
def run(cmd, **kw):
return subprocess.run(cmd, check=True, **kw)
# ─── audio ─────────────────────────────────────────────────────
def extract_audio(src: Path, out_wav: Path):
run(["ffmpeg", "-y", "-i", str(src), "-vn",
"-ac", "1", "-ar", str(SR), "-f", "wav", str(out_wav)],
capture_output=True)
def load_wav(path: Path) -> np.ndarray:
with wave.open(str(path), "rb") as w:
raw = w.readframes(w.getnframes())
return np.frombuffer(raw, dtype=np.int16).astype(np.float32) / 32768.0
def band_envelope(audio: np.ndarray, lo_hz: float, hi_hz: float) -> np.ndarray:
"""Per-video-frame band energy via overlapping STFT, normalized to 98th pct."""
hop = SR // FPS # 1600 samples = one video frame
win = 2048
n = len(audio) // hop
window = np.hanning(win).astype(np.float32)
freqs = np.fft.rfftfreq(win, 1 / SR)
mask = (freqs >= lo_hz) & (freqs <= hi_hz)
env = np.zeros(n, dtype=np.float32)
pad = np.zeros(win, dtype=np.float32)
for i in range(n):
s = i * hop
chunk = audio[s:s + win]
if len(chunk) < win:
pad[:] = 0
pad[:len(chunk)] = chunk
chunk = pad
spec = np.abs(np.fft.rfft(chunk * window))
env[i] = spec[mask].mean()
p = np.percentile(env, 98)
if p > 1e-9:
env = np.clip(env / p, 0, 1)
return env
def follower(env: np.ndarray, attack: float, release: float) -> np.ndarray:
"""Asymmetric one-pole envelope follower. attack/release in 0..1."""
out = np.zeros_like(env)
prev = 0.0
for i, x in enumerate(env):
coef = attack if x > prev else release
prev = prev + coef * (x - prev)
out[i] = prev
return out
# ─── video ─────────────────────────────────────────────────────
class FrameSource:
"""Infinite-looping rgb24 frame reader via an ffmpeg subprocess."""
def __init__(self, path: Path, w: int, h: int, fps: int):
self.proc = subprocess.Popen([
"ffmpeg", "-stream_loop", "-1", "-i", str(path),
"-vf", f"scale={w}:{h}:force_original_aspect_ratio=increase,"
f"crop={w}:{h}",
"-f", "rawvideo", "-pix_fmt", "rgb24", "-r", str(fps),
"-loglevel", "error", "-"
], stdout=subprocess.PIPE)
self.size = w * h * 3
self.w, self.h = w, h
def read(self):
buf = self.proc.stdout.read(self.size)
if len(buf) < self.size:
return None
return np.frombuffer(buf, dtype=np.uint8).reshape(self.h, self.w, 3)
def close(self):
try:
self.proc.stdout.close()
except Exception:
pass
self.proc.terminate()
try:
self.proc.wait(timeout=2)
except Exception:
self.proc.kill()
class Looper:
"""Reads from N FrameSources, cross-fades sequentially with smoothstep.
Reads only the currently-active source(s) — idle sources don't advance,
they catch up when they become active (acceptable for ambient loops)."""
def __init__(self, paths, w, h, period_seconds=12.0):
self.sources = [FrameSource(p, w, h, FPS) for p in paths]
self.period = max(1, int(period_seconds * FPS))
self.i = 0
def frame(self):
n = len(self.sources)
if n == 1:
self.i += 1
return self.sources[0].read()
phase = (self.i / self.period) % n
a_idx = int(phase) % n
b_idx = (a_idx + 1) % n
t = phase - int(phase)
t = t * t * (3 - 2 * t) # smoothstep
self.i += 1
a = self.sources[a_idx].read()
if t < 1e-3:
return a
b = self.sources[b_idx].read()
if a is None or b is None:
return None
# in-place blend without float64 promotion
return (a.astype(np.float32) * (1 - t) + b.astype(np.float32) * t).astype(np.uint8)
def close(self):
for s in self.sources:
s.close()
def zoom_frame(arr: np.ndarray, factor: float) -> np.ndarray:
"""Crop center, upscale back — zooms in by `factor` (>=1).
BILINEAR is intentional: at 1.0-1.06× on monochrome content the difference
vs LANCZOS is invisible and BILINEAR is ~3× faster."""
if factor <= 1.002:
return arr
h, w = arr.shape[:2]
cw = int(w / factor)
ch = int(h / factor)
x = (w - cw) // 2
y = (h - ch) // 2
crop = arr[y:y + ch, x:x + cw]
return np.asarray(Image.fromarray(crop).resize((w, h), Image.BILINEAR))
def brighten(arr: np.ndarray, amount: float,
gain: float = 0.18, lift: float = 42.0) -> np.ndarray:
if amount <= 0:
return arr
out = arr.astype(np.float32) * (1.0 + gain * amount) + lift * amount
return np.clip(out, 0, 255).astype(np.uint8)
def has_video_stream(path: Path) -> bool:
r = subprocess.run(
["ffprobe", "-v", "error", "-select_streams", "v:0",
"-show_entries", "stream=codec_type", "-of", "csv=p=0", str(path)],
capture_output=True, text=True)
return "video" in r.stdout
# ─── main ──────────────────────────────────────────────────────
def main():
ap = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument("-a", "--audio", required=True,
help="audio source — accepts any media (audio or video)")
ap.add_argument("-s", "--src", nargs="+", required=True,
help="one or more Shipow MP4s; multiple → cross-fade")
ap.add_argument("-o", "--out", required=True)
ap.add_argument("--bass-lo", type=float, default=40)
ap.add_argument("--bass-hi", type=float, default=160)
ap.add_argument("--high-lo", type=float, default=4000)
ap.add_argument("--high-hi", type=float, default=12000)
ap.add_argument("--zoom", type=float, default=0.06,
help="max zoom factor on bass peak (0.06 = +6%%)")
ap.add_argument("--flash", type=float, default=1.0,
help="brightness flash multiplier on highs")
ap.add_argument("--opacity", type=float, default=0.4,
help="bg blend strength when overlaying on code video")
ap.add_argument("--morph-period", type=float, default=12.0,
help="seconds per cross-fade cycle when multi-src")
ap.add_argument("--bg-only", action="store_true",
help="output the reactive backdrop alone (no composite)")
args = ap.parse_args()
src_audio = Path(args.audio).expanduser().resolve()
paths = [Path(p).expanduser().resolve() for p in args.src]
out = Path(args.out).expanduser().resolve()
for p in [src_audio, *paths]:
if not p.exists():
sys.exit(f"missing: {p}")
with tempfile.TemporaryDirectory() as td:
td = Path(td)
wav = td / "a.wav"
print(f"[1/4] extracting audio → {wav.name}")
extract_audio(src_audio, wav)
audio = load_wav(wav)
n_frames = len(audio) * FPS // SR
print(f" {n_frames} frames @ {FPS}fps ({n_frames / FPS:.1f}s)")
print("[2/4] computing FFT band envelopes")
bass = follower(band_envelope(audio, args.bass_lo, args.bass_hi),
attack=0.65, release=0.10)
high = follower(band_envelope(audio, args.high_lo, args.high_hi),
attack=0.85, release=0.28)
print(f" bass mean={bass.mean():.2f} peak={bass.max():.2f} "
f"high mean={high.mean():.2f} peak={high.max():.2f}")
print(f"[3/4] rendering visual layer ({len(paths)} src"
f"{' cross-fading' if len(paths) > 1 else ''}) at {BG_W}x{BG_H}")
looper = Looper(paths, BG_W, BG_H, period_seconds=args.morph_period)
bg_path = td / "bg.mp4"
enc = subprocess.Popen([
"ffmpeg", "-y", "-f", "rawvideo", "-pix_fmt", "rgb24",
"-s", f"{BG_W}x{BG_H}", "-r", str(FPS), "-i", "-",
"-c:v", "libx264", "-preset", "ultrafast", "-crf", "18",
"-pix_fmt", "yuv420p", "-fps_mode", "cfr", "-r", str(FPS),
"-loglevel", "error", str(bg_path)
], stdin=subprocess.PIPE)
try:
n = min(n_frames, len(bass), len(high))
for i in range(n):
f = looper.frame()
if f is None:
break
f = zoom_frame(f, 1.0 + args.zoom * float(bass[i]))
f = brighten(f, args.flash * float(high[i]))
enc.stdin.write(f.tobytes())
if i % (FPS * 10) == 0 and i > 0:
print(f" {i}/{n} ({100 * i // n}%)")
finally:
try:
enc.stdin.close()
except Exception:
pass
enc.wait()
looper.close()
if args.bg_only:
print(f"[4/4] muxing backdrop + audio")
run(["ffmpeg", "-y", "-i", str(bg_path), "-i", str(src_audio),
"-map", "0:v", "-map", "1:a?",
"-c:v", "copy", "-c:a", "aac", "-b:a", "192k",
"-shortest", "-movflags", "+faststart", str(out)])
elif has_video_stream(src_audio):
print(f"[4/4] screen-blending backdrop onto code (opacity {args.opacity})")
# Convert both streams to planar RGB before blend — screen-mode on YUV
# chroma pushes neutral grayscale off-center and tints output pink.
run(["ffmpeg", "-y", "-i", str(src_audio), "-i", str(bg_path),
"-filter_complex",
f"[0:v]scale={W}:{H},format=gbrp[code];"
f"[1:v]scale={W}:{H}:flags=bilinear,format=gbrp[bg];"
f"[code][bg]blend=all_mode=screen:all_opacity={args.opacity},"
f"format=yuv420p[v]",
"-map", "[v]", "-map", "0:a?",
"-c:v", "libx264", "-preset", "medium", "-crf", "20",
"-pix_fmt", "yuv420p", "-fps_mode", "cfr", "-r", str(FPS),
"-c:a", "aac", "-b:a", "192k",
"-movflags", "+faststart", str(out)])
else:
print(f"[4/4] audio-only source — muxing backdrop + audio")
run(["ffmpeg", "-y", "-i", str(bg_path), "-i", str(src_audio),
"-map", "0:v", "-map", "1:a",
"-c:v", "copy", "-c:a", "aac", "-b:a", "192k",
"-shortest", "-movflags", "+faststart", str(out)])
print(f"✓ {out}")
if __name__ == "__main__":
sys.exit(main() or 0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment