On a Sunday afternoon, fifteen friends, all non musicians but two amateur musicians, joined the machines set in turn, around 8 at a time, to improvise electro or hip-hop rhythmic grooves. Of course there were food and drinks as well.
The goal was to introduce music making in an attractive way: no pressure, no constraint, no reason to be shy, just have fun!
Don’t be shy
Some arrived saying “no no no I will never sing in the mike”, but ended up doing the mike to record voice loops into the Kaoss Pad… Other spent time to figure out how to play something musical from machines they were touching for the first time. It was amazing how everybody got into it!
Here is a time lapse overview, unfortunately silent:
The machine set was primarily composed of an Akai MPC500 with various programs (drums, stabs, acapella chops, etc.), a Korg Kaoss Pad 3 with an Shure SM58 mike and a Korg microKorg, all MIDI clock-ed together, and all mixed into a Yamaha MG12/4 with a Boss SE-70 reverb send. There were also a 49-keys Casio keyboard and a Yamaha SHS10 mini handheld keyboard, both used as MIDI controllers to drive an EMU Turbo Phatt. Various circuit-bent toys were also pre-mixed and then fed into the Kaoss Pad as well, to get the best out of them.
Every machine has its own appeal: the Kaoss Pad 3 is the most appealing at first, but then it gets more difficult to master. The microKorg, thanks to its sync-ed arpeggiator and its modulation wheel is also rewarding very quickly. The MPC is somehow harder since you must be rather accurate when playing for the rhythm to sound good. The EMU Phatt is very easily rewarding, especially when using the Beats programs or other programs made of several sounds laid over the keyboard.
Fun or accurate: this is the question
One note about loops, either on the Kaoss Pad or in the MPC: if they help to improve the accuracy of the music (repeats perfectly each time), they also kill a lot of fun out of it since you only have to play once, record, and then you are done! On the other end, playing repeatedly the same thing (or at least trying to) helps to get warmer and warmer!
Thanks all for joining us for this party, and see you for next time!
Following my ongoing work on a theory of rhythms and a corresponding physical instrument using lasers, here is a version of the same idea implemented into an Arduino: a generative sequencer. The idea is to generate rhythms, and perhaps melodies, from one rhythm seed, then use mutated copies of it to create something more interesting, all this in realtime using knobs and buttons.
This is not ‘yet another step sequencer’, but really a generative music device, that builds a real time MIDI loop based on an underlying theory described in a previous post.
This is work in progress, and is shown ‘as is’ for the sake of getting feedback.
Approach
The approach is to generate a “seed” of rhythm that is then copied a few times into “instances”, each instance being distorted in its own way. The controls for the human player (or programmer) are therefore all about adjusting the deformations (transforms actually) to apply to each instance, and of course defining the seed.
Eventually each instance is wired to a MIDI note, channel etc. to remote control a synthesizer or a drum machine or any MIDI setup, to generate actual sounds.
Principle: one seed, many transformed instances
The maths
Given a seed of rhythm of lengh length composed of pulses, each of duration m, then:
for each instance k of the seed, each pulse i,
pulse(k, i) happen at time t = phase(k) + i . m . stretch(k), t < length
where phase(k) and stretch(k) are the phase and stretch settings for the instance k.
Realtime control of the sequencer is therefore all about setting the phase and stretch values for each instance, once the pulse number and the pulse duration of the seed have been globally set.
Inversely, for a given instance k, at time t, we have a pulse if:
there exists an i, such as t = phase(k) + i * m * stretch(k)
i.e. i = (t - phase(k))/(m * stretch(k))
Thinking in MIDI ticks (24 per quarters), in 4/4, for 1 bar, length = 4 * 24, phase is in [-24 .. 24] and stretch is in [4:1 .. 1:4] and m in [12 .. 48] by steps of 12 ticks.
The implementation is the very simple: for each instance of the seed, and given its phase and stretch settings, whenever the modulo condition above is true, then we emit its MIDI note, with the set velocity on the set MIDI channel.
As usual, the pace of the loop is primarily based on the value from the Tempo potentiometer.
Overview of the circuit, with the switches and the knobs
Adding some swing
8th note swing
The EMU SP-1200, early Linn machines, Roland 909, Akai MPC and many other machines are famous for their swing quantize, a feature that delays every other note by a certain amount in order to create a groovy feeling (see Swung Note).
Different machines express the swing factor in different ways, we will stick to the MPC format, expressed in percent from 50% (no swing, play straight) to 75% (hard shuffle).
For a swing for 8th notes, this swing factor represents the ratio of the period of the first 8th note over the period of the second 8th note, in percent.
In the Arduino code of our generative sequencer, we chose to do a fixed swing for 8th notes only.
A big constraint is that we are limited to a resolution of 24 ticks per quarter note, which is not a lot! By contrast, MPC have a 96 ppq resolution. Because a hard swing of 70% translates into hardly 2 MIDI ticks at 24 ppq, doing the swing on top of the ticks will not be accurate at all!
The only solution is to vary the internal tempo before and after each 8th note. The drawback (or advantage) is that the MIDI clock being sent will also move, reflecting the same swing. Since the Swing knob value is actually between 0 and 25 (to be read from50% to 75%), the tempo before (t-) and the tempo after (t+), are given by:
t+/- = (50 +/- swing) * t / 50
where t is the base loop period without swing
Video Demo
Here is a video demo. There are only 3 instances, selected by the switches 1, 2 and 3; the first switch selects the GLOBAL settings: step duration (quarter, 8th etc.), swing factor, tempo. Each instance can be set its Phase, Stretch, MIDI note, velocity and MIDI channel. Here I have preset the MIDI channels, instance 1 on channel 1 (the microKorg) and instances 2 and 3 on channel 2 (the MPC with a drum kit).
The goal is to build a simple beat by only adjusting the parameters.
Please note that some parts of the code are not used any more, such as the big constant arrays, and some comments are not up to date (e-g no prime number anymore).
All analog inputs are wired to simple knobs. Digital inputs 8, 9, 10 , 11 are the four buttons used to switch pages. Digital output 12 is the activity LED (showing when the knob is active within the knob pagination). MIDI out is on the Tx pin.
/*
* Generative rhythm sequencer, more details at: http://cyrille.martraire.com
*
* Knob mapping according to a grid 2^n . prime^m, against the MIDI 24 ticks/quarter.
*
* Knob pagination to multiplex the knobs several times with LED to show activity.
*
* Memory-less event handling thanks to maths relationships.
*
* MIDI note on output on every 16 channel and MIDI clock according to tempo.
//---------- USER INPUT AND PAGINATION -----------
#define PAGE_NB 4
#define KNOB_NB 6
#define FIRST_PAGE_BUTTON 8
#define PROTECTED -1
#define ACTIVE 1
#define SYNC_LED 12
// the permanent storage of every value for every page, used by the actual music code
int pageValues[PAGE_NB][KNOB_NB];
// last read knob values
int knobsValues[KNOB_NB];
// knobs state (protected, enable...)
int knobsStates[KNOB_NB];
// current (temp) value just read
int value = 0;
// the current page id of values being edited
int currentPage = 0;
// signals the page change
boolean pageChange = false;
//temp variable to detect when the knob's value matches the stored value
boolean inSync = false;
int maxValue = 890;
int scaleLen = 15;
int *scale = scale3;
int step = 60;
int center = 30;
int coeff = 10;
//---------- GENERATIVE MUSIC CODE ---------
unsigned int cursor = 0;
int bars = 1;
int length = bars * 4 * 24;
// INPUTS
int PHASE = 0;
int STRETCH = 1;
//int DIRECTION = 2;
int NOTE = 2;
int DURATION = 3;
int VELOCITY = 4;
int CHANNEL = 5;
// GLOBAL KNOBS (seed and global settings)
int seedDuration = 24;
int seedTimes = 8;
int instanceNb = 4;
int swing = 0;//0..25% (on top of 50%)
//
int loopPeriod = 125/6;//120BPM
int actualPeriod = loopPeriod;
//instance i
int phase = 0;
int stretch = 1;
int note = 48;
int duration = 24;
int velocity = 100;
int channel = 1;
// custom map function, with min value always 0, and out max cannot be exceeded
long mapC(long x, long in_max, long out_min, long out_max)
{
if (x > in_max) {
return out_max;
}
return x * (out_max - out_min) / in_max + out_min;
}
// for each instance, and for the given cursor, is there a pulse?
boolean isPulse(byte phase, byte stretch){
int num = cursor - phase;
int denum = seedDuration * stretch / 4;
return num % denum == 0;
}
// Sends a MIDI tick (expected to be 24 ticks per quarter)
void midiClock(){
Serial.print(0xF8, BYTE);
}
// plays a MIDI note for one MIDI channel. Does not check that
// channel is less than 15, or that data values are less than 127:
void noteOn(char channel, char noteNb, char velo) {
midiOut(0x90 | channel, noteNb, velo);
}
// plays a MIDI message Status, Data1, Data2, no check
void midiOut(char cmd, char data1, char data2) {
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}
// read knobs and digital switches and handle pagination
void poolInputWithPagination(){
// read page selection buttons
for(int i = FIRST_PAGE_BUTTON;i < FIRST_PAGE_BUTTON + PAGE_NB; i++){
value = digitalRead(i);
if(value == LOW){
pageChange = true;
currentPage = i - FIRST_PAGE_BUTTON;
}
}
// if page has changed then protect knobs (unfrequent)
if(pageChange){
pageChange = false;
digitalWrite(SYNC_LED, LOW);
for(int i=0; i < KNOB_NB; i++){
knobsStates[i] = PROTECTED;
}
}
// read knobs values, show sync with the LED, enable knob when it matches the stored value
for(int i = 0;i < KNOB_NB; i++){
value = analogRead(i);
inSync = abs(value - pageValues[currentPage][i]) < 20;
// enable knob when it matches the stored value
if(inSync){
knobsStates[i] = ACTIVE;
}
// if knob is moving, show if it's active or not
if(abs(value - knobsValues[i]) > 5){
// if knob is active, blink LED
if(knobsStates[i] == ACTIVE){
digitalWrite(SYNC_LED, HIGH);
} else {
digitalWrite(SYNC_LED, LOW);
}
}
knobsValues[i] = value;
// if enabled then miror the real time knob value
if(knobsStates[i] == ACTIVE){
pageValues[currentPage][i] = value;
}
}
}
In the post “Playing with laser beams to create very simple rhythms” I explained a theoretical approach that I want to materialize into an instrument. The idea is to create complex rhythms by combining several times the same rhythmic patterns, but each time with some variation compared to the original pattern.
Several possible variations (or transforms, since a variation is generated by applying a transform to the original pattern) were proposed, starting from an hypothetical rhythmic pattern “x.x.xx..”. Three linear transforms: Reverse (”..xx.x.x”), Roll (”x.x.xx..”) and Scale 2:1 (”x…x…x.x…..”) or 1:2 (”xxx.”), and some non-linear transforms: Truncate (”xx..”) etc.
Geometry + Light = Tangible transforms
The very idea behind the various experiments made using laser light beams and LDR sensors is to build an instrument that proposes all the previous transforms in a tangible fashion: when you move physical object, you also change the rhythm accordingly.
Let’s consider a very narrow light beam turning just like the hands of a clock. Let’s suppose that our clock has no number written around, but we can position marks (mirrors) wherever on the clock surface. Still in the context of creating rhythms, now assume that every time a hand crosses a mark (mirror) we trigger a sound. So far we have a rhythmic clock, which is a funny instrument already. But we can do better…
Going back to our rhythmic pattern “x.x.xx..”, we can represent it with 4 mirrors that we position on a same circle. On the illustration below this original pattern is displayed in orange, each mirror shown by an X letter.. If we now link these 4 mirrors together with some adhesive tape, we have built a physical object that represents a rhythmic pattern. The rotating red line represents the laser beam turning like the clock hands.
Illustration of how the geometry of the rhythmic clock physically represents the transforms
Now we have a physical pattern (the original one), we can of course create copies of it (need more mirrors and more adhesive tape). We can then position the copies elsewhere on the clock. The point is that where you put a copy defines the transform that applies to it compared with the original pattern:
If we just shift a pattern left or right while remaining on the same circle, then we are actually doing the Roll transform (change the phase of the pattern) (example in blue on the picture)
If we reverse the adhesive tape with its mirrors glued on, then of course we also apply the Reverse transform to the pattern (example in grey on the picture)
If we move the pattern to another (concentric) circle, then we are actually applying the Scale transform, where the scaling coefficient is the fraction of the radius of the circle over the radius of the circle of the original pattern (example in green on the picture)
Therefore, simple polar geometry is enough to provide a complete set of physical operations that fully mimic the desired operations on rhythmic pattern. And since this geometry is in deep relationship with how the rhythm is being made, the musician can understand what’s happening and how to place the mirrors to get any the desired result. The system is controllable.
To apply the Truncate transform (that is not a linear transform) we can just stick a piece of black paper to hide the mirror(s) we want to mute.
If we layer the clock we just described, with one layer for each timbre to play, then again changing the timbre (yet another non-linear transform) can then be done by physically moving the pattern (mirrors on adhesive tape) across the layers.
From theory to practice
Second prototype, with big accuracy issues
Though appealing in principle, this geometric approach is hard to implement into a physical installation, mostly because accuracy issues:
The rotating mirror must rotate perfectly, with no axis deviation; any angular deviation is multiplied by two and then leads to important position deviation in the light spot in the distance: delta = distance . tan(2 deviation angle)
Each laser module is already not very accurate: the light beam is not always perfectly aligned with the body. To fix that would require careful tilt and pan adjustment on the laser module support
Positioning the retroreflectors in a way that is accurate and easy to add, move or remove at the same time is not that easy; furthermore, even if in theory the retroreflectors reflect all the incoming light back to where it comes from, in practice maximum reflectance happens when the light hits the reflector orthogonally, which is useful to prevent missed hits
Don’t hesitate to check these pages for progress, and any feedback much appreciated.
Once again, the rotating mirror is reflecting the four parallel laser beams so that they sweep a 180 degrees area, where some retroreflectors are positioned to hit the beams trajectories.
Every time a beam hits a reflector then it should trigger a sound on a MIDI synth (here it is my little microkorg playing the sounds).
Generative music (a.k.a mangled rhythm)
However in the first try I forgot to set a short loop perid (the period was set to 100ms). Given the velocity of the laser beam when it hits the reflectors there is very little time to catch the signal on the sensors, and with a measure every 100ms the Arduino is missing most hits.
This means we got a simple and regular theoretical rhythm that is mangled by the input sampling process, and this fuzzyness actually creates “interesting” generative music, as in the video:
Note that it is not totally random… (actually it is not random at all, just the result of different frequencies that sometime are in sync and most times are not).
Laser beams on the wall
Regular rhythm at last
With a shorter Arduino loop period (10ms) it becomes reliable: every (almost) hit triggers a note, as illustrated in the next video where we can hear a steady rhythmic pattern.
The Arduino code is quite simple: for each of the 4 sensors, read analog value, compare to threshold, debounce (not to send multiple notes for the actual same hit), then send MIDI note.
Just like many arts, music arousal is considered to follow the well-known Wundt curve that defines the balance between attractiveness and boredom. Too much repetition is boring, not enough repetition is confusing and considered just noise.
What for?
Let us assert that idea to music, to generate rhythms. A very simple application of the Wundt curve principle is to consider one given rhythmic pattern (e-g. , “x.x.xx..”) then to build up a more elaborate polyrhythm by combining various repetitions of it, although each copy must be distorted a bit to make the combination more complex hence more attractive. In other word, given a rhythmic seed, make it grow a rhythmic tree.
The transforms to apply to the rhythmic patterns can be linear:
Reverse (“..xx.x.x”)
Roll (“x.x.xx..”)
Scale 2:1 (“x…x…x.x…..”) or 1:2 (“xxx.”)
or non-linear:
Truncate (“xx..”)
Switch timbre (not really a transform, just to put somewhere)
In practice
To put that into practice I have been trying simple Java programs long ago, but it was too slow a process, and since I did not build a genetic algorithm around it was driven at random.
To make it more fun to investigate, we have started a small project of building an instrument to program rhythms on using laser beams and small reflectors. Each reflector triggers a sound (on a MIDI controlled MPC500) when hit by a laser beam (you need the sound on to listen to the Clap sound being triggered):
Then by having several reflectors linked to each other to make patterns, we expect to be able to program rhythms by moving reflectors sets in the playground, using its geometry to derive the transformations to apply to the patterns.