Generative Workout Mix

This project began when I had ran out of music to workout to. Before I headed out for my workout, I would spend 5-10 minute creating a playlist of music to workout to. Clearly I had preferences on what worked for me and what did not. This is when I started to analytically breakdown what makes for a good workout music. I think that a good workout mix needs to not change a lot but change just enough. A Genius Conclusion if I may say so.

Besides these there are some pragmatic requirements.

  • The music needs to align with my periods of activity and rest
  • It starts of slow, build up to a crescendo and then slow down again for the cooldown phase of the workout.

Experimenting with Tidal Cycles

I started with trying to come up with a generative algorithmic process to create this music. While I was trying to come up with rules for this type of music to encode in my algorithm, I began trying out new ideas frequently in a live coding music environment called Tidal Cycles. What I eventually learnt was that instead of coming up with ONE generative system, the process of coming up with this music was much more fun and natural to creating workout music.

Highlights

  1. Exploring harmony and dynamics in sound design

d1 $ stack [
    n "<c4'maj7(3,8,<2,2,4,4>)!3 a3'maj9(5,8,<2,4>)>" # s "supercomparator" # room 0.8 # sz 0.2 # gain (sine+0.4) # voice 0.8 # decay 0.2 # legato 1 
    , "tsukick:2(3,16,<0,2,6,10>)" # n (irand 2) # cut 382 # gain 1.2 
    , "[tsuho:6(9,16,<2,4,5>), tsuhc:9(4,16,1)]" # pan (sine+0.2) 
    , struct "t(4,8)" $ scale "lydian" "0 1 3 4 5 6" # s "superhammond" # silence
]
            
  1. Composing and Playing melodies

let melody4 a b c d = cat [(scale "lydian" a),(scale "lydian" b),(scale "lydian" c),(scale "lydian" d)]
let bl4 key a b c d = cat [(scale "lydian" a |-| 24 |+| key),(scale "lydian" b |-| 24 |+| key),(scale "lydian" c |-| 24 |+| key),(scale "lydian" d |-| 24 |+| key)]
let melody8 a b c d e f g h = cat [(scale "major" a),(scale "major" b),(scale "major" c),(scale "major" d),(scale "major" e),(scale "major" f),(scale "major" g),(scale "major" h)]
let catMelody melodyA melodyB = cat [melodyA, melodyB]
            
  1. Fast Melodic Solos

d1 $ jux rev $ chunk 4 (fast 2 . (|- n 12)) $ off 0.25 (|+ 7) $ struct (iter 4 "t(3,8)")
  $ arp "<up down>" $ n "<d3'm9'8 g3'dom13>"
  # sound "superpiano"
  # gain 0.8
d2 $ n "<d3'min'7 g3'dom7>"
  # sound "superpiano"
  # gain 0.7
  # attack 0.3
  # sustain 2
  # room 0.9
  # sz 0.9
  # pan sine
  # legato 0.4
  # speed (sine + 0.5)
d3 "[gabba(2,9,<0,4>), [~ sd], hh(5,8,<1,2>), hc(3,8,2)]"
  1. Melodies and Bassline using mini notation

d1 
    $ n ("{<g(3,8)!3 f(4,8,2)>}%<2 2 6 <4 <2 6>>>") 
    # s "defaultB"
    # gain 1.4
    # silence
do
    let pat = "{<g3(<3 4>,8) <a3 as3 d3 f3>(2,4,2)>}%<1 2 4 8>"
    d1 
        $ n (pat |- 12)
        # s "subBass1"
        # gain (1+cosine)
    d7 
        $ n (pat |- 24)
        # s "subBass1"
        # gain (1+sine)
    d8
        $ n (pat |+ 24)
        # s "defaultB"
        # gain 1.4
  1. Recognizable melodic ideas with randomization

do
  let bassPat = struct "t(<5!3 6 5 7 7 8>,16,<0 2 4>)" $ choose [0, 3, 5, 7] + 5
  let leadPat = struct "t(<5!3 6 7 7 7 8>,16,<1 2 3>)" $ wchoose [(0, 1), (3, 0.75), (5, 0.75), (6, 0.125), (7, 0.5)] + 5
  d1 
      $ n (bassPat |- 12)
      # s "subBass1"
      # pan tri
      # gain 0.8
  d7 
      $ n (bassPat |- 24)
      # s "subBass1"
      # pan tri
      # gain 0.8
  d8
      $ n (bassPat |- 24)
      # s "defaultB"
      # gain 1.6
      # room 0.2
      # sz 0.6
      # pan tri
  d3 $ s "<[tsukick:1 tsusnare:14]!7 [tsukick:1 tsusnare:14(5,8)]>" # gain 1.8
  d6 $ n "<f3'maj7'ii(1,2)!7 as3'maj9(2,3)>" # s "supercomparator" # legato 0.4 # gain 0.7 # room 0.5 # sz 0.2
  d4 $ fast 2 $ s "<[tsuho(6,8), tsuhc:3(3,8)]!7 [tsuho(7,8), tsuhc:4(6,8,1)]>" # gain 1.2 # legato 0.2 # pan cosine
  d9  
      $ every 12 (jux rev) 
      $ whenmod 9 7 (fast 2)
      $ every 7 (|+ 12)
      $ leadPat
      # s "supercomparator"
      # gain 0.9
      # room 0.2
      # sz 0.6
  1. Playing with Samples

Sample credits go to Emma Chamberlain


d2 
    $ every "<2 4 2 4>" ((scramble 8).(ply 3).(degradeBy 0.2))
    $ stack [
        slow 2 $ striate 128 "food:1" # gain 1.2
    ]