Live coding music library/environment for Kotlin
A live coding music library/environment for Kotlin. For software developers who want to dive into live coding music.
"Punkt" is "point" in Polish.
Demos:
git clone
, run and enjoygit clone https://github.com/pjagielski/punkt-template.git
src/main/resources/punkt.scd
in SuperCollider.)Main.kt
in punkt-template
src/main/kotlin/live.kts
in your favourite editor for live-coding patterns(beats = 8) {
+ repeat(1).sample("bd_haus")
}
Plays "bd_haus" sample every beat.
What happened here? punkt
highly relies on durations to create patterns. If we want to play "bd_haus" sample every
beat, we could specify this by a list of beats, like listOf(0, 1, 2, 3, ...)
. We could use rangeTo
function (e.g. 0..7
) to
create a fixed range of beats. In punkt
instead, you specify the durations between the beats, and a
starting point - which defaults to 0 by this repeat
function (which is not repeat
from Kotlin standard library).
This has some advantages:
patterns(beats = 8) {..}
function.Another example: 4 on the floor beat:
patterns(beats = 8) {
+ repeat(1).sample("bd_haus") // every beat starting from 0
+ repeat(2).sample("claps", at = 1.0) // every even beat, starting from 1
+ repeat(1).sample("hat_2", at = 0.5, amp = 0.5f) // every beat, starting from 0.5
}
Evaluates to:
sample | played at beats |
---|---|
"bd_haus" | [0,1,2,3,4,5,6,7] |
"claps" | [1,3,5,7] |
"hat_2" | [0.5,1.5,2.5,3.5,4.5,5.5,6.5] |
punkt
also uses similar technique to create melodies. But melodies, apart from time when the sound should play,
require a note (pitch), which should play. To make it more musically correct, these notes should be part
of some musical scale. That's why we start by creating a scale
object using DSL from scale
package:
val scale = Scale(C.sharp(), minor)
The notes of C# minor are: C#,D#,E,F#,G#,A,B (https://en.wikipedia.org/wiki/C-sharp_minor)
Then we can use phrase
function, which takes sequence of degrees of given scale and sequence of durations to create a melody:
patterns(beats = 8) {
+ scale.low()
.phrase(
degrees(listOf(0,-4,-2,-1).flatMap { listOf(it,it,it) }),
cycle(0.75, 0.75, 0.5))
.synth("tr808", amp = 0.2f)
}
This creates following notes:
beats | note | degree |
---|---|---|
0, 0.75, 1.5 | C# | 0 |
2, 2.75, 3.5 | F# | -4 |
4, 4.75, 5.5 | A | -2 |
6, 6.75, 7.5 | B | -1 |
Which is the "Shape of you" bassline ;)
TB-303 pentatonic arpeggio with LFO
val pentatonic = Scale(C.sharp(), pentatonic)
val lfo = LFO(1000, 3200, length = 1.5)
patterns(beats = 8) {
+ pentatonic.low()
.phrase(degrees(cycle(cycle((0..4)).take(10).toList())), cycle(0.25))
.synth("tb303", amp = 0.2f)
.params("sus" to 0.3, "dec" to 0.2, "start" to 100)
.params("cutoff" to lfo)
}
4-step chord progression with lead synth
val scale = Scale(C.sharp(), minor)
val progression = listOf(Chord.I, Chord.IV, Chord.VI, Chord.VII)
patterns(beats = 8) {
+ scale
.phrase(
progression.flatMap { listOf(it, null, it) }.toDegrees(),
cycle(1.0, 0.25, 0.75)
)
.synth("lead", amp = 0.25f)
.params("cutoff" to 1500)
}
reverb
, delay
, djf
djf
, waveDist
, squiz
piano
, bass8
amp
, track
lpf
, hpf
, delay
, dist
, chop
lead
sample
and loop
supporttb303
, tr808
, plucklead
, da-funk
Copyright © 2020- Piotr Jagielski
Punkt is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.