acid test

acid test

generative acid basslines.

acid-test

lately I’ve been listening to acid house music and thinking about markov chains. previously I used markov chains to make a jazz piano accompaniment. it seemed to me that acid house basslines might be amenable to applying stateless logic for generating believable sequences. whether this results in “believable” acid music is up to you, but worth it for me to give it a try.

demo (sequencing roland sh-01a, midi lfos are on VCF freq, resonance, and VCO noise):

this script started off as a literal “test” to do A/B explorations on different meta-parameters of the markov chains, but its too slow to sample parameter space by listening. so instead, I decided that the markov chains might be intuitive enough to edit directly, and I added controls to edit each individual markov chain. the output can be sent to midi, crow, or the builtin engine. the builtin engine is forked from bernhard’s sc code which itself is forked from by_otophilia’s code for a 303 emulator in SuperCollider.

Requirements

  • norns
  • midi (optional)
  • crow (optional)

Documentation

quick start

simply use K2 to generate/modify sequences.

  • K2 modifies current sequence
  • K3 toggles start/stop

you can have sequences modify themselves and evolve by changing the parameter PARAMS > sequences > evolve.

each time you generate/modify a sequence it will increase the number of modifications it makes (with a refractory period). each time you modify a sequence, it also creates a saved sequence which you can recall:

  • K1+E1 selects saved sequence
  • K1+K3 loads saved sequence

you can also manually edit notes in the sequence

  • E2 selects a note
  • E3 changes a note

editing markov chains

sequences are generated based on the transition probabilities in the markov chains. you can edit these properties to create your own style of generative acid basslines.

to enter the markov-chain editing mode hit K1+K2. all controls are as follows:

  • K1+K2 toggles markov chain editing mode
  • E1 selects markov chain
  • E2 selects transition
  • E3 changes transition probability

this next part assumes a basic understanding of a markov chain. pretty much all you need to know can be learned by reading these examples. feel free to ask questions.

the generation of each step in a sequence is determined based on the states of 9 markov chains. the states of the markov chains change based on only the previous state (i.e. “memoryless”). each step in a sequence has similar properties to the 303 sequencer in that it has three parameters: a note, a slide toggle, and an accent toggle. each step in the sequence has these three parameters determined based on the state of a markov chain and discussed in detail below.

the transitions between the states of the markov chain are under your control. use E1 to select an markov chain property and use E2 to select a transition in that property. then use E3 to modify the probability of that transition. the brighter the transition arrow, the higher the probability. the combination of these 9 markov chains are then combined to generate the sequence.

accent

transitions between “no” and “yes”. when the state of this markov chain is ‘yes’, then the velocity will be increased slightly for that note.

accent

slide

transitions between “no” and “yes”. when the state of this markov chain is ‘yes’, the portamento will be increased. for midi devices you can set the portamento cc in the PARAMS > midi section. for crow/engine output, the portamento is applied automatically through slew in the pitch.

slide

bass or lead

in designing this sequencer I felt that I had to separate between “bass” and “lead” notes in the bassline - though technically the whole thing is a bassline, the “bass” notes typically being an octave below. I felt that acid basslines get part of the signature sound by oscillating between two intertwined melodies that are loosely mirrored across an octave. so there are separate markov chains for the “bass” and “lead”, which are combined using this “bass or lead” property.

this property transitions between “bass” and “lead”. the generator actually generates twice as many notes as requested - i.e. one entire set of bass notes and one entire set of lead notes. but will only select either based on the state of this property.

bassorlead

bass / lead coef+mult

the bass and lead parts each use two properties to generate a single note. the starting note of each sequence is the “base note” defined in the parameters. the base note is then increased by coef x mult at each step in the sequence where coef and mult are determined by the current state in both of those markov chains. for example, if the coef state is 2 and the mult is -1 then the sequence will transition -2 notes in the scale. the scale can be defined in the parameters.

bassorlead

bassorlead

the lead coef+mult works the same way as the bass coef+mult, but only affects the lead notes.

bassorlead

bassorlead

bass / lead note

the legato of the note will be determined by the “bass note” property (for bass notes) or the “lead note” property (for lead notes). if the state is “rest” then no note will be played, and any current note will be stopped. if the state is “new” then the current note will be stopped and a new note will be played. if the state is “hold” and the new note is the same as the last note, then there will be no gate, it will simply continue the note. if the new note is not the same and there is a slide, then portamento will be applied.

bassnote

leadnote

crow

crow is supported. output 1 is pitch which will be slewed according to slides. output 2 is the gate (0-5v).

midi

midi out can be selected in the parameters. you can also select the cc value for portamento (if your synthesizer allows it) as well as up to three LFOs that will be sent to the midi device via cc’s (e.g. for filter / resonance / etc).

saving/loading

save and load via the PSETs. saving and loading should save all the sequences that you’ve accumulated over time (i.e. saves are “collections” of all evolved sequences).

Install

install using with

;install https://github.com/schollz/acid-test
86 Likes

Oh yeah! Dang dude, do you ever get outside?

10 Likes

brilliant, love it! :slight_smile: :slight_smile:

2 Likes

wowee! you just don’t quit!

2 Likes

thanks @2197 and @Justmat !

actually most of this script was actually written on an airplane :slight_smile: (thanks to norns docker)

35 Likes

Nice! Glad to hear you’re not locked in a basement somewhere, chained to a terminal. Great work!

6 Likes

What, the, actual fuck?

9 Likes

Wonder what happens when I plug this in to an Acid box…. :thinking:

EDIT: “I just kinda wrote this on a plane” is seriously strong “nbd” energy

12 Likes

Markov chained.

Now i want to dig out my computer science theory textbook (Sipser 2012) and recap FSMs and NFAs.

aci_{eee}d = \langle Q, \Sigma, \Delta, q_0, F \rangle
7 Likes

oh, just playing with norns on a laptop while sailing through the sky at 500 kn… you know, as per the usge

2 Likes

Holy shit, your seatmate is doing some serious foot contortions.

4 Likes

Looks like a curled up SO

2 Likes

Had a play with this last night and really loved it. Really appreciated this.

I’m not sure I understood it though-not really a problem, I am happy to be surprised.
One question: if i wanted to keep things quite bass heavy is there a way to limit the high lead notes? keep them within a certain octave range?

best

3 Likes

I am also interested in your what looks like non-browser Maiden. Mine is always segfaulting.

1 Like

I don’t really understand it much yet, but it’s very interesting to play with.
However, it seems to be a bit weird with MIDI start messages? It starts sometimes, but not always.

function toggle_playing(on)
  disable_transport=true
  clock.run(function()
    clock.sleep(1)
    disable_transport=false

It has something to do with pressing stop twice on my Digitakt (common thing to do, stops the fx engine). Looks like you’re assuming the user presses start or stop once, in sequence.

3 Likes

This is amazing – well done!

Quick question: Is there any way to display the notes being played either while playing or when stopped? Would be pretty nifty to load an initial bassline and then have it evolve using MDP

1 Like

what is MDP? yeah the note display could be added to the redraw() routine, probably in these lines, the actual note number is designs[1].seq.data[sel_note].note. I can add it when I get a chance or will gladly take a PR

I have to play around with this, it could very well be weird with MIDI start messages as I haven’t fully tested them.

I am using a Docker-ized version that utilizes norns.online locally for the interface /controls. the code is here: GitHub - schollz/norns-dev: Docker images and information on setting up a Norns development environment. there is no useful commentary there though (the README’s that are there are not accurate to my fork). if your interested let me know.

yeah! use the markov chain for “bass or lead” and make sure the probabilities lead towards the “bass” to get more bass heavy. you can also heavily limit the lead range by biasing away from “+2” or “+3” in the “lead coef” markov chain.

lol we actually had the three seats to ourselves!

4 Likes

Damn! As soon as I get home I’m going to drive the Nymphes with this script.

1 Like

I noticed the library is also available in the public repository but installing it from there fails as the folder name then contains spacing. Installing using the git command works fine.

Pull request to fix is here

2 Likes

Had the same experience. Installed using git. Fun script!

1 Like