Write Music with Code! Workshop

Happy March and happy Spring! The bluebonnets and the Indian paintbrushes are out. I have a couple of different creative projects that I'm deep into, so I'm going to keep this post short, but I wanted to drop an update on a very cool thing I got to attend. A couple weeks ago, during SXSW, and I attended Write Music with Code!, a workshop held at the amazing local DIY space dadaLab. The workshop was run by Dan Gorelick and Viola He.

The format was pretty straightforward: There was a decent amount of time for the hosts and attendees to do meet and greets, then Dan and Viola talked briefly about what live coding is and what the live coding community and algoraves are all about.

As for tech and materials, we were using Strudel, which is a web-based JavaScript version of Tidal Cycles. Dan and Viola walked briefly and quickly through some of the Strudel and Tidal Cycles docs, as well as the Hello World materials they had prepared, but the majority of the workshop was loosely split between guided coding examples in Strudel and heads down free coding. Overall it was pretty informal and the hosts were super happy to share their knowledge.

The workshop ended with a share out session. Each person dropped a public link to the little bit of music they had worked on throughout the workshop, the hosts played the track for everyone to hear, and Dan live coded/remixed each track, talking through his process as he was remixing. It was very cool to see and hear his decision-making process as he transformed music on the fly using programming.

Here is the code for what I wrote:

stack(
  note("<C3 C4>").sound("gm_electric_guitar_muted").clip(0.1),
  note("60 ~ <63 62 65 63> ~ [63 <59 52> 70 55]")
    .sound("gm_bird_tweet")
    .gain(0.08),
  n("4 2 4 9 11 <3 <12 [2 12]>> <[4,8] [7,11]> 8")
    .scale("C:minor")
    .sound("gm_electric_guitar_muted")
    .lpf(400)
    .cpm(60),
  // s("bd(<2 3 4 5>,8)").gain(0.008).cutoff(100),
  s("bd bd").gain(0.1).cutoff(100),
  s("hh ~ ~ [hh ~ ~ ~  hh]").clip(0.1).hpf(100).gain(0.1),
  "<0 4 2 3>".struct("2(3,8)").scale("c2:mixolydian").note().sound("sine"),
  "{0 1 5 3 <4 9>}%8"
    .off(1 / 4, (n) => n.add(7))
    .scale("a2 minor")
    .note()
    .sound("sine")
    .cutoff(160)
    .legato(0.8)
);

Please don't ask me what any of that does...I do not know! Haha. But you can hear it at this link.

And here is the final product of Dan's remix:

stack(
  // note("<C3 C4>").sound("gm_electric_guitar_muted").clip(0.1),
  // note("60 ~ <63 62 65 63> ~ [63 <59 52> 70 55]")
  //   .sound("gm_bird_tweet")
  //   .gain(0.08),
  // n("4 2 4 9 11 <3 <12 [2 12]>> <[4,8] [7,11]> 8")
  //   .scale("C:minor")
  //   .sound("gm_electric_guitar_muted")
  //   .lpf(sine.range(800, 20000).segment(64).slow(7)).lpq(50)
  //   .cpm(60),
  // s("bd(<2 3 4 5>,8)").gain(0.008).cutoff(100),
  // s("bd(<3 5>,8)").gain(0.5).cutoff(2000).fast(2),
  // s("~ sd"),
  s("hh ~ ~ [hh ~ ~ ~  hh]").clip(0.1).hpf(5000).gain(0.1),
  "<0 4 2 3>".struct("2(3,8)").scale("c2:mixolydian").note().sound("sine"),
  "{0 1 5 3 <4 9>}%8"
    .off(1 / 4, (n) => n.add(7))
    .scale("a2 minor")
    .note()
    .sound("sine")
    .cutoff(160)
    .legato(0.8)
);

He was commenting and uncommenting things out as the track looped, and changing argument values passed to the different functions. You can listen to that remixed version here, and try further remixing yourself if you'd like.

Anyway, that's all that I have for this month. This workshop was very cool, and I'm happy to have another creative coding tool in my toolkit! Strudel is super fun and has a really low barrier to entry, so you should try it out too!