Tips og tricks til patterns
Der er meget at lære, når man først starter med patterns. Der følger en helt ny, musikalsk logik med dette komplekse system af redskaber, der kan anvendes på kryds og tværs. Herunder kommer et par yderst nyttige tips og tricks, som du vil få glæde af, når du eksperimenterer med patterns.
Mød Pbinds bedste ven, Pdef
Når man skriver kompositioner med Pbind
og foretager mange små ændringer, kan det være en lidt klodset proces konstant at skulle slukke for lyden først og derefter eksekvere Pbind().play
igen. Her kan det være en stor fordel at bruge Pdef
. Den giver os nemlig mulighed for at eksekvere den samme blok igen og igen, og så vil instrukserne i den nyligt eksekverede kildekode erstatte de hidtidigt kørende instrukser. Første argument til Pdef()
er et unikt navn, som vi vil give vores komposition. Næste argument er det pattern, vi vil anvende - typisk en Pbind
. Kildekoden herunder eksekveres flere gange uden Ctrl/Cmd-Punktum.
TempoClock.tempo = 250 / 60;
Pdef(\minKomposition,
Pbind(
\degree, Pshuf([-3, -2, 0, 4], inf)
)
).play;
Kører vi kildekoden ovenfor, vil Pshuf
vælge en tilfældig rækkefølge og gentage den, indtil vi stopper kompositionen igen. Men kører vi blokken igen uden at stoppe den først, bliver vores Pdef
, Pbind
og Pshuf
genoprettet på ny, og Pshuf
vil derfor vælge en ny rækkefølge. Vi fortsætter endda i takt med det, vi havde gang i før eksekveringen.
Når vi starter en Pdef
, vil den automatisk blive registreret under det navn, vi angiver. Vi kan senere bruge navnet til fx at stoppe kompositionen igen. Bemærk her, at der ikke er behov for globale variabler, da Pdef
-klassen selv holder styr på alle dens instances.
Pdef(\minKomposition,
Pbind(
\freq, Pexprand(55, 1500).round(55),
\dur, Pexprand(0.1, 0.2),
\legato, 2,
)
).play;
Pdef(\minKomposition).stop;
Pdef
har i øvrigt en slægtning kaldet Pbindef
, som også er handy, men som jeg ikke anbefaler at bruge, da den kan give uventede resultater, hvis man tilføjer og fjerner nøgler og patterns løbende.
Hvad giver dit pattern egentlig af resultater?
Hvis man eksperimenterer og forsøger sig frem med forskellige patterns og værdier, kan det godt være vanskeligt at forstå hvad outputtet er. Derfor kan det være nyttigt med et overblik over de værdier, der bliver genereret.
Følg med i strømmen af data med .trace
I den situation er method'en .trace
en stor hjælp, da den viser outputtet fra et pattern i SuperColliders post window.
Pbind(
\freq, Pexprand(220, 1500, 10).round(220).trace,
\dur, 0.25,
).play;
Hvis vi har gang i flere patterns, som vi gerne vil følge, kan vi bruge argumentet prefix
til at kende forskel ved hjælp af en angivet tekst.
Pbind(
\octave, Pbrown(3, 5, 1).trace(prefix: "Oktav: "),
\degree, Pseries(0, 1, 10).trace(prefix: "Skalatrin: "),
).play;
Generér en masse data på én gang og plot dem
Et sidste trick, der kan være nyttigt, er at generere alle værdierne fra et pattern på én gang, for at få et overblik over dem. Dette gør vi i et par trin:
- Først skriver vi det pattern, vi vil undersøge - inklusiv de argumenter, vi vil eksperimentere med. Her er det meget vigtigt, at det er et pattern med et begrænset antal output. Ellers vil SuperCollider få det umådeligt svært, fordi det skal beregne samtlige værdier i en uendelig strøm.
- Dernæst konverterer vi vores pattern til en såkaldt stream med method'en
.asStream
. - Vi kan derefter bruge method'en
.all
til at få alle de genererede værdier udregnet.
Vi kan også sortere, visualisere og analysere disse data med forskellige methods, der knytter sig til lister.
~data = Pexprand(0.1, 100, 1000).asStream.all;
// -> [ 44.267960075825, 0.33396883358304, 6.4274511302122, 1.1416103740564 ...
~data.mean; // Gennemsnit
// -> 14.903230351712
// Plot
[~data, ~data.copy.sort].plot(discrete: true);
Vi bruger her method'en .copy
, fordi .sort
ellers vil forandre den oprindelige liste, som er gemt under variablen ~data
(og dermed give os to ens grafer). Når vi sætter argumentet discrete: true
, vil datapunkterne i plottet blive vist med prikker i stedet for forbundne linjer.