The Fluxamasynth is well suited for making musical appliances. One example is from a series of Soundboxen; this one is inspired by Brian Eno's Music for Airports tape loops. For this appliance the length of each loop is determined by one of the potentiometers. The Arduino code for Fluxamasynth is here:
// Inspired by Eno's Music for Airports #2:
// F2 G#2 C3 C#3 D#3 F3 G#3
// Reads poteniometers on A0-A5
#include "Fluxamasynth.h"
Fluxamasynth synth;
int tones[6] = { 29, 32, 36, 37, 39, 41 };
int instruments[6] = { 55, 55, 55, 55, 55, 55 };
int tapeLength[6] = { 30, 31, 32, 33, 34, 35 };
int startingPoint[6] = { 0, 1, 2, 3, 4, 5 };
int length[6] = { 100, 110, 120, 130, 140, 150 };
int lengthCount[6] = { 0, 0, 0, 0, 0, 0 };
int tempo[6] = { 1000, 2000, 3000, 4000, 5000, 6000 };
int tempoCount[6] = { 0, 0, 0, 0, 0, 0 };
long int startTime = 0;
void setup() {
Serial.begin(9600);
int seed = 0;
for (int i=0; i<6; i++) {
seed += analogRead(i);
}
randomSeed(seed);
delay(100);
for (int i=0; i<6; i++) {
synth.setChannelVolume(i, 255 );
synth.allNotesOff(i);
synth.setReverb(i, 5, 64, 0);
synth.pan(5-i,127/(6*(i+1)));
}
changeProgram();
startTime = 0;
}
void changeProgram() {
for (int i=0; i<6; i++) {
synth.programChange(0, i,random(127));
}
}
void loop() {
if (millis() > (startTime + 5000)) {
changeProgram();
startTime = millis();
Serial.println("changeProgram");
}
int ledTempo = 0;
for (int i=0; i<6; i++) {
int val = analogRead(i);
tempo[i] = 5100 - map(val, 0, 1023, 100, 5000);
tempoCount[i]++;
if (tempoCount[i] > tempo[i]) {
if (lengthCount[i] == 0) {
synth.noteOn(i, tones[i], 127);
}
lengthCount[i]++;
if (lengthCount[i] > length[i]) {
synth.noteOff(i, tones[i]);
lengthCount[i] = 0;
tempoCount[i] = 0;
}
}
}
delay(1);
}
Here's the result:
Here's one more example of a musical appliance: a radio station broadcasting generative music using Orff instruments on 102.5. This uses the Adafruit FM transmitter module and a Fluxamasynth to generate the music.
And the Arduino code:
#include <Wire.h>
#include <Adafruit_Si4713.h>
#include <fluxamasynth.h>
#include <pgmchange.h></pgmchange.h></fluxamasynth.h>
#define RESETPIN 12
//#define FMSTATION 8830 // 10230 == 102.30 MHz
#define FMSTATION 10250
Adafruit_Si4713 radio = Adafruit_Si4713(RESETPIN);
Fluxamasynth synth = Fluxamasynth();
#define numInstruments 4
byte parts[4];
int measures[16];
int notes[16];
int rhythm[16];
int percussion[16];
char partName[4] = {'a','b','c','d'};
int noteName[16];
int binaryChoice[16];
int noteOn[4] = {0, 0, 0, 0};
int rhythmOn[4] = {0, 0, 0, 0};
int tempo=30;
// Limit instrument choice
int instrument[numInstruments] = {13, 13, 13, 13};
void setup() {
randomSeed(millis()+analogRead(0));
Serial.begin(9600);
chooseParts();
synth.setMasterVolume(127);
for (int i=0; i<numInstruments; i++) {
synth.programChange(0, i, instrument[i]);
pan(i,127/numInstruments*i);
//synth.setChannelVolume(i, volume[i]);
synth.setReverb(i, 3, 127, 25);
}
synth.setReverb(9,5,255,100); //Plate reverb
delay(1000);
Serial.println("Adafruit Radio - Si4713 Test");
if (! radio.begin()) { // begin with address 0x63 (CS high default)
Serial.println("Couldn't find radio?");
while (1);
}
}
void chooseParts() {
parts[0] = random(254)+1;
parts[1] = random(255);
parts[1] = parts[1] & (parts[1]^parts[0]);
parts[2] = random(255);
parts[2] = parts[2] & (parts[2]^(parts[0]|parts[1]));
parts[3] = ~(parts[0]|parts[1]|parts[2]);
}
void chooseMeasures(int p) {
measures[0+p] = random(254)+1;
measures[1+p] = random(255);
measures[1+p] = measures[1+p] & (measures[1+p]^measures[0+p]);
measures[2+p] = random(255);
measures[2+p] = measures[2+p] & (measures[2+p]^(measures[0+p]|measures[1+p]));
measures[3+p] = ~(measures[0+p]|measures[1+p]|measures[2+p]);
}
void chooseNotes(int p) {
int baseNote = random(40)+50;
noteName[p] = baseNote;
noteName[p+1]=baseNote + (random(3)-1)*7;
noteName[p+2]=baseNote + (random(3)-1)*4 + random(3)-1;
noteName[p+3]=baseNote + (random(3)-1)*random(8);
}
void chooseRhythm(int p) {
rhythm[0+p] = random(254)+1;
rhythm[1+p] = random(255);
rhythm[1+p] = rhythm[1+p] & (rhythm[1+p]^rhythm[0+p]);
rhythm[2+p] = random(255);
rhythm[2+p] = rhythm[2+p] & (rhythm[2+p]^(rhythm[0+p]|rhythm[1+p]));
rhythm[3+p] = ~(rhythm[0+p]|rhythm[1+p]|rhythm[2+p]);
}
void choosePercussion(int p) {
//percussion[p] = 36;
//percussion[p+1]=38;
//percussion[p+2]=42;
//percussion[p+3]=44;
percussion[p] = random(127);
percussion[p+1]=random(127);
percussion[p+2]=random(127);
percussion[p+3]=random(127);
}
void loop() {
// New Song
for (int i=0; i<numInstruments; i++) {
synth.allNotesOff(i);
}
tempo = random(200)+10;
for (int i=0; i<4; i++) {
instrument[i] = 13;
synth.programChange(0, i, instrument[i]);
}
int numSections = random(20)+60;
for (int m=0; m<4; m++) {
choosePercussion(m);
}
for (int sections=0; sections<numSections; sections++) {
chooseParts();
for (int m=0; m<4; m++) {
chooseMeasures(m);
chooseNotes(m);
chooseRhythm(m);
}
for (int i=0; i<16; i++) {
if (random(100)>50) {
binaryChoice[i] = 1;
} else {
binaryChoice[i] = 0;
}
}
tempo = tempo-random(tempo/160);
// TODO: Add four time channels: triplet, quad,
// quintuplet, septuplet
while(random(100)<10) {
for (int i=0; i<8; i++) {
Serial.println();
for (int part =0; part<4; part++) {
if ((parts[part]>>i) & 0x01) {
Serial.print(partName[part]);
for (int beat =0; beat<8; beat++) {
delay(tempo);
for (int voice=0; voice<4; voice++) {
if (((measures[part+voice]>>beat) & 0x01)==binaryChoice[part+voice]) {
if (noteOn[voice]!=noteName[part+voice]) {
if (noteOn[voice]==0) {
Serial.print(voice);
synth.noteOn(voice, noteName[part+voice], 127);
noteOn[voice] = noteName[part+voice];
} else {
synth.noteOff(voice, noteOn[voice]);
synth.noteOn(voice, noteName[part+voice], 127);
//Serial.print("PrevOff");
//Serial.print("On");
noteOn[voice] = noteName[part+voice];
}
} else {
//Serial.print("Hold");
}
} else {
if (noteOn[voice]) {
synth.noteOff(voice, noteOn[voice]);
noteOn[voice]=0;
}
}
if (((rhythm[part+voice]>>beat) & 0x01)==binaryChoice[part+voice]) {
if (!rhythmOn[voice]) {
rhythmOn[voice]=1;
synth.noteOn(9, percussion[voice], 100) ;
synth.noteOff(9, percussion[voice]) ;
}
} else {
rhythmOn[voice]=0;
}
}
}
}
}
}
}
}
delay(2000);
}
void pan(int channel, int value) {
// TODO: Add this to library (done)
byte command[3] = {
(0xb0 | (channel & 0x0f)), 0x0A, (value) };
synth.fluxWrite(command, 3);
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.