You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Patterns: Strudel arbeitet ausschließlich mit Patterns. Ein Pattern ist ein sich wiederholendes Muster, das musikalische Ereignisse über einen bestimmten Zeitraum hinweg erzeugt. Das System basiert auf Zyklen, wobei ein Zyklus die Dauer eines Patterns angibt.
Mini-Notation: Die Mini-Notation ist die Sprache von Strudel. Sie verwendet Symbole wie < >, [ ], /, *, und @, um komplexe rhythmische und melodische Strukturen zu beschreiben.
< > gruppiert Patterns und spielt sie nacheinander ab. Beispiel: <bd sd hh> spielt Bassdrum, Snare und Hi-Hat in dieser Reihenfolge.
[ ] stapelt Patterns und spielt sie gleichzeitig ab. Beispiel: [bd hh] spielt Bassdrum und Hi-Hat gleichzeitig.
* wiederholt Patterns. Beispiel: bd*4 spielt die Bassdrum viermal pro Zyklus.
/ teilt Patterns auf. Beispiel: bd/2 spielt die Bassdrum mit halber Geschwindigkeit.
! wählt Patterns aus einer Liste. Beispiel: bd!2 wählt zwei Patterns nach dem Zufallsprinzip aus.
@ ändert die Abspielgeschwindigkeit oder verzögert. Beispiel: bd@2 spielt die Bassdrum in doppelter Geschwindigkeit.
Generative Musik: Strudel ermöglicht es, dynamische und sich ständig verändernde Musik zu kreieren. Funktionen wie sine, perlin, oder rand können verwendet werden, um Parameter wie Lautstärke, Tonhöhe oder Tempo kontinuierlich zu modulieren.
Dieser Song zeigt, wie man komplexe, sich überlagernde Rhythmen und Melodien erzeugt und dabei Patterns mit Effekten moduliert.
samples('github:eddyflux/crate'): Lädt ein externes Sample-Pack von GitHub, das unter dem Namen 'crate' verfügbar ist.
setcps(.75): Setzt die Geschwindigkeit auf 0.75 Cycles per Second (Zyklen pro Sekunde), was ein langsameres Tempo ergibt.
let chords = chord("<Bbm9 Fm9>/4").dict('ireal'): Definiert ein Pattern von Akkorden. Die Notation <Bbm9 Fm9>/4 bedeutet, dass die Akkorde in Gruppen von vier Vierteln pro Zyklus gespielt werden. .dict('ireal') ist eine Funktion, die die Akkordnamen in spielbare Noten umwandelt.
stack( ... ): Stapelt mehrere Patterns, sodass sie gleichzeitig laufen. Dies wird für die Schlagzeug-, Akkord- und Melodie-Patterns verwendet.
s("bd").struct("<[x*<1 2> [~@3 x]] x>"): Spielt das bd (Bassdrum) Sample ab. .struct(...) wendet eine komplexe rhythmische Struktur an, die von [x*<1 2> [~@3 x]] und x beschrieben wird, um einen vielschichtigen Beat zu erzeugen.
n("[0 <1 3>]*<2!3 4>").s("hh"): Spielt die Hi-Hat. n(...) wählt die Noten. [0 <1 3>]*<2!3 4> ist eine rhythmische und melodische Mini-Notation, die die Noten 0, 1 und 3 in einem bestimmten Muster spielt, das von den folgenden rhythmischen Modifikatoren beeinflusst wird.
.mask("<[0 1] 1 1 1>/16"): Wendet eine Maske auf das Pattern an. Die Maske lässt nur bestimmte Teile des Patterns durch, was einen Effekt wie beim Clave-Rhythmus erzeugt. Die Notation <[0 1] 1 1 1>/16 spielt in einem 16-tel-Raster, wobei nur die erste Note des ersten Patterns durchkommt.
.phaser(4).room(.5): Fügt einen Phaser-Effekt mit einer Frequenz von 4 und einen Hall-Effekt (room) mit einer Stärke von 0.5 hinzu.
.gain(perlin.range(.6, .9)): Moduliert die Lautstärke (gain) mit einem Perlin-Noise-Pattern, das zufällige, aber sanft fließende Werte zwischen 0.6 und 0.9 erzeugt.
Dieses Stück demonstriert die dynamische Modulation des Tempos.
setDefaultVoicings('legacy'): Setzt das Standard-Voicing für Akkorde auf 'legacy', was die Art und Weise der Notenverteilung in Akkorden beeinflusst.
melody: "<...>" .scale("c4:minor").note().s("gm_oboe:2"): Definiert ein Melodie-Pattern, das mit pickRestart aus einer Liste von Unter-Patterns zufällig ausgewählt wird. .scale("c4:minor") wendet eine c-Moll-Tonleiter an, wodurch alle Noten innerhalb dieser Skala bleiben. s("gm_oboe:2") weist der Melodie den Klang einer Oboe zu.
tempochanges: cps(sine.segment(32).slow(16).mul(30).add(160).div(60*3)): Dies ist der komplexeste Teil. Es moduliert das Tempo (cps) dynamisch.
sine: Erzeugt ein Sinuswellen-Pattern, das sanfte, periodische Werte erzeugt.
.segment(32): Teilt die Sinuswelle in 32 Segmente pro Zyklus.
.slow(16): Verlangsamt das Pattern auf 1/16 der Normalgeschwindigkeit.
.mul(30).add(160).div(60*3): Skaliert und verschiebt die Werte der Sinuswelle, um ein Tempo im Bereich von ca. 1.6 bis 3.1 Zyklen pro Sekunde (96 bis 186 BPM) zu erzeugen, und konvertiert dieses auf eine für cps verständliche Zahl.
all(x=>x.room(0.6)): Wendet den Raum-Effekt (room) mit einer Stärke von 0.6 auf alle aktiven Patterns an.
Dieses Beispiel demonstriert fortgeschrittene Techniken, darunter benutzerdefinierte Funktionen und komplexe Pattern-Manipulation.
setcps(104/60/4): Stellt das Tempo auf 104 BPM, aber geteilt durch 4, was ein sehr langsames, atmosphärisches Tempo erzeugt.
const split = register(...): register ist eine der wichtigsten Funktionen dieses Stücks. Sie wird verwendet, um eine neue, benutzerdefinierte Funktion zu definieren, die in diesem Fall split genannt wird. Diese Funktion ist nicht standardmäßig in Strudel enthalten und ermöglicht es dem Programmierer, eine völlig neue Art der Pattern-Verarbeitung zu erschaffen.
let chr = { ... }: Definiert ein Objekt (chr), das Akkorde als Key-Value-Paare speichert. Dies dient als Nachschlagewerk für die Akkord-Sequenzierung.
piano: "<...>" .split([0,.5],(x)=>x[0].pickOut(chr).velocity(x[1])): Das Piano-Pattern ist extrem komplex. Es verwendet die benutzerdefinierte split-Funktion, um das Hauptpattern <[i1 i2 i3 i4] ooooh ...> aufzuteilen und zu verarbeiten. [0, .5] sind die Werte, die für die Verarbeitung übergeben werden. Die Funktion verwendet .pickOut(chr) um Noten aus dem chr-Objekt basierend auf den in der Notation definierten Keys (z.B. X, Y, Z) auszuwählen. velocity(x[1]) verwendet den zweiten Wert 0.5 der split-Funktion, um die Anschlagsstärke der Noten zu bestimmen.
ooooh: "<~ 0 ~@4 0@2 ~@8>/8" ... .penv(x[1]).patt(0.04).s("triangle")...: Dieses Pattern erzeugt einen atmosphärischen Synthesizer-Sound. .s("triangle") wählt einen einfachen Dreieckswellen-Synth.
.penv(x[1]): Steuert die Hüllkurve (Anschlag, Sustain, Decay). x[1] ist hier wieder der Wert aus der split-Funktion, was zeigt, wie die Notenhülle dynamisch gesteuert wird.
.vmod(.1).vib(5): Fügt einen Vibrato-Effekt mit einer Stärke von 0.1 und einer Frequenz von 5 hinzu.
Patterns: Strudel works exclusively with patterns. A pattern is a repeating cycle that generates musical events over a specific period. The system is based on cycles, where one cycle defines the duration of a pattern.
Mini-Notation: Mini-notation is the language of Strudel. It uses symbols like < >, [ ], /, *, and @ to describe complex rhythmic and melodic structures.
< > groups patterns and plays them sequentially. Example: <bd sd hh> plays bass drum, snare, and hi-hat in that order.
[ ] stacks patterns and plays them simultaneously. Example: [bd hh] plays bass drum and hi-hat at the same time.
* repeats patterns. Example: bd*4 plays the bass drum four times per cycle.
/ divides patterns. Example: bd/2 plays the bass drum at half speed.
! selects patterns from a list. Example: bd!2 selects two patterns randomly.
@ changes playback speed or adds delay. Example: bd@2 plays the bass drum at double speed.
Generative Music: Strudel allows for the creation of dynamic and ever-changing music. Functions like sine, perlin, or rand can be used to continuously modulate parameters such as volume, pitch, or tempo.
This song demonstrates how to create complex, overlapping rhythms and melodies while modulating patterns with effects.
samples('github:eddyflux/crate'): Loads an external sample pack from GitHub, available under the name 'crate'.
setcps(.75): Sets the speed to 0.75 Cycles per Second, resulting in a slower tempo.
let chords = chord("<Bbm9 Fm9>/4").dict('ireal'): Defines a pattern of chords. The notation <Bbm9 Fm9>/4 means chords are played in groups of four quarter-notes per cycle. .dict('ireal') converts chord names into playable notes.
stack( ... ): Layers multiple patterns so they run simultaneously. Used here for drums, chords, and melody.
s("bd").struct("<[x*<1 2> [~@3 x]] x>"): Plays the bd (bass drum) sample. .struct(...) applies a complex rhythmic structure to create a multi-layered beat.
n("[0 <1 3>]*<2!3 4>").s("hh"): Plays the hi-hat. n(...) selects the notes. The mini-notation plays notes 0, 1, and 3 in a pattern influenced by rhythmic modifiers.
.mask("<[0 1] 1 1 1>/16"): Applies a mask to the pattern. It only lets specific parts through, creating an effect similar to a clave rhythm.
.phaser(4).room(.5): Adds a phaser effect (freq 4) and reverb (room, strength 0.5).
.gain(perlin.range(.6, .9)): Modulates the volume (gain) using a Perlin noise pattern, creating smooth, random fluctuations between 0.6 and 0.9.
This piece demonstrates the dynamic modulation of tempo.
setDefaultVoicings('legacy'): Sets default chord voicing to 'legacy', affecting how notes are distributed in chords.
melody: "<...>" .scale("c4:minor").note().s("gm_oboe:2"): Defines a melody pattern randomly selected from a list using pickRestart. .scale("c4:minor") applies a C minor scale. s("gm_oboe:2") assigns an oboe sound.
tempochanges: cps(sine.segment(32).slow(16).mul(30).add(160).div(60*3)): The most complex part, modulating tempo (cps) dynamically:
sine: Generates a smooth periodic wave.
.segment(32): Samples the wave into 32 segments per cycle.
.slow(16): Slows the pattern to 1/16 speed.
.mul(30).add(160).div(60*3): Scales and shifts values to a range of approx. 1.6 to 3.1 cycles per second (96 to 186 BPM).
all(x=>x.room(0.6)): Applies reverb (room) at 0.6 strength to all active patterns.
This example demonstrates advanced techniques, including custom functions and complex pattern manipulation.
setcps(104/60/4): Sets the tempo to 104 BPM divided by 4, creating a very slow, atmospheric pace.
const split = register(...): register is used to define a new, custom function called split. This allows the creator to build entirely new pattern processing logic not included in standard Strudel.
let chr = { ... }: Defines an object (chr) that stores chords as key-value pairs, serving as a lookup table for chord sequencing.
piano: "<...>" .split([0,.5],(x)=>x[0].pickOut(chr).velocity(x[1])): The piano pattern is extremely complex. It uses the custom split function to process the main pattern. .pickOut(chr) selects notes from the chr object based on keys like X, Y, Z. velocity(x[1]) uses the split value to determine touch sensitivity.
ooooh: "<~ 0 ~@4 0@2 ~@8>/8" ... .penv(x[1]).patt(0.04).s("triangle")...: Creates an atmospheric synth sound. .s("triangle") selects a simple triangle wave.
.penv(x[1]): Controls the envelope (attack, sustain, decay) dynamically.
.vmod(.1).vib(5): Adds a vibrato effect (strength 0.1, frequency 5).