Modern Device >>
I’m a fan of experimental composer Terry Riley (try some of his organ work like Shri Camel to get started), so it seemed natural to try to adapt his 1964 algorithmic composition “In C” for the Arduino with our Fluxamasynth Shield.
In C was written for 20 to 35 players. Each player works their way through 53 short phrases, listening to the other players and following the rules of the score. The basic structural rules are that a player repeats a phrase as long as they like before moving to the next. Players always move forward through the score, and the piece is finished when everyone reaches the end, which usually takes around 40 minutes at the recommended tempo.
I decided to add a potentiometer to the Arduino version of the piece; the pot controls the tempo and allows you to speed up the 40 minute performance to 3 minutes or so.
The code is one of the standard examples distributed with the Fluxamasynth library available on github. It illustrates the use of the library for assigning instruments and effects to channels, and shows one way you might encode a score for use with the Fluxamasynth. The pan() function also shows how you might extend the library. Note that the Fluxamasynth just takes MIDI commands you could use this with any MIDI instrument; it is like having the whole composition in a box. An In C appliance.
// // Terry Riley's In C // // This sketch implements Terry Riley's "In C" composition for // the Fluxamasynth Shield.. // For the score and more background visit: // http://en.wikipedia.org/wiki/In_C // http://imslp.org/wiki/In_C_(Riley,_Terry) // // http://moderndevice.com/product/fluxamasynth-shield/ // https://github.com/moderndevice/Fluxamasynth-Shield // // This code expects an analog input on A1 to control tempo #include#include #define numInstruments 13 #define numParts 53 Fluxamasynth synth; // The PgmChange.h header defines all of these instrument names int instrument[numInstruments] = { BANK0_Vibraphone, BANK0_Marimba, BANK0_ElPiano1, BANK0_Vibraphone, BANK0_ElPiano1, BANK0_ElPiano1, BANK0_Vibraphone, BANK0_Marimba, BANK0_ElGrd_Piano3, BANK0_Vibraphone, BANK0_Marimba, BANK0_SynthBass1, BANK0_Grand_Piano1 }; // An array containing the score. The first element is a MIDI note 0-127 // followed by a duration in sixteenth notes. Each part ends with a 255 // byte score[] = { 0, 1, 255, // part 0 60, 1, 64, 3, 60, 1, 64, 3, 60, 1, 64, 3, 255, // part 1 60, 1, 64, 1, 65, 2, 64, 2, 0, 3, 255, // part 2 0, 2, 64, 2, 65, 2, 64, 2, 255, // part 3 0, 2, 64, 2, 65, 2, 67, 2, 255, // part 4 64, 2, 65, 2, 67, 2, 0, 2, 255, // part 5 72, 16, 72, 16, 255, // part 6 0, 14, 60, 1, 60, 1, 60, 2, 0, 18, 255, // part 7 67, 24, 65, 16, 65, 16, 255, // part 8 71, 1, 67, 1, 0, 14, 255, // part 9 71, 1, 67, 1, 255, // part 10 65, 1, 67, 1, 71, 1, 67, 1, 71, 1, 67, 1, 255, // part 11 65, 2, 67, 2, 71, 16, 71, 4, 255, // part 12 71, 1, 67, 3, 67, 1, 65, 1, 67, 2, 0, 3, 67, 7, 255, // part 13 72, 16, 71, 16, 67, 16, 66, 16, 255, // part 14 67, 1, 0, 15, 255, // part 15 67, 1, 71, 1, 72, 1, 71, 1, 255, // part 16 71, 1, 72, 1, 71, 1, 72, 1, 71, 1, 0, 1, 255, // part 17 64, 1, 68, 1, 64, 1, 68, 1, 64, 3, 64, 2, 255, // part 18 0, 6, 79, 6, 255, // part 19 64, 1, 66, 1, 64, 1, 66, 1, 57, 3, 64, 1, 65, 1, 64, 1, 65, 1, 64, 1, 255, // part 20 66, 12, 255, // part 21 64, 6, 64, 6, 64, 6, 64, 6, 64, 6, 66, 6, 67, 6, 69, 6, 71, 2, 255, // part 22 64, 2, 66, 6, 66, 6, 66, 6, 66, 6, 67, 6, 69, 6, 71, 6, 255, // part 23 64, 2, 66, 2, 67, 6, 67, 6, 67, 6, 67, 6, 67, 6, 69, 6, 71, 2, 255, // part 24 64, 2, 66, 2, 67, 2, 69, 6, 69, 6, 69, 6, 69, 6, 69, 6, 71, 6, 255, // part 25 64, 2, 66, 2, 67, 2, 69, 2, 71, 6, 71, 6, 71, 6, 71, 6, 71, 6, 255, // part 26 64, 1, 66, 1, 64, 1, 66, 1, 67, 2, 64, 1, 67, 1, 66, 1, 64, 1, 66, 1, 64, 1, 255, // part 27 64, 1, 66, 1, 64, 1, 66, 1, 64, 3, 64, 1, 255, // part 28 64, 12, 67, 12, 72, 12, 255, // part 29 72, 24, 255, // part 30 67, 1, 65, 1, 67, 1, 71, 1, 67, 1, 71, 1, 255, // part 31 65, 1, 67, 1, 65, 1, 67, 1, 71, 1, 65, 13, 67, 6, 255, // part 32 67, 1, 65, 1, 0, 2, 255, // part 33 67, 1, 65, 1, 255, // part 34 65, 1, 67, 1, 71, 1, 67, 1, 71, 1, 67, 1, 71, 1, 67, 1, 71, 1, 67, 1, 0, 14, 70, 4, 79, 12, 81, 2, 79, 4, 83, 2, 79, 6, 79, 2, 76, 12, 79, 2, 78, 14, 0, 10, 76, 10, 77, 24, 255, // part 35 65, 1, 67, 1, 71, 1, 67, 1, 71, 1, 67, 1, 255, // part 36 65, 1, 67, 1, 255, // part 37 65, 1, 67, 1, 71, 1, 255, // part 38 71, 1, 67, 1, 65, 1, 67, 1, 71, 1, 72, 1, 255, // part 39 71, 1, 65, 1, 255, // part 40 71, 1, 67, 1, // part 41 72, 16, 71, 16, 69, 16, 72, 16, 255, // part 42 77, 1, 76, 1, 77, 1, 76, 1, 76, 2, 76, 2, 76, 2, 77, 1, 76, 1, 255, // part 43 77, 2, 76, 4, 76, 2, 72, 4, 255, // part 44 74, 4, 74, 4, 67, 4, 255, // part 45 67, 1, 74, 1, 76, 1, 74, 1, 0, 2, 67, 2, 67, 2, 0, 2, 67, 2, 67, 1, 74, 1, 76, 1, 74, 1, 255, // part 46 74, 1, 76, 1, 74, 2, 255, // part 47 67, 24, 67, 16, 64, 16, 64, 4, 255, // part 48 65, 1, 67, 1, 70, 1, 67, 1, 70, 1, 67, 1, 255, // part 49 65, 1, 67, 1, 255, // part 50 65, 1, 67, 1, 70, 1, 255, // part 51 67, 1, 70, 1, 255, // part 52 70, 1, 67, 1, 255 // part 53 }; unsigned long startTime; int chance; int max = 0; int spread = 0; int targetVolume=127; int startPart = 1; int partIndices[53]; int partBeats[53]; int index[numInstruments]; int part[numInstruments]; int beat[numInstruments]; int startDelay[numInstruments]; int note[numInstruments]; int volume[numInstruments]; int prevNote[numInstruments]; int noteCount[numInstruments]; boolean playNote[numInstruments]; boolean hitEnd[numInstruments]; boolean started[numInstruments]; boolean finished[numInstruments]; int numFinished = 0; int tempo = 30; // 30 to 150, center is 90 void setNextNote(int j) { // Sets up the next note to be played if (index[j] > 0) { prevNote[j] = score[index[j]-1]; } else { prevNote[j] = 0; } note[j] = score[index[j]]; if (j == 11) { note[j] -= 24; } noteCount[j] = score[index[j]+1]; playNote[j] = true; } void setup() { // The tempo is determined by a potentiometer on Analog 1. pinMode(A0, OUTPUT); pinMode(A2, OUTPUT); digitalWrite(A0, LOW); // pot is powered by A0 and A2 digitalWrite(A2, HIGH); // Calculate number of beats in each part int beatCount = 0; int c = 3; partIndices[0] = 0; for (int i=1; i<53; i++) { partIndices[i]=c; while (score[c] != 255) { c++; beatCount+=score[c]; c++; } c++; partBeats[i] = beatCount; beatCount=0; } synth.setMasterVolume(75); // Set up the individual instruments for (int i=0; i = partBeats[part[i]]) { beat[i] = 0; // Add a spread to hold back the lead if it gets too far ahead if ((max-part[i] > 4)) { chance = 50; } else { chance = 90; } if ((max == part[i]) && (spread > 4)) { chance = 99; } if ((random(1, 100) > chance)) { part[i]++; if ((i==9) || (random(1, 100)>90)) { synth.setChannelVolume(i, 0); } else { synth.setChannelVolume(i, volume[i]); } max = 0; spread=0; for (int j=0; j max) { max = part[j]; } if ((max-part[j])>spread) { spread = max-part[j]; } } if (part[i]>numParts) { finished[i] = true; numFinished++; } } index[i] = partIndices[part[i]]; } else { index[i] = index[i]+2; } setNextNote(i); } } } delay(tempo-(millis()-startTime)); } void pan(int channel, int value) { // TODO: Add this to library byte command[3] = { (0xb0 | (channel & 0x0f)), 0x0A, (value) }; synth.fluxWrite(command, 3); }
The post Terry Riley’s In C for Arduino with the Fluxamasynth appeared first on Modern Device.