Code: Select all
/*
Fluxamasynth.cpp
A library to facilitate playing music on the Modern Device Fluxamasynth board.
More info at www.moderndevice.com
This software is in the public domain.
*/
/*
2011-05-05 steve cooley (the impatient)
mutilation of perfectly functional code, just to get the software serial working on pin 4. Does. It. Work??
Not yet.
*/
#include "WProgram.h"
#include "Fluxamasynth.h"
#include <SoftwareSerial.h>
SoftwareSerial mySerial = SoftwareSerial(5, 4);
Fluxamasynth::Fluxamasynth() {
mySerial.begin(31250);
}
void Fluxamasynth::noteOn(byte channel, byte pitch, byte velocity) {
// byte command[3] = { 0x90 | (channel & 0x0f), pitch, velocity };
mySerial.print(0x90 | (channel & 0x0f), BIN);
mySerial.print(pitch, BIN);
mySerial.print(velocity, BIN);
}
void Fluxamasynth::noteOff(byte channel, byte pitch) {
// byte command[3] = { 0x80 | (channel & 0x0f), pitch, byte(0x00) };
// mySerial.write(command, 3);
mySerial.print(0x80 | (channel & 0x0f), BIN);
mySerial.print(pitch, BIN);
mySerial.print(0x00, BIN);
}
void Fluxamasynth::programChange(byte bank, byte channel, byte v) {
// bank is either 0 or 127
// byte command[3] = { 0xB0 | (channel & 0x0f), byte(0x00), bank };
// mySerial.write(command, 3);
// mySerial.write(0xc0 | (channel & 0x0f));
// mySerial.write(v);
mySerial.print(0xB0 | (channel & 0x0f), BIN);
mySerial.print(byte(0x00), BIN);
mySerial.print(bank, BIN);
mySerial.print(0xc0 | (channel & 0x0f), BIN);
mySerial.print(v, BIN);
}
void Fluxamasynth::pitchBend(byte channel, int v) {
// v is a value from 0 to 1023
// it is mapped to the full range 0 to 0x3fff
v = map(v, 0, 1023, 0, 0x3fff);
// byte command[3] = { 0xe0 | (channel & 0x0f), byte(v & 0x00ef), byte(v >> 7) };
// mySerial.write(command, 3);
mySerial.print(0xe0 | (channel & 0x0f), BIN);
mySerial.print(byte(v & 0x00ef), BIN);
mySerial.print(byte(v >> 7) , BIN);
}
void Fluxamasynth::pitchBendRange(byte channel, byte v) {
// Also called pitch bend sensitivity
//BnH 65H 00H 64H 00H 06H vv
// byte command[7] = {0xb0 | (channel & 0x0f), 0x65, 0x00, 0x64, 0x00, 0x06, (v & 0x7f)};
// mySerial.write(command, 7);
mySerial.print(0xb0 | (channel & 0x0f), BIN);
mySerial.print(0x65, BIN);
mySerial.print(0x00, BIN);
mySerial.print(0x64, BIN);
mySerial.print(0x00, BIN);
mySerial.print(0x06, BIN);
mySerial.print((v & 0x7f), BIN);
}
void Fluxamasynth::midiReset() {
// mySerial.write(0xff);
mySerial.print(0xff, BIN);
}
void Fluxamasynth::setChannelVolume(byte channel, byte level) {
// byte command[3] = { (0xb0 | (channel & 0x0f)), 0x07, level };
// mySerial.write(command, 3);
mySerial.print((0xb0 | (channel & 0x0f)), BIN);
mySerial.print(0x07, BIN);
mySerial.print(level, BIN);
}
void Fluxamasynth::allNotesOff(byte channel) {
// BnH 7BH 00H
// byte command[3] = { (0xb0 | (channel & 0x0f)), 0x7b, 0x00 };
// mySerial.write(command, 3);
mySerial.print((0xb0 | (channel & 0x0f)), BIN);
mySerial.print(0x7b, BIN);
mySerial.print(0x00, BIN);
}
void Fluxamasynth::setMasterVolume(byte level) {
//F0H 7FH 7FH 04H 01H 00H ll F7H
// byte command[8] = { 0xf0, 0x7f, 0x7f, 0x04, 0x01, 0x00, (level & 0x7f), 0xf7 };
// mySerial.write(command, 8);
mySerial.print(0xf0, BIN);
mySerial.print(0x7f, BIN);
mySerial.print(0x7f, BIN);
mySerial.print(0x04, BIN);
mySerial.print(0x01, BIN);
mySerial.print(0x00, BIN);
mySerial.print((level & 0x7f), BIN);
mySerial.print(0xf7, BIN);
}
void Fluxamasynth::setReverb(byte channel, byte program, byte level, byte delayFeedback) {
// Program
// 0: Room1 1: Room2 2: Room3
// 3: Hall1 4: Hall2 5: Plate
// 6: Delay 7: Pan delay
// mySerial.write(0xb0 | (channel & 0x0f));
// mySerial.write(0x50);
// mySerial.write(program & 0x07);
// Set send level
// mySerial.write(0xb0 | (channel & 0x0f));
// mySerial.write(0x5b);
// mySerial.write(level & 0x7f);
mySerial.print(0xb0 | (channel & 0x0f), BIN);
mySerial.print(0x50, BIN);
mySerial.print(program & 0x07, BIN);
// Set send level
mySerial.print(0xb0 | (channel & 0x0f), BIN);
mySerial.print(0x5b, BIN);
mySerial.print(level & 0x7f, BIN);
if (delayFeedback > 0) {
//F0H 41H 00H 42H 12H 40H 01H 35H vv xx F7H
//byte command[11] = { 0xf0, 0x41, byte(0x00), 0x42, 0x12, 0x40, 0x01, 0x35, (delayFeedback & 0x7f), 0xf7 };
//mySerial.write(command, 11);
mySerial.print(0xf0, BIN);
mySerial.print(0x41, BIN);
mySerial.print(byte(0x00), BIN);
mySerial.print(0x42, BIN);
mySerial.print(0x12, BIN);
mySerial.print(0x40, BIN);
mySerial.print(0x01, BIN);
mySerial.print(0x35, BIN);
mySerial.print(0x01, BIN);
mySerial.print((delayFeedback & 0x7f), BIN);
mySerial.print(0xf7, BIN);
}
}
void Fluxamasynth::setChorus(byte channel, byte program, byte level, byte feedback, byte chorusDelay) {
// Program
// 0: Chorus1 1: Chorus2 2: Chorus3
// 3: Chorus4 4: Feedback 5: Flanger
// 6: Short delay 7: FB delay
// mySerial.write(0xb0 | (channel & 0x0f));
// mySerial.write(0x51);
// mySerial.write(program & 0x07);
mySerial.print(0xb0 | (channel & 0x0f), BIN);
mySerial.print(0x51, BIN);
mySerial.print(program & 0x07, BIN);
// Set send level
// mySerial.write(0xb0 | (channel & 0x0f));
// mySerial.write(0x5d);
// mySerial.write(level & 0x7f);
mySerial.print(0xb0 | (channel & 0x0f), BIN);
mySerial.print(0x5d, BIN);
mySerial.print(level & 0x7f, BIN);
if (feedback > 0) {
//F0H 41H 00H 42H 12H 40H 01H 3BH vv xx F7H
// byte command[11] = { 0xf0, 0x41, byte(0x00), 0x42, 0x12, 0x40, 0x01, 0x3B, (feedback & 0x7f), 0xf7 };
// mySerial.write(command, 11);
mySerial.print(0xf0, BIN);
mySerial.print(0x41, BIN);
mySerial.print(byte(0x00), BIN);
mySerial.print(0x42, BIN);
mySerial.print(0x12, BIN);
mySerial.print(0x40, BIN);
mySerial.print(0x01, BIN);
mySerial.print(0x3B, BIN);
mySerial.print((feedback & 0x7f), BIN);
mySerial.print(0xf7, BIN);
}
if (chorusDelay > 0) {
// F0H 41H 00H 42H 12H 40H 01H 3CH vv xx F7H
// byte command[11] = { 0xf0, 0x41, byte(0x00), 0x42, 0x12, 0x40, 0x01, 0x3C, (chorusDelay & 0x7f), 0xf7 };
// mySerial.write(command, 11);
mySerial.print(0xf0, BIN);
mySerial.print(0x41, BIN);
mySerial.print(byte(0x00), BIN);
mySerial.print(0x42, BIN);
mySerial.print(0x12, BIN);
mySerial.print(0x40, BIN);
mySerial.print(0x01, BIN);
mySerial.print(0x3C, BIN);
mySerial.print((chorusDelay & 0x7f), BIN);
mySerial.print(0xf7, BIN);
}
}
Code: Select all
#include <SoftwareSerial.h>
#include <Fluxamasynth.h>
Fluxamasynth synth;
int counter = 0;
int channel = 0;
int voice = 0;
int j = 0;
void setup() {
Serial.begin(57600);
Serial.println("hello world");
synth.programChange(0, 9, 40);
synth.programChange(0, 1, 0);
}
void loop()
{
while(counter < 128)
{
if(voice >128)
{
voice = 0;
}
synth.programChange(channel, 0, voice);
Serial.print("program changed - voice : ");
Serial.println(voice);
for(int i=0; i<10; i++)
{
int note = int(random(36,100));
synth.noteOn(channel, note, 127); // play 1 note (C4) on channel 0
Serial.print("played note ");
Serial.print(note);
Serial.print(" on channel ");
Serial.println(channel);
int coinflip = int(random(0,20));
if(coinflip == 5)
{
while(j < 200)
{
synth.pitchBend(channel, j);
j+= 16;
delay(10);
}
j = 0;
}
delay(100);
synth.noteOff(channel, note);
}
voice++;
/*
synth.noteOn(1, c3, 127);
synth.noteOn(1, e3, 127); // play 3 notes (C3, E3, G3) on channel 1
synth.noteOn(1, g3, 127);
//delay(1000);
synth.noteOff(1, c3);
synth.noteOff(1, e3);
synth.noteOff(1, g3);
*/
}
Serial.println("counter = "+counter);
channel++;
counter++;
Serial.println("looping...");
}