License Flash Crash 210710 SC Set Writeup

I hope it isn’t presumptuous posting this but I wanted to describe my Flash Crash set a little bit, in case someone saw the gist in the Flash Crash set and just got hecka confused. I also have the feeling there is a decent amount of SuperCollider interest in these parts, but people are (understandably) intimidated, so hopefully I can mitigate that a bit by talking through the code.

(side note: If I did a crappy job of demystifying this, please let me know! I want more people to use SC so I can selfishly absorb their wisdom (as I have from @infinitedigits) and use it to expand my own skills!)

If you are curious and haven’t seen the gist yet, here it is!
(EDIT: link fixed, sorry I dumbed that! Thank you @infinitedigits and @synthetivv for testing the link)

Concept

  1. Use the built-in laptop as the source of all sounds. Mostly typing, because I’m doing that anyway :smiley: Anyway, it’s quite versatile!
  2. Store a 12-second buffer of some of that mic signal, plus a couple useful control signals, all at audio rate.
  3. Drive loops from that buffer using a common phasor. And then, downstream, use modulo (%) to smoosh down the values from this phasor into something a.) that hugs those juicy loops and b.) creates funky[-ish] rhythms! More on these in a moment…
  4. Use the mouse (via MouseX.kr) to find sweet/sour spots within the buffer. More on this later too.
  5. “Sample” the spots by literally just punching in the numbers rolling off the mouse as I see them fly by in the poll for mouse values, and overriding the mouse mapping.

Buffer recording

Buffers in SC are just long lists/arrays/tables of numbers (just like most audio recordings such as WAV files). Write at audio rate to a buffer (using BufWr.ar), and boom, you have an audio recorder.

In this case, it’s a 4-channel (i.e. 4 parallel table) buffer. The first 2 channels are from said mic. Its third channel is a gate signal derived from a pretty crude noise gate on the mic signal, and the fourth is a pretty crude envelope (a LagUD, or lag with independent up and down (think Maths)) derived from that gate signal. All 4 channels together look something like this:

In this set, I wrote to the buffer 4 times: once with the keyboard, once with the rubber band, once scraping on the laptop chassis, and once I resampled the delay. I used an envelope here just for its doneAction which destroys the enclosing “synth”. I’m going to go ahead and say the synth concept is out-of-scope for this writeup, but this kind of SuperCollider 101 - suffice to say it’s a structure of sound processing on the server, kind of like a “patch”. I didn’t want to leave it running because once it recorded once, I didn’t care about it anymore.

Ndef

These are a cool feature of SC that enable a flavor of livecoding that fits with my brain. I kind of think of these as being able to create and modify your own modules on-the-fly. You can also route between them, and map their parameters to whatever rando other thing strikes your fancy. The details are out of scope of this writeup, but please read more here if you’re curious! Ndef | SuperCollider 3.11.2 Help

PHASOR!

OK, if you don’t know what a phasor is, well, phasors rule. It’s literally just a resetting counter. Every sample/cycle/frame, it goes up a certain amount. Programmers out there may recognize this as a cousin of the for-loop (well, the typical i++-type implementation, anyway)!

And synthesists may recognize this as just a ramp wave. It just goes up to a certain amount, and then it abruptly drops back to the beginning.

In a sense, they’re the same thing. That sounds pretty boring, right? Well what mechanism do you suppose allows you to play looped samples? That’s right, a phasor! You can even pipe a phasor into a sine function and get a continuous sine wave (or apply > x to it for pulse waves, or create a triangle wave using subtraction and .abs, or…)

In this case, we have a phasor counting up to 64 over the course of as many seconds. This was kind of overkill (I could’ve gotten away with 8) but I wasn’t sure how bonkers I wanted to get. This might sound a bit mysterious but it will make sense when we discuss…

MODULO!!

This is where it gets interesting (in my opinion)! Lots of Teletype peeps already know how cool modulo is. It does this:

source: 0 1 2 3 4 5 6 7 8 9 ...
mod 3 : 0 1 2 0 1 2 0 1 2 0 ...

Does that make sense? No? It also does this:

source: 0 1 2 3 4 5 6 7 8 9 ...
mod 2 : 0 1 0 1 0 1 0 1 0 1 ...

So it’s like a clock divider, kinda.

But you can also do funny tricks when you double-modulo. Check this out!

source     :  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
mod 8 mod 3:  0  1  2  0  1  2  0  1  0  1  2  0  1  2  0  1

And we have the beginnings of a footwork beat (imagine kicks on 0 or maybe 1). So right there we have a thing that can do some of the same stuff as a Euclidean function just by doing a simple math trick twice.

The trick here is that you can modulo audio rate signals! So we take that core clock phasor, modulo it, and now we have a sub-clock. Then we can use this as a “playback head” into the buffer which plays the buffer at a shorter loop.

The double-modulo is controlled by both the mod and mod2 parameter. The latter is set to a ridiculously high value like 9000 (though, in retrospect, anything 64 or higher would’ve been fine :sweat_smile:) when I didn’t want to do double-modulo tricks, rendering it effectively inactive.

But what actually is this modulo? It’s just the remainder of division! But (at least in SC) it works with floats too. Which is cool.

Buffer playback

Now that we’ve discussed modulo, there really isn’t much to say about playback. Because all we’re doing is taking that modulo output, scaling it (a.k.a. multiplying it by a fixed number), and reading the buffer value at that position. It works just like a playback head on a tape or a needle on a vinyl record.

One interesting note, though - to add a bit of crunch, I set the interpolation option of the sample players to 1 for no interpolation. Who needs an S900, anyway?

Lag

It’s really just a slew limiter but it’s a nice way to smooth out the sharp edges. It can be added to almost any parameter, which is great. I use this on quite a few (most?) of the parameters. I meant to add one to the offset at the end when we descend into the drone zone but I goofed. Oops! #flashcrash

Mouse

We’ve got this cool modulo going, but it always starts at 0 and goes to some amount. That’s not super cool because it’s always going to play from the beginning of the buffer (0). How do we fix that? Simple, just add a number to it. But how do we know which number? Well, I figured the best way is to listen! So that’s where the mouse comes in. The \mouse8 Ndef goes from 0 to 8 based on the horizontal mouse position. By mapping this to the offset parameter, this allows for scrubbing through the buffer quickly and precisely.

Once the sweet/sour spot is found, I just punched in the value logged in the Post window by the MouseX.poll and “pin it” by remapping it to that static number instead of the dynamic mouse value. It can easily be remapped to the mouse later, and that’s exactly what I did.

The components (mostly a bunch of Ndefs)

  • Mic (obviously)
  • Delay/echo… nothing to write home about, really
  • Buffer (not an Ndef)
  • Buffer-recorder (not an Ndef either, because I only need it three times, for 12 seconds each)
  • Phasor from which all buffer positions come
  • A handful of players, with “playback head” position derived from the phasor modulos

Note on \p1, \p2, \p3

At first I was copy+pasting that big ugly Ndef and I got kinda tired of it, so I just made an ~id variable and assigned each of these to it so I could reassign the Ndef with that. Stupid hack but it saved me probably 15 seconds and a lot of confusion during the set.

The Plan

  • Start off the SC boilerplate (the JUNK section)
  • Turn on the mic
  • Type a bit
  • Pipe the mic into a delay as kind of an appetizer (I’m not going to write this up, it’s just kind of a fattener, but have fun with my implementation if you like!)
  • Record into the buffer
  • Fire up the phasor
  • Fling some buffer-players into the ether
  • Jam out on player parameters
  • Turn the phasor speed down to 0.00insertridiculouslysmallnumberhere and then to 0 (so it’s like a stopped turntable)

The ending

Because we’re just deriving single cycles (albeit long ones, for most of the set) from a common modulo, we can treat it like a single-cycle player like a ROMpler. So, hey, why not just play a drone chord? :smiley:

Once the drone chord is created, I pipe it into the delay, and then jam on the offset for a bit, and then I just crank the core phasor speed slowly down to 0 (thanks .lag), and because all the players are derived from it, they all slow down at one time. It’s a neat/stupid trick, and with the utter lack of interpolation, it reveals lots of nice crunchy trextures on its way down.

Thanks for reading

I hope that was educational and not rambly or spammy. Again, please learn SC so I can steal any cool tricks you come up with in the future!

43 Likes

@license I absolutely want to read about these kinds of details, and appreciate the effort to document everything!

2 Likes

My pleasure! Seriously please hit me up if you have any questions, corrections, ramen/kimchi/guacamole recipes, anything!

2 Likes

Double modulo is brilliant! Thanks :clap:

2 Likes

You are most welcome!

Also, I added some pictures and attempted to clarify some things.

1 Like

thanks so much for this, I have written in my notebook “what is modulo??” this is a very useful description of how to use it for synthesis specifically.

3 Likes