This commit is contained in:
gauthiier 2018-12-01 12:57:32 +01:00
parent 5aa8489eee
commit dd0197fa42
23 changed files with 3954 additions and 0 deletions

View File

@ -0,0 +1,447 @@
//______________________/\\\\\__________________________/\\\______________________________/\\\__________________________________________________________
// ____________________/\\\///__________________________\/\\\_____________________________\/\\\__________________________________________________________
// ___________________/\\\______________________________\/\\\_____________________________\/\\\_____/\\\__/\\\_______________________________/\\\\\\\\___
// _____/\\\\\\\\__/\\\\\\\\\_______/\\\\\______________\/\\\____________/\\\\\___________\/\\\____\//\\\/\\\___/\\\\\\\\\\_____/\\\\\\\\___/\\\////\\\__
// ___/\\\//////__\////\\\//______/\\\///\\\____________\/\\\\\\\\\____/\\\///\\\____/\\\\\\\\\_____\//\\\\\___\/\\\//////____/\\\/////\\\_\//\\\\\\\\\__
// __/\\\____________\/\\\_______/\\\__\//\\\___________\/\\\////\\\__/\\\__\//\\\__/\\\////\\\______\//\\\____\/\\\\\\\\\\__/\\\\\\\\\\\___\///////\\\__
// _\//\\\___________\/\\\______\//\\\__/\\\____________\/\\\__\/\\\_\//\\\__/\\\__\/\\\__\/\\\___/\\_/\\\_____\////////\\\_\//\\///////__________\/\\\__
// __\///\\\\\\\\____\/\\\_______\///\\\\\/_____________\/\\\\\\\\\___\///\\\\\/___\//\\\\\\\/\\_\//\\\\/_______/\\\\\\\\\\__\//\\\\\\\\\\________\/\\\\_
// ____\////////_____\///__________\/////_______________\/////////______\/////______\///////\//___\////________\//////////____\//////////_________\////__
// CFO BODYSEQ sequencer, 2 button version, reworked interaction, http://www.vsionhairies.info/
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
const int seqLed [] = {2,3,4,5,6,7,8,9};
int seqLedVal [] = {0,0,0,0,0,0,0,0};
const int statusLed1 = 10, statusLed2 = 11;
const int buttonPin [] = {12,13};
const int pot1 = A0, pot2 = A1;
const int bodySwitch [] = {A2,A3,A4,A5,A6,A7,A8,A9};
unsigned long lastPrint = millis();
boolean sequencerRunning = true;
float maxBodyReading = 0;
float maxBodyFadeout = 0.9999;
float averageNoise = 0;
int inputFreq = 10;
unsigned long lastInput = millis();
int seqStep = 0;
int seqLength = 7;
int seqNote[] = {-1,-1,0,-1,12,-1,-1,-1,-1,-1,0,-1,24,-1,-1,-1,-1,-1,0,-1,36,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1,-1,-1,0,-1,12,-1,-1,-1,-1,-1,0,-1,24,-1,-1,-1,-1,-1,0,-1,36,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1};
int activeSeq = 0, seqStart = 0, seqEnd = 7;
unsigned long lastStep = millis();
int stepTime = 200;
int baseNote = 36;
const int scale[3][7] = {
{0,2,4,5,7,9,11}, // major
{0,2,3,5,6,7,10}, // blues
{0,3,4,7,9,10,-1} // rock
};
const int scaleLength = 24;
int activeScale [scaleLength];
int bodySwitchVal [] = {0,0,0,0,0,0,0,0};
boolean bodySwitchesTouched = false;
int mode = 0;
int preset = 16;
boolean buttonState [] = {HIGH, HIGH};
boolean buttonAction [] = {false, false};
int potVal1 = 0, potVal2 = 0;
boolean pot1Moved = false, pot2Moved = false, potsMoved = false;
int potNoise = 1;
boolean debug = true;
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(16);
Music.setEnv1Decay(36);
Music.setEnv1Sustain(0);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
analogReadAveraging(32);
Serial.begin(9600);
delay(100);
Serial.println("hello");
pinMode(buttonPin[0], INPUT_PULLUP);
pinMode(buttonPin[1], INPUT_PULLUP);
newActiveScale(scaleLength);
pinMode(statusLed1,OUTPUT);
pinMode(statusLed2,OUTPUT);
for (int i = 0; i<8; i++) {
pinMode(seqLed[i], OUTPUT);
}
startupAnimation();
sampleAverageNoise();
}
void loop() {
// check for incoming USB MIDI messages
usbMIDI.read();
if (lastInput + inputFreq < millis()) {
// check user input
readPots();
readBodyswitches();
readButtons();
// general navigation
// button 0 pushed
if (buttonState[0] == LOW && buttonState[1] == HIGH) {
noteInputFromBodyswitches();
}
// button 1 pushed
if (buttonState[1] == LOW && buttonState[0] == HIGH) {
eraseNotesFromBodyswitches();
if (pot1Moved) {
// change sequencer speed
stepTime = map(analogRead(pot1),1023,0,1000,0);
potsMoved = false;
}
}
// both buttons pushed
if (buttonState[1] == LOW && buttonState[0] == LOW) {
changeMode();
activeSeq = mode;
if (pot2Moved) {
changePreset();
potsMoved = false;
}
if (pot1Moved) {
changeOctave();
potsMoved = false;
}
}
lastInput = millis();
}
if (sequencerRunning) updateSequence();
if (potsMoved) setCutoffFromPots();
}
void sampleAverageNoise() {
Serial.print("sampling average noise levels: ");
for (int i = 0; i<8; i++) {
averageNoise += analogRead(bodySwitch[i]);
}
averageNoise = averageNoise/8 + 3;
Serial.println(averageNoise);
}
void setCutoffFromPots() {
Music.setCutoff((1023-analogRead(pot1))*64);
Music.setCutoffModAmount((1023-analogRead(pot2))*64);
}
void updateLEDs() {
for (int i = 0; i<8; i++) {
if (seqNote[activeSeq*8+i] != -1) {
digitalWrite(seqLed[i], HIGH);
} else {
digitalWrite(seqLed[i], LOW);
}
}
}
void newActiveScale (int length) {
Serial.println("lets make a new active scale");
int amountOfNotesInScale = 0;
for (int i = 0; i<7; i++) {
if (scale[1][i] != -1) amountOfNotesInScale++;
}
for (int i = 0; i<length+1; i++) {
int currentOctave = i/amountOfNotesInScale;
Serial.print("octave ");
Serial.print(currentOctave);
int currentNote = scale[1][i%amountOfNotesInScale];
Serial.print("\tnote ");
Serial.print(currentNote);
activeScale[i] = currentOctave*12+currentNote;
Serial.print("\tthis yields ");
Serial.println(activeScale[i]);
}
}
void eraseNotesFromBodyswitches() {
for (int i = 0; i<8; i++) {
if (bodySwitchVal[i] > 0) {
seqNote[activeSeq*8+i] = -1;
}
}
updateLEDs();
}
void noteInputFromBodyswitches() {
for (int i = 0; i<8; i++) {
if (bodySwitchVal[i] > 0) {
if (debug) Serial.print(i);
if (debug) Serial.print(": ");
if (debug) Serial.print(bodySwitchVal[i]);
int note = map(bodySwitchVal[i],0,127,0,scaleLength-1);
if (debug) Serial.print("\tnote: ");
if (debug) Serial.print(note);
seqNote[activeSeq*8+i] = activeScale[note];
if (debug) Serial.print("\tseqNote: ");
if (debug) Serial.println(seqNote[activeSeq*8+i]);
}
}
updateLEDs();
}
void readPots() {
int newPotVal1 = analogRead(pot1);
int newPotVal2 = analogRead(pot2);
potsMoved = false;
if ( (newPotVal1 < (potVal1-potNoise)) || (newPotVal1 > (potVal1+potNoise)) ) {
potVal1 = newPotVal1;
pot1Moved = true;
potsMoved = true;
}
else {
pot1Moved = false;
}
if ( (newPotVal2 < (potVal2-potNoise)) || (newPotVal2 > (potVal2+potNoise)) ) {
potVal2 = newPotVal2;
pot2Moved = true;
potsMoved = true;
}
else {
pot2Moved = false;
}
if (potsMoved) {
Serial.print("pot 1 ");
Serial.println(potVal1);
Serial.print("pot 2 ");
Serial.println(potVal2);
}
}
void changeOctave() {
// change from pot
int newOctave = map(analogRead(pot1),1023,0,-3,4);
baseNote = 36 + newOctave*12;
for (int i = 0; i<8; i++) {
if (newOctave+3 == i) {
// SoftPWMSet(seqLed[i],255);
digitalWrite(seqLed[i],HIGH);
}
else {
// SoftPWMSet(seqLed[i],0);
digitalWrite(seqLed[i],LOW);
}
}
}
void changeMode() {
// select mode with body switches
int highest = -1, highestVal = averageNoise;
for (int i=0; i<8; i++) {
if (bodySwitchVal[i] > highestVal) {
highest = i;
highestVal = bodySwitchVal[i];
}
}
if (highest != -1) {
mode = highest;
}
updateLEDs();
}
void changePreset() {
int newPreset = map(analogRead(pot2),1023,0,63,0);
if (preset != newPreset) { // only do something if preset has changed
// NB! user preset 0-16 might be empty, resulting in crazy sounds!
if (debug) Serial.print("new preset ");
if (debug) Serial.println(newPreset);
preset = newPreset;
Music.getPreset(preset);
}
}
void updateSequence() {
if (lastStep + stepTime < millis()) {
seqStep++;
if (seqStep > seqEnd) seqStep = seqStart;
int note = activeSeq*8+seqStep;
if (seqNote[note] != -1) {
Music.noteOn(baseNote+seqNote[note]);
}
lastStep = millis();
}
updateLEDs();
int blinkTime = max(stepTime/5,100);
if (lastStep + blinkTime < millis()) {
digitalWrite(seqLed[seqStep], HIGH);
}
if (lastStep + stepTime - blinkTime < millis()) {
digitalWrite(seqLed[seqStep], LOW);
}
}
void readBodyswitches() {
bodySwitchesTouched = false;
for (int i = 0; i<8; i++) {
int reading = constrain(analogRead (bodySwitch[i]),0,127);
maxBodyReading = max(maxBodyReading, reading);
if (reading > averageNoise) { // averageNoise is sampled on startup
int midiVal = map (reading, averageNoise, maxBodyReading, 0, 127);
bodySwitchVal[i] = constrain(midiVal,0,127);
bodySwitchesTouched = true;
}
else {
bodySwitchVal[i] = 0;
reading = 0;
}
seqLedVal[i] = reading*2;
}
maxBodyReading = maxBodyReading * maxBodyFadeout;
}
void printFeedback() {
// for debugging purposes
for (int i = 0; i<8; i++) {
int reading = analogRead (bodySwitch[i]);
seqLedVal[i] = reading/4;
Serial.print(i);
Serial.print(": ");
Serial.print(reading);
Serial.print("\t");
}
Serial.println();
int potVal1 = analogRead(pot1);
int potVal2 = analogRead(pot2);
Serial.print(potVal1);
Serial.print("\t");
Serial.print(potVal2);
Serial.println();
}
void startupAnimation() {
digitalWrite(statusLed1, HIGH);
digitalWrite(statusLed2, HIGH);
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],LOW);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],LOW);
delay(30);
}
digitalWrite(statusLed1, LOW);
digitalWrite(statusLed2, LOW);
delay(100);
}
void readButtons() {
// buttons are active low
for (int i = 0; i<3; i++) {
if (digitalRead(buttonPin[i]) == HIGH) {
if (buttonState[i] == LOW) {
// button has just been released
buttonAction[i] = true;
if (debug) Serial.print("button ");
if (debug) Serial.print(i);
if (debug) Serial.println(" has just been released");
} else {
// button was already released, no action here
buttonAction[i] = false;
}
buttonState[i] = HIGH;
}
if (digitalRead(buttonPin[i]) == LOW) {
if (buttonState[i] == HIGH) {
// button has just been pushed
buttonAction[i] = true;
if (debug) Serial.print("button ");
if (debug) Serial.print(i);
if (debug) Serial.println(" has just been pushed");
buttonState[i] = LOW;
} else {
// button was already psuhed, no action here
buttonAction[i] = false;
}
}
}
}

View File

@ -0,0 +1,465 @@
//______________________/\\\\\__________________________/\\\______________________________/\\\__________________________________________________________
// ____________________/\\\///__________________________\/\\\_____________________________\/\\\__________________________________________________________
// ___________________/\\\______________________________\/\\\_____________________________\/\\\_____/\\\__/\\\_______________________________/\\\\\\\\___
// _____/\\\\\\\\__/\\\\\\\\\_______/\\\\\______________\/\\\____________/\\\\\___________\/\\\____\//\\\/\\\___/\\\\\\\\\\_____/\\\\\\\\___/\\\////\\\__
// ___/\\\//////__\////\\\//______/\\\///\\\____________\/\\\\\\\\\____/\\\///\\\____/\\\\\\\\\_____\//\\\\\___\/\\\//////____/\\\/////\\\_\//\\\\\\\\\__
// __/\\\____________\/\\\_______/\\\__\//\\\___________\/\\\////\\\__/\\\__\//\\\__/\\\////\\\______\//\\\____\/\\\\\\\\\\__/\\\\\\\\\\\___\///////\\\__
// _\//\\\___________\/\\\______\//\\\__/\\\____________\/\\\__\/\\\_\//\\\__/\\\__\/\\\__\/\\\___/\\_/\\\_____\////////\\\_\//\\///////__________\/\\\__
// __\///\\\\\\\\____\/\\\_______\///\\\\\/_____________\/\\\\\\\\\___\///\\\\\/___\//\\\\\\\/\\_\//\\\\/_______/\\\\\\\\\\__\//\\\\\\\\\\________\/\\\\_
// ____\////////_____\///__________\/////_______________\/////////______\/////______\///////\//___\////________\//////////____\//////////_________\////__
// CFO BODYSEQ sequencer, 3 button version, reworked interaction, http://www.vsionhairies.info/
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
const int seqLed [] = {3,4,5,6,7,8,9,10};
int seqLedVal [] = {0,0,0,0,0,0,0,0};
const int statusLed1 = 13;
const int buttonPin [] = {11,12,2};
const int pot1 = A0, pot2 = A1;
const int bodySwitch [] = {A2,A3,A4,A5,A6,A7,A8,A9};
unsigned long lastPrint = millis();
boolean sequenceRunning = true;
float maxBodyReading = 0;
float maxBodyFadeout = 0.9999;
float averageNoise = 0;
int inputFreq = 10;
unsigned long lastInput = millis();
int seqStep = 0;
int seqLength = 7;
int seqNote[] = {-1,-1,0,-1,12,-1,-1,-1,-1,-1,0,-1,24,-1,-1,-1,-1,-1,0,-1,36,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1,-1,-1,0,-1,12,-1,-1,-1,-1,-1,0,-1,24,-1,-1,-1,-1,-1,0,-1,36,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1};
int activeSeq = 0, seqStart = 0, seqEnd = 7;
unsigned long lastStep = millis();
int stepTime = 200;
int baseNote = 36;
const int scale[3][7] = {
{0,2,4,5,7,9,11}, // major
{0,2,3,5,6,7,10}, // blues
{0,3,4,7,9,10,-1} // rock
};
const int scaleLength = 24;
int activeScale [scaleLength];
int bodySwitchVal [] = {0,0,0,0,0,0,0,0};
boolean bodySwitchesTouched = false;
int mode = 0;
int preset = 16;
boolean buttonState [] = {HIGH, HIGH, HIGH};
boolean buttonAction [] = {false, false, false};
int potVal1 = 0, potVal2 = 0;
boolean pot1Moved = false, pot2Moved = false, potsMoved = false;
int potNoise = 1;
boolean debug = true;
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
// Music.setSampler(true);
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(21);
Music.setEnv1Decay(36);
Music.setEnv1Sustain(0);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Serial.begin(9600);
delay(100);
Serial.println("hello");
pinMode(buttonPin[0], INPUT_PULLUP);
pinMode(buttonPin[1], INPUT_PULLUP);
pinMode(buttonPin[2], INPUT_PULLUP);
newActiveScale(scaleLength);
pinMode(statusLed1,OUTPUT);
for (int i = 0; i<8; i++) {
pinMode(seqLed[i], OUTPUT);
}
startupAnimation();
sampleAverageNoise();
}
void loop() {
// check for incoming USB MIDI messages
usbMIDI.read();
if (lastInput + inputFreq < millis()) {
// check user input
readPots();
readBodyswitches();
readButtons();
// general navigation
// button 0 pushed
if (buttonState[0] == LOW) {
noteInputFromBodyswitches();
}
// button 1 pushed
if (buttonState[1] == LOW) {
eraseNotesFromBodyswitches();
if (pot1Moved) {
// change sequencer speed
stepTime = map(analogRead(pot1),0,1023,1000,0);
potsMoved = false;
}
}
// button 2 pushed
if (buttonState[2] == LOW) {
changeMode();
activeSeq = mode;
if (pot2Moved) {
changePreset();
potsMoved = false;
}
if (pot1Moved) {
changeOctave();
potsMoved = false;
}
}
// button 0 and 2 pushed
if (buttonState[2] == LOW && buttonState[0] == LOW) {
int lowestSwitch = 0, highestSwitch = 0;
if (bodySwitchesTouched) {
for (int i = 0; i<8; i++) {
if (bodySwitchVal[i] > 0) {
highestSwitch = i;
}
if (bodySwitchVal[7-i] > 0) {
lowestSwitch = 7-i;
}
}
seqStart = lowestSwitch;
seqEnd = highestSwitch;
}
}
lastInput = millis();
}
if (sequenceRunning) updateSequence();
if (potsMoved) setCutoffFromPots();
}
void sampleAverageNoise() {
Serial.print("sampling average noise levels: ");
for (int i = 0; i<8; i++) {
pinMode(seqLed[i], OUTPUT);
averageNoise += analogRead(bodySwitch[i]);
}
averageNoise = averageNoise/8 + 3;
Serial.println(averageNoise);
}
void setCutoffFromPots() {
Music.setCutoff((analogRead(pot1))*64);
Music.setCutoffModAmount((analogRead(pot2))*64);
}
void updateLEDs() {
for (int i = 0; i<8; i++) {
if (seqNote[activeSeq*8+i] != -1) {
digitalWrite(seqLed[i], HIGH);
}
else {
digitalWrite(seqLed[i], LOW);
}
}
}
void newActiveScale (int length) {
Serial.println("lets make a new active scale");
int amountOfNotesInScale = 0;
for (int i = 0; i<7; i++) {
if (scale[1][i] != -1) amountOfNotesInScale++;
}
for (int i = 0; i<length+1; i++) {
int currentOctave = i/amountOfNotesInScale;
Serial.print("octave ");
Serial.print(currentOctave);
int currentNote = scale[1][i%amountOfNotesInScale];
Serial.print("\tnote ");
Serial.print(currentNote);
activeScale[i] = currentOctave*12+currentNote;
Serial.print("\tthis yields ");
Serial.println(activeScale[i]);
}
}
void eraseNotesFromBodyswitches() {
for (int i = 0; i<8; i++) {
if (bodySwitchVal[i] > 0) {
seqNote[activeSeq*8+i] = -1;
}
}
updateLEDs();
}
void noteInputFromBodyswitches() {
for (int i = 0; i<8; i++) {
if (bodySwitchVal[i] > 0) {
if (debug) Serial.print(i);
if (debug) Serial.print(": ");
if (debug) Serial.print(bodySwitchVal[i]);
int note = map(bodySwitchVal[i],0,127,0,scaleLength-1);
if (debug) Serial.print("\tnote: ");
if (debug) Serial.print(note);
seqNote[activeSeq*8+i] = activeScale[note];
if (debug) Serial.print("\tseqNote: ");
if (debug) Serial.println(seqNote[activeSeq*8+i]);
}
}
updateLEDs();
}
void readPots() {
int newPotVal1 = 1023-analogRead(pot1);
int newPotVal2 = 1023-analogRead(pot2);
potsMoved = false;
if ( (newPotVal1 < (potVal1-potNoise)) || (newPotVal1 > (potVal1+potNoise)) ) {
potVal1 = newPotVal1;
pot1Moved = true;
potsMoved = true;
}
else {
pot1Moved = false;
}
if ( (newPotVal2 < (potVal2-potNoise)) || (newPotVal2 > (potVal2+potNoise)) ) {
potVal2 = newPotVal2;
pot2Moved = true;
potsMoved = true;
}
else {
pot2Moved = false;
}
if (potsMoved) {
Serial.print("pot 1 ");
Serial.println(potVal1);
Serial.print("pot 2 ");
Serial.println(potVal2);
}
}
void changeOctave() {
// change from pot
int newOctave = map(analogRead(pot1),0,1023,-3,4);
baseNote = 36 + newOctave*12;
for (int i = 0; i<8; i++) {
if (newOctave+3 == i) {
// SoftPWMSet(seqLed[i],255);
digitalWrite(seqLed[i],HIGH);
}
else {
// SoftPWMSet(seqLed[i],0);
digitalWrite(seqLed[i],LOW);
}
}
}
void changeMode() {
// select mode with body switches
int highest = -1, highestVal = averageNoise;
for (int i=0; i<8; i++) {
if (bodySwitchVal[i] > highestVal) {
highest = i;
highestVal = bodySwitchVal[i];
}
}
if (highest != -1) {
mode = highest;
}
updateLEDs();
}
void changePreset() {
int newPreset = map(analogRead(pot2),0,1023,63,0);
if (preset != newPreset) { // only do something if preset has changed
// NB! user preset 0-16 might be empty, resulting in crazy sounds!
if (debug) Serial.print("new preset ");
if (debug) Serial.println(newPreset);
preset = newPreset;
Music.getPreset(preset);
}
}
void updateSequence() {
if (lastStep + stepTime < millis()) {
seqStep++;
if (seqStep > seqEnd) seqStep = seqStart;
int note = activeSeq*8+seqStep;
if (seqNote[note] != -1) {
Music.noteOn(baseNote+seqNote[note]);
}
lastStep = millis();
}
updateLEDs();
int blinkTime = max(stepTime/5,100);
if (lastStep + blinkTime < millis()) {
digitalWrite(seqLed[seqStep], HIGH);
}
if (lastStep + stepTime - blinkTime < millis()) {
digitalWrite(seqLed[seqStep], LOW);
}
}
void readBodyswitches() {
bodySwitchesTouched = false;
for (int i = 0; i<8; i++) {
int reading = constrain(analogRead (bodySwitch[i]),0,127);
maxBodyReading = max(maxBodyReading, reading);
if (reading > averageNoise) { // averageNoise is sampled on startup
int midiVal = map (reading, averageNoise, maxBodyReading, 0, 127);
bodySwitchVal[i] = constrain(midiVal,0,127);
bodySwitchesTouched = true;
}
else {
bodySwitchVal[i] = 0;
reading = 0;
}
seqLedVal[i] = reading*2;
}
maxBodyReading = maxBodyReading * maxBodyFadeout;
}
void printFeedback() {
for (int i = 0; i<8; i++) {
int reading = analogRead (bodySwitch[i]);
seqLedVal[i] = reading/4;
Serial.print(i);
Serial.print(": ");
Serial.print(reading);
Serial.print("\t");
}
Serial.println();
int potVal1 = analogRead(pot1);
int potVal2 = analogRead(pot2);
Serial.print(potVal1);
Serial.print("\t");
Serial.print(potVal2);
Serial.println();
}
void startupAnimation() {
digitalWrite(statusLed1, HIGH);
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],LOW);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],LOW);
delay(30);
}
digitalWrite(statusLed1, LOW);
delay(100);
}
void readButtons() {
// buttons are active low
for (int i = 0; i<3; i++) {
if (digitalRead(buttonPin[i]) == HIGH) {
if (buttonState[i] == LOW) {
// button has just been released
buttonAction[i] = true;
if (debug) Serial.print("button ");
if (debug) Serial.print(i);
if (debug) Serial.println(" has just been released");
} else {
// button was already released, no action here
buttonAction[i] = false;
}
buttonState[i] = HIGH;
}
if (digitalRead(buttonPin[i]) == LOW) {
if (buttonState[i] == HIGH) {
// button has just been pushed
buttonAction[i] = true;
if (debug) Serial.print("button ");
if (debug) Serial.print(i);
if (debug) Serial.println(" has just been pushed");
buttonState[i] = LOW;
} else {
// button was already psuhed, no action here
buttonAction[i] = false;
}
}
}
}

View File

@ -0,0 +1,524 @@
//______________________/\\\\\__________________________/\\\______________________________/\\\__________________________________________________________
// ____________________/\\\///__________________________\/\\\_____________________________\/\\\__________________________________________________________
// ___________________/\\\______________________________\/\\\_____________________________\/\\\_____/\\\__/\\\_______________________________/\\\\\\\\___
// _____/\\\\\\\\__/\\\\\\\\\_______/\\\\\______________\/\\\____________/\\\\\___________\/\\\____\//\\\/\\\___/\\\\\\\\\\_____/\\\\\\\\___/\\\////\\\__
// ___/\\\//////__\////\\\//______/\\\///\\\____________\/\\\\\\\\\____/\\\///\\\____/\\\\\\\\\_____\//\\\\\___\/\\\//////____/\\\/////\\\_\//\\\\\\\\\__
// __/\\\____________\/\\\_______/\\\__\//\\\___________\/\\\////\\\__/\\\__\//\\\__/\\\////\\\______\//\\\____\/\\\\\\\\\\__/\\\\\\\\\\\___\///////\\\__
// _\//\\\___________\/\\\______\//\\\__/\\\____________\/\\\__\/\\\_\//\\\__/\\\__\/\\\__\/\\\___/\\_/\\\_____\////////\\\_\//\\///////__________\/\\\__
// __\///\\\\\\\\____\/\\\_______\///\\\\\/_____________\/\\\\\\\\\___\///\\\\\/___\//\\\\\\\/\\_\//\\\\/_______/\\\\\\\\\\__\//\\\\\\\\\\________\/\\\\_
// ____\////////_____\///__________\/////_______________\/////////______\/////______\///////\//___\////________\//////////____\//////////_________\////__
// CFO BODYSEQ sequencer, 3 button version, reworked interaction, http://www.vsionhairies.info/
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
boolean playStep = false;
int ticksPerStep = 6;
const int seqLed [] = {3,4,5,6,7,8,9,10};
int seqLedVal [] = {0,0,0,0,0,0,0,0};
uint8_t ledValue = 0;
const int statusLed1 = 13;
const int buttonPin [] = {11,12,2};
const int pot1 = A0, pot2 = A1;
const int bodySwitch [] = {A2,A3,A4,A5,A6,A7,A8,A9};
unsigned long lastPrint = millis();
boolean sequencerRunning = true;
float maxBodyReading = 0;
float maxBodyFadeout = 0.9999;
float averageNoise = 0;
int inputFreq = 10;
unsigned long lastInput = millis();
int seqStep = 0;
long seqTick = -1;
int seqLength = 7;
int seqNote[] = {-1,-1,0,-1,12,-1,-1,-1,-1,-1,0,-1,24,-1,-1,-1,-1,-1,0,-1,36,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1,-1,-1,0,-1,12,-1,-1,-1,-1,-1,0,-1,24,-1,-1,-1,-1,-1,0,-1,36,-1,-1,-1,-1,-1,0,-1,0,-1,-1,-1};
int activeSeq = 0, seqStart = 0, seqEnd = 7;
unsigned long lastStep = millis();
int stepTime = 200;
int baseNote = 36;
const int scale[3][7] = {
{0,2,4,5,7,9,11}, // major
{0,2,3,5,6,7,10}, // blues
{0,3,4,7,9,10,-1} // rock
};
const int scaleLength = 24;
int activeScale [scaleLength];
int bodySwitchVal [] = {0,0,0,0,0,0,0,0};
boolean bodySwitchesTouched = false;
int mode = 0;
int preset = 16;
boolean buttonState [] = {HIGH, HIGH, HIGH};
boolean buttonAction [] = {false, false, false};
int potVal1 = 0, potVal2 = 0;
boolean pot1Moved = false, pot2Moved = false, potsMoved = false;
int potNoise = 1;
boolean debug = true;
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(16);
Music.setEnv1Decay(36);
Music.setEnv1Sustain(0);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Serial.begin(9600);
delay(100);
Serial.println("hello");
pinMode(buttonPin[0], INPUT_PULLUP);
pinMode(buttonPin[1], INPUT_PULLUP);
pinMode(buttonPin[2], INPUT_PULLUP);
newActiveScale(scaleLength);
pinMode(statusLed1,OUTPUT);
for (int i = 0; i<8; i++) {
pinMode(seqLed[i], OUTPUT);
}
Music.setResonance(255);
startupAnimation();
sampleAverageNoise();
}
void loop() {
// check for incoming USB MIDI messages
usbMIDI.read();
Midi.checkSerialMidi();
if (sequencerRunning) updateSequence();
// MIDI_SERIAL.write(byte(0xB0 | (MIDI_CHANNEL-1 & 0x0F)));
// MIDI_SERIAL.write(0x7F & CFO_LIGHT_LED);
// MIDI_SERIAL.write(0x7F & ledValue++);
//
// if(ledValue > 15) ledValue = 0;
if (lastInput + inputFreq < millis()) {
// check user input
readPots();
readBodyswitches();
readButtons();
// general navigation
// button 0 pushed
if (buttonState[0] == LOW) {
noteInputFromBodyswitches();
}
// button 1 pushed
if (buttonState[1] == LOW) {
eraseNotesFromBodyswitches();
if (pot1Moved) {
// change sequencer speed
stepTime = map(analogRead(pot1),0,1023,1000,0);
potsMoved = false;
}
}
// button 2 pushed
if (buttonState[2] == LOW) {
changeMode();
activeSeq = mode;
if (pot2Moved) {
changePreset();
potsMoved = false;
}
if (pot1Moved) {
changeOctave();
potsMoved = false;
}
}
// button 0 and 2 pushed
if (buttonState[2] == LOW && buttonState[0] == LOW) {
int lowestSwitch = 0, highestSwitch = 0;
if (bodySwitchesTouched) {
for (int i = 0; i<8; i++) {
if (bodySwitchVal[i] > 0) {
highestSwitch = i;
}
if (bodySwitchVal[7-i] > 0) {
lowestSwitch = 7-i;
}
}
seqStart = lowestSwitch;
seqEnd = highestSwitch;
}
}
lastInput = millis();
}
if (potsMoved) setCutoffFromPots();
}
void sampleAverageNoise() {
Serial.print("sampling average noise levels: ");
for (int i = 0; i<8; i++) {
pinMode(seqLed[i], OUTPUT);
averageNoise += analogRead(bodySwitch[i]);
}
averageNoise = averageNoise/8 + 3;
Serial.println(averageNoise);
}
void setCutoffFromPots() {
Music.setCutoff((analogRead(pot1))*64);
Music.setCutoffModAmount((analogRead(pot2))*64);
}
void updateLEDs() {
for (int i = 0; i<8; i++) {
if (seqNote[activeSeq*8+i] != -1) {
digitalWrite(seqLed[i], HIGH);
}
else {
digitalWrite(seqLed[i], LOW);
}
}
}
void newActiveScale (int length) {
Serial.println("lets make a new active scale");
int amountOfNotesInScale = 0;
for (int i = 0; i<7; i++) {
if (scale[1][i] != -1) amountOfNotesInScale++;
}
for (int i = 0; i<length+1; i++) {
int currentOctave = i/amountOfNotesInScale;
Serial.print("octave ");
Serial.print(currentOctave);
int currentNote = scale[1][i%amountOfNotesInScale];
Serial.print("\tnote ");
Serial.print(currentNote);
activeScale[i] = currentOctave*12+currentNote;
Serial.print("\tthis yields ");
Serial.println(activeScale[i]);
}
}
void eraseNotesFromBodyswitches() {
for (int i = 0; i<8; i++) {
if (bodySwitchVal[i] > 0) {
seqNote[activeSeq*8+i] = -1;
}
}
updateLEDs();
}
void noteInputFromBodyswitches() {
for (int i = 0; i<8; i++) {
if (bodySwitchVal[i] > 0) {
if (debug) Serial.print(i);
if (debug) Serial.print(": ");
if (debug) Serial.print(bodySwitchVal[i]);
int note = map(bodySwitchVal[i],0,127,0,scaleLength-1);
if (debug) Serial.print("\tnote: ");
if (debug) Serial.print(note);
seqNote[activeSeq*8+i] = activeScale[note];
if (debug) Serial.print("\tseqNote: ");
if (debug) Serial.println(seqNote[activeSeq*8+i]);
}
}
updateLEDs();
}
void readPots() {
int newPotVal1 = 1023-analogRead(pot1);
int newPotVal2 = 1023-analogRead(pot2);
potsMoved = false;
if ( (newPotVal1 < (potVal1-potNoise)) || (newPotVal1 > (potVal1+potNoise)) ) {
potVal1 = newPotVal1;
pot1Moved = true;
potsMoved = true;
}
else {
pot1Moved = false;
}
if ( (newPotVal2 < (potVal2-potNoise)) || (newPotVal2 > (potVal2+potNoise)) ) {
potVal2 = newPotVal2;
pot2Moved = true;
potsMoved = true;
}
else {
pot2Moved = false;
}
if (potsMoved) {
Serial.print("pot 1 ");
Serial.println(potVal1);
Serial.print("pot 2 ");
Serial.println(potVal2);
}
}
void changeOctave() {
// change from pot
int newOctave = map(analogRead(pot1),0,1023,-3,4);
baseNote = 36 + newOctave*12;
for (int i = 0; i<8; i++) {
if (newOctave+3 == i) {
// SoftPWMSet(seqLed[i],255);
digitalWrite(seqLed[i],HIGH);
}
else {
// SoftPWMSet(seqLed[i],0);
digitalWrite(seqLed[i],LOW);
}
}
}
void changeMode() {
// select mode with body switches
int highest = -1, highestVal = averageNoise;
for (int i=0; i<8; i++) {
if (bodySwitchVal[i] > highestVal) {
highest = i;
highestVal = bodySwitchVal[i];
}
}
if (highest != -1) {
mode = highest;
}
updateLEDs();
}
void changePreset() {
int newPreset = map(analogRead(pot2),0,1023,0,24);
if (preset != newPreset) { // only do something if preset has changed
// NB! user preset 0-16 might be empty, resulting in crazy sounds!
if (debug) Serial.print("new preset ");
if (debug) Serial.println(newPreset);
preset = newPreset;
Music.getPreset(preset);
}
}
void updateSequence() {
// if (lastStep + stepTime < millis()) {
//
// seqStep++;
// if (seqStep > seqEnd) seqStep = seqStart;
//
// int note = activeSeq*8+seqStep;
//
// if (seqNote[note] != -1) {
// Music.noteOn(baseNote+seqNote[note]);
// Midi.sendNoteOn(baseNote+seqNote[note], 127);
// }
// lastStep = millis();
//
// }
if(playStep) playNote();
updateLEDs();
// int blinkTime = max(stepTime/5,100);
//
// if (lastStep + blinkTime < millis()) {
// digitalWrite(seqLed[seqStep], HIGH);
// }
// if (lastStep + stepTime - blinkTime < millis()) {
// digitalWrite(seqLed[seqStep], LOW);
// }
}
void readBodyswitches() {
bodySwitchesTouched = false;
for (int i = 0; i<8; i++) {
int reading = constrain(analogRead (bodySwitch[i]),0,127);
maxBodyReading = max(maxBodyReading, reading);
if (reading > averageNoise) { // averageNoise is sampled on startup
int midiVal = map (reading, averageNoise, maxBodyReading, 0, 127);
bodySwitchVal[i] = constrain(midiVal,0,127);
bodySwitchesTouched = true;
}
else {
bodySwitchVal[i] = 0;
reading = 0;
}
seqLedVal[i] = reading*2;
}
maxBodyReading = maxBodyReading * maxBodyFadeout;
}
void printFeedback() {
for (int i = 0; i<8; i++) {
int reading = analogRead (bodySwitch[i]);
seqLedVal[i] = reading/4;
Serial.print(i);
Serial.print(": ");
Serial.print(reading);
Serial.print("\t");
}
Serial.println();
int potVal1 = analogRead(pot1);
int potVal2 = analogRead(pot2);
Serial.print(potVal1);
Serial.print("\t");
Serial.print(potVal2);
Serial.println();
}
void startupAnimation() {
digitalWrite(statusLed1, HIGH);
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],LOW);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],LOW);
delay(30);
}
digitalWrite(statusLed1, LOW);
delay(100);
}
void readButtons() {
// buttons are active low
for (int i = 0; i<3; i++) {
if (digitalRead(buttonPin[i]) == HIGH) {
if (buttonState[i] == LOW) {
// button has just been released
buttonAction[i] = true;
if (debug) Serial.print("button ");
if (debug) Serial.print(i);
if (debug) Serial.println(" has just been released");
} else {
// button was already released, no action here
buttonAction[i] = false;
}
buttonState[i] = HIGH;
}
if (digitalRead(buttonPin[i]) == LOW) {
if (buttonState[i] == HIGH) {
// button has just been pushed
buttonAction[i] = true;
if (debug) Serial.print("button ");
if (debug) Serial.print(i);
if (debug) Serial.println(" has just been pushed");
buttonState[i] = LOW;
} else {
// button was already psuhed, no action here
buttonAction[i] = false;
}
}
}
}
void RealTimeSystem(byte realtimebyte) {
if(realtimebyte == MIDI_CLOCK) {
seqTick++;
if(seqTick == ticksPerStep) {
seqTick = 0;
playStep = true;
}
}
if(realtimebyte == MIDI_START) {
seqTick = 0;
seqStep = 0;
playStep = true;
digitalWrite(13, HIGH);
}
if(realtimebyte == MIDI_CONTINUE) {
playStep = true;
digitalWrite(13, HIGH);
}
if(realtimebyte == MIDI_STOP) {
Music.noteOff();
digitalWrite(13, LOW);
}
}
void playNote() {
if (seqStep > seqEnd) seqStep = seqStart;
int note = activeSeq*8+seqStep;
if (seqNote[note] != -1) {
Music.noteOn(baseNote+seqNote[note]);
Midi.sendNoteOn(baseNote+seqNote[note], 127);
}
seqStep++;
playStep = false;
updateLEDs();
}

View File

@ -0,0 +1,539 @@
//______________________/\\\\\__________________________/\\\______________________________/\\\__________________________________________________________
// ____________________/\\\///__________________________\/\\\_____________________________\/\\\__________________________________________________________
// ___________________/\\\______________________________\/\\\_____________________________\/\\\_____/\\\__/\\\_______________________________/\\\\\\\\___
// _____/\\\\\\\\__/\\\\\\\\\_______/\\\\\______________\/\\\____________/\\\\\___________\/\\\____\//\\\/\\\___/\\\\\\\\\\_____/\\\\\\\\___/\\\////\\\__
// ___/\\\//////__\////\\\//______/\\\///\\\____________\/\\\\\\\\\____/\\\///\\\____/\\\\\\\\\_____\//\\\\\___\/\\\//////____/\\\/////\\\_\//\\\\\\\\\__
// __/\\\____________\/\\\_______/\\\__\//\\\___________\/\\\////\\\__/\\\__\//\\\__/\\\////\\\______\//\\\____\/\\\\\\\\\\__/\\\\\\\\\\\___\///////\\\__
// _\//\\\___________\/\\\______\//\\\__/\\\____________\/\\\__\/\\\_\//\\\__/\\\__\/\\\__\/\\\___/\\_/\\\_____\////////\\\_\//\\///////__________\/\\\__
// __\///\\\\\\\\____\/\\\_______\///\\\\\/_____________\/\\\\\\\\\___\///\\\\\/___\//\\\\\\\/\\_\//\\\\/_______/\\\\\\\\\\__\//\\\\\\\\\\________\/\\\\_
// ____\////////_____\///__________\/////_______________\/////////______\/////______\///////\//___\////________\//////////____\//////////_________\////__
// CFO BODYSEQ sequencer, 3 button version, reworked interaction, http://www.vsionhairies.info/
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include "CFO_BODYSEQ.h"
const int seqLed [] = {3, 4, 5, 6, 7, 8, 9, 10};
int seqLedVal [] = {0, 0, 0, 0, 0, 0, 0, 0};
int _bpm = 120;
int s1;
const int statusLed1 = 13;
const int buttonPin [] = {11, 12, 2};
const int pot1 = A0, pot2 = A1;
const int bodySwitch [] = {A2, A3, A4, A5, A6, A7, A8, A9};
unsigned long lastPrint = millis();
boolean sequenceRunning = true;
float maxBodyReading = 0;
float maxBodyFadeout = 0.9999;
float averageNoise = 0;
int inputFreq = 10;
unsigned long lastInput = millis();
int seqStep = 0;
int seqLength = 7;
int seqNote[] = { -1, -1, 0, -1, 12, -1, -1, -1, -1, -1, 0, -1, 24, -1, -1, -1, -1, -1, 0, -1, 36, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, 0, -1, 12, -1, -1, -1, -1, -1, 0, -1, 24, -1, -1, -1, -1, -1, 0, -1, 36, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1};
int activeSeq = 0, seqStart = 0, seqEnd = 7;
unsigned long lastStep = millis();
int stepTime = 200, blinkTime = 50;
int baseNote = 36;
const int scale[3][7] = {
{0, 2, 4, 5, 7, 9, 11}, // major
{0, 2, 3, 5, 6, 7, 10}, // blues
{0, 3, 4, 7, 9, 10, -1} // rock
};
const int scaleLength = 24;
int activeScale [scaleLength];
int bodySwitchVal [] = {0, 0, 0, 0, 0, 0, 0, 0};
boolean bodySwitchesTouched = false;
int mode = 0;
int bank = 0, preset = 16;
boolean buttonState [] = {HIGH, HIGH, HIGH};
boolean buttonAction [] = {false, false, false};
int potVal1 = 0, potVal2 = 0;
boolean pot1Moved = false, pot2Moved = false, potsMoved = false;
int potNoise = 1;
boolean debug = true;
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(13);
Music.setEnv1Decay(36);
Music.setEnv1Sustain(0);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
delay(1000);
Sequencer.init(120);
s1 = Sequencer.newSequence(NOTE_16, &sequenceCallback);
Sequencer.setInternalClock(true);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, true);
Sequencer.startSequence(s1);
checkBPM();
Serial.begin(9600);
Serial.println("hello");
pinMode(buttonPin[0], INPUT_PULLUP);
pinMode(buttonPin[1], INPUT_PULLUP);
pinMode(buttonPin[2], INPUT_PULLUP);
newActiveScale(scaleLength);
pinMode(statusLed1, OUTPUT);
for (int i = 0; i < 8; i++) {
pinMode(seqLed[i], OUTPUT);
}
startupAnimation();
sampleAverageNoise();
}
void loop() {
// check for incoming USB MIDI messages
usbMIDI.read();
Midi.checkSerialMidi();
// update sequencer
Sequencer.update();
// check user input
if (lastInput + inputFreq < millis()) {
// check user input
readPots();
readBodyswitches();
readButtons();
// general navigation
// button 0 pushed
if (buttonState[0] == LOW) {
noteInputFromBodyswitches();
}
// button 1 pushed
if (buttonState[1] == LOW) {
eraseNotesFromBodyswitches();
if (pot1Moved) {
// change sequencer speed
checkBPM();
potsMoved = false;
}
}
// button 2 pushed
if (buttonState[2] == LOW) {
changeSequenceBank();
activeSeq = bank;
if (pot2Moved) {
changePreset();
potsMoved = false;
}
if (pot1Moved) {
changeOctave();
potsMoved = false;
}
}
// button 0 and 2 pushed
if (buttonState[2] == LOW && buttonState[0] == LOW) {
int lowestSwitch = 0, highestSwitch = 0;
if (bodySwitchesTouched) {
for (int i = 0; i < 8; i++) {
if (bodySwitchVal[i] > 0) {
highestSwitch = i;
}
if (bodySwitchVal[7 - i] > 0) {
lowestSwitch = 7 - i;
}
}
seqStart = lowestSwitch;
seqEnd = highestSwitch;
}
}
lastInput = millis();
}
if (potsMoved) setCutoffFromPots();
updateLEDs();
}
void sampleAverageNoise() {
Serial.print("sampling average noise levels: ");
for (int i = 0; i < 8; i++) {
pinMode(seqLed[i], OUTPUT);
averageNoise += analogRead(bodySwitch[i]);
}
averageNoise = averageNoise / 8 + 3;
Serial.println(averageNoise);
}
void setCutoffFromPots() {
Music.setCutoff((analogRead(pot1)) * 64);
Music.setCutoffModAmount((analogRead(pot2)) * 64);
}
void updateLEDs() {
for (int i = 0; i < 8; i++) {
if (seqNote[activeSeq * 8 + i] != -1) {
// there is a note
digitalWrite(seqLed[i], HIGH);
}
else {
digitalWrite(seqLed[i], LOW);
}
}
// blink ON to show sequencer progression
if (lastStep + blinkTime < millis()) {
digitalWrite(seqLed[seqStep], HIGH);
}
// blink OFF to show sequencer progression
if (lastStep + stepTime - blinkTime/2 < millis()) {
digitalWrite(seqLed[seqStep], LOW);
}
}
void newActiveScale (int length) {
if (debug) Serial.println("lets make a new active scale");
int amountOfNotesInScale = 0;
for (int i = 0; i < 7; i++) {
if (scale[1][i] != -1) amountOfNotesInScale++;
}
for (int i = 0; i < length + 1; i++) {
int currentOctave = i / amountOfNotesInScale;
if (debug) Serial.print("octave ");
if (debug) Serial.print(currentOctave);
int currentNote = scale[1][i % amountOfNotesInScale];
if (debug) Serial.print("\tnote ");
if (debug) Serial.print(currentNote);
activeScale[i] = currentOctave * 12 + currentNote;
if (debug) Serial.print("\tthis yields ");
if (debug) Serial.println(activeScale[i]);
}
}
void eraseNotesFromBodyswitches() {
for (int i = 0; i < 8; i++) {
if (bodySwitchVal[i] > 0) {
seqNote[activeSeq * 8 + i] = -1;
}
}
//updateLEDs();
}
void noteInputFromBodyswitches() {
for (int i = 0; i < 8; i++) {
if (bodySwitchVal[i] > 0) {
if (debug) Serial.print(i);
if (debug) Serial.print(": ");
if (debug) Serial.print(bodySwitchVal[i]);
int note = map(bodySwitchVal[i], 0, 127, 0, scaleLength - 1);
if (debug) Serial.print("\tnote: ");
if (debug) Serial.print(note);
seqNote[activeSeq * 8 + i] = activeScale[note];
if (debug) Serial.print("\tseqNote: ");
if (debug) Serial.println(seqNote[activeSeq * 8 + i]);
}
}
//updateLEDs();
}
void readPots() {
int newPotVal1 = 1023 - analogRead(pot1);
int newPotVal2 = 1023 - analogRead(pot2);
potsMoved = false;
if ( (newPotVal1 < (potVal1 - potNoise)) || (newPotVal1 > (potVal1 + potNoise)) ) {
potVal1 = newPotVal1;
pot1Moved = true;
potsMoved = true;
}
else {
pot1Moved = false;
}
if ( (newPotVal2 < (potVal2 - potNoise)) || (newPotVal2 > (potVal2 + potNoise)) ) {
potVal2 = newPotVal2;
pot2Moved = true;
potsMoved = true;
}
else {
pot2Moved = false;
}
/*
if (potsMoved) {
if (debug) Serial.print("pot 1 ");
if (debug) Serial.println(potVal1);
if (debug) Serial.print("pot 2 ");
if (debug) Serial.println(potVal2);
}
*/
}
void changeOctave() {
// change from pot
int newOctave = map(analogRead(pot1), 0, 1023, -3, 4);
baseNote = 36 + newOctave * 12;
// display on LEDs which octave is active
for (int i = 0; i < 8; i++) {
if (newOctave + 3 == i) {
digitalWrite(seqLed[i], HIGH);
}
else {
digitalWrite(seqLed[i], LOW);
}
}
}
void changeSequenceBank() {
// select bank with body switches
int highest = -1, highestVal = averageNoise;
for (int i = 0; i < 8; i++) {
if (bodySwitchVal[i] > highestVal) {
highest = i;
highestVal = bodySwitchVal[i];
}
}
if (highest != -1) {
bank = highest;
if (debug) Serial.print("playing sequence bank: ");
if (debug) Serial.println(bank);
}
//updateLEDs();
}
void changePreset() {
int newPreset = map(analogRead(pot2), 0, 1023, 0, 31);
if (preset != newPreset) { // only do something if preset has changed
// NB! user preset 0-16 might be empty, resulting in crazy sounds!
if (debug) Serial.print("new preset ");
if (debug) Serial.println(newPreset);
preset = newPreset;
Music.getPreset(preset);
}
}
void sequenceCallback() {
// this is a callback function, called every time the sequencer steps
// calculate how many millis have passed since last step
unsigned long thisStep = millis();
stepTime = thisStep - lastStep;
lastStep = thisStep;
// and calculate sequencer blink time
blinkTime = max(stepTime >> 2, 100);
// updater sequencer notes
seqStep++;
if (seqStep > seqEnd) seqStep = seqStart;
int note = activeSeq * 8 + seqStep;
if (seqNote[note] != -1) {
Music.noteOn(baseNote + seqNote[note]);
}
//updateLEDs();
}
void updateSequence() {
if (lastStep + stepTime < millis()) {
seqStep++;
if (seqStep > seqEnd) seqStep = seqStart;
int note = activeSeq * 8 + seqStep;
if (seqNote[note] != -1) {
Music.noteOn(baseNote + seqNote[note]);
}
lastStep = millis();
}
//updateLEDs();
}
void readBodyswitches() {
bodySwitchesTouched = false;
for (int i = 0; i < 8; i++) {
int reading = constrain(analogRead (bodySwitch[i]), 0, 127);
maxBodyReading = max(maxBodyReading, reading);
if (reading > averageNoise) { // averageNoise is sampled on startup
int midiVal = map (reading, averageNoise, maxBodyReading, 0, 127);
bodySwitchVal[i] = constrain(midiVal, 0, 127);
bodySwitchesTouched = true;
}
else {
bodySwitchVal[i] = 0;
reading = 0;
}
seqLedVal[i] = reading * 2;
}
maxBodyReading = maxBodyReading * maxBodyFadeout;
}
void printFeedback() {
for (int i = 0; i < 8; i++) {
int reading = analogRead (bodySwitch[i]);
seqLedVal[i] = reading / 4;
Serial.print(i);
Serial.print(": ");
Serial.print(reading);
Serial.print("\t");
}
Serial.println();
int potVal1 = analogRead(pot1);
int potVal2 = analogRead(pot2);
Serial.print(potVal1);
Serial.print("\t");
Serial.print(potVal2);
Serial.println();
}
void startupAnimation() {
digitalWrite(statusLed1, HIGH);
for (int i = 0; i < 8; i++) {
digitalWrite(seqLed[i], HIGH);
delay(30);
}
for (int i = 0; i < 8; i++) {
digitalWrite(seqLed[i], LOW);
delay(30);
}
for (int i = 0; i < 8; i++) {
digitalWrite(seqLed[7 - i], HIGH);
delay(30);
}
for (int i = 0; i < 8; i++) {
digitalWrite(seqLed[7 - i], LOW);
delay(30);
}
digitalWrite(statusLed1, LOW);
delay(100);
}
void readButtons() {
// buttons are active low
for (int i = 0; i < 3; i++) {
if (digitalRead(buttonPin[i]) == HIGH) {
if (buttonState[i] == LOW) {
// button has just been released
buttonAction[i] = true;
if (debug) Serial.print("button ");
if (debug) Serial.print(i);
if (debug) Serial.println(" has just been released");
} else {
// button was already released, no action here
buttonAction[i] = false;
}
buttonState[i] = HIGH;
}
if (digitalRead(buttonPin[i]) == LOW) {
if (buttonState[i] == HIGH) {
// button has just been pushed
buttonAction[i] = true;
if (debug) Serial.print("button ");
if (debug) Serial.print(i);
if (debug) Serial.println(" has just been pushed");
buttonState[i] = LOW;
} else {
// button was already psuhed, no action here
buttonAction[i] = false;
}
}
}
}
//////////
// POTS //
//////////
void checkBPM() {
// >> is C for bitwise shift right.
if (debug) Serial.println("checkBPM");
int bpm = analogRead(A0) >> 2; // fast way of roughly dividing by 4
if (bpm != _bpm) {
_bpm = bpm;
if (debug) Serial.print("BPM set to ");
if (debug) Serial.println(_bpm);
Sequencer.setbpm(_bpm);
if (_bpm == 0) {
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(false);
} else {
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(true);
// Sequencer.sequencerContinue();
}
}
}

View File

@ -0,0 +1,81 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include "CFO_BODYSEQ.h"
// sequence ID
int s1, s2;
int _bpm = 120;
// sequence step index
int indx1 = 0;
int indx2 = 0;
const int nbr_notes1 = 8; // try with 16 :)
const int nbr_steps2 = 8;
int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
//int notes1[] = {36, 48, 31, 36, 60, 36, 48, 39, 24, 36, 72, 60, 43, 48, 27, 60};
int notes2[] = {0, 2, 3, 5, 6, 8, 10, 12};
int vels[] = {100, 72, 96, 64, 112, 88, 78, 96};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(13);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
Sequencer.init(_bpm);
s1 = Sequencer.newSequence(NOTE_16, 16, LOOP);
Sequencer.startSequence(s1);
Sequencer.insertNotes(s1, notes1, 16, 0);
Sequencer.insertNotes(s1, vels, 7, 8);
Sequencer.insertNotes(s1, vels, 3, 2);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, true );
}
void loop() {
// Checking for incoming MIDI to use dashboard
Sequencer.update();
usbMIDI.read();
Midi.checkSerialMidi();
checkBPM();
}
void checkBPM() {
// int bpm = analogRead(A0)>>2;
int bpm = 124;
if(bpm != _bpm) {
_bpm = bpm;
Serial.println(_bpm);
Sequencer.setbpm(_bpm);
if(_bpm == 0) {
Midi.setMidiIn(false);
Midi.setMidiThru(true);
Midi.setMidiOut(false);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(false);
} else {
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(true);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(true);
// Sequencer.sequencerContinue();
}
}
}

View File

@ -0,0 +1,234 @@
//______________________/\\\\\__________________________/\\\______________________________/\\\__________________________________________________________
// ____________________/\\\///__________________________\/\\\_____________________________\/\\\__________________________________________________________
// ___________________/\\\______________________________\/\\\_____________________________\/\\\_____/\\\__/\\\_______________________________/\\\\\\\\___
// _____/\\\\\\\\__/\\\\\\\\\_______/\\\\\______________\/\\\____________/\\\\\___________\/\\\____\//\\\/\\\___/\\\\\\\\\\_____/\\\\\\\\___/\\\////\\\__
// ___/\\\//////__\////\\\//______/\\\///\\\____________\/\\\\\\\\\____/\\\///\\\____/\\\\\\\\\_____\//\\\\\___\/\\\//////____/\\\/////\\\_\//\\\\\\\\\__
// __/\\\____________\/\\\_______/\\\__\//\\\___________\/\\\////\\\__/\\\__\//\\\__/\\\////\\\______\//\\\____\/\\\\\\\\\\__/\\\\\\\\\\\___\///////\\\__
// _\//\\\___________\/\\\______\//\\\__/\\\____________\/\\\__\/\\\_\//\\\__/\\\__\/\\\__\/\\\___/\\_/\\\_____\////////\\\_\//\\///////__________\/\\\__
// __\///\\\\\\\\____\/\\\_______\///\\\\\/_____________\/\\\\\\\\\___\///\\\\\/___\//\\\\\\\/\\_\//\\\\/_______/\\\\\\\\\\__\//\\\\\\\\\\________\/\\\\_
// ____\////////_____\///__________\/////_______________\/////////______\/////______\///////\//___\////________\//////////____\//////////_________\////__
// CFO BODYSEQ sequencer, 3 button version, reworked interaction, http://www.vsionhairies.info/
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
#define NUM_TRACKS 8
#define NUM_STEPS 8
#define NUM_LEDS 8
int mode;
int track[8];
int debounceTime = 40;
int _bpm;
const int scale[] = {0, 2, 3, 5, 7, 8, 10, 12};
//const int octave[] = {-24, -12, 0, 12, 24};
int rootNote = 36;
int trackPlaying = 0 ;
int trackSelected = 0;
int stepSelected = 0;
int noteSelected = 0;
int oct = 0;
int notes[64];
int octave[64];
int noteValues[8];
int leds;
int note;
//int var = 0;
//const int pot1 = A0, pot2 = A1;
// old stuff
const int seqLed[] = {3,4,5,6,7,8,9,10};
const int statusLed1 = 13;
//boolean debug = true;
/////////////
// BUTTONS //
/////////////
#define NUM_BUTTONS 8
const int buttonPin [] = {11,12,2};
int buttonIndex = 0;
int buttonRead = 0;
int buttonChange = 0;
int buttonState[] = {0, 0, 0};
unsigned long buttonNow = 0;
unsigned long buttonTime[] = {0, 0, 0};
int machineState = 0;
//////////
// KEYS //
//////////
#define NUM_KEYS 8
#define KEY_THRESHOLD 15
const int keyPin[] = {A2,A3,A4,A5,A6,A7,A8,A9};
int keyIndex = 0;
int keyRead = 0;
int keyValue = 0;
int keyChange = 0;
int keyState[] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned long keyNow = 0;
unsigned long keyTime[] = {0, 0, 0, 0, 0, 0, 0, 0};
int keys;
void setup() {
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(21);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
delay(2000);
Sequencer.init(120);
setupSequences();
initInterface();
}
void loop() {
Sequencer.update();
usbMIDI.read();
Midi.checkSerialMidi();
readButtons();
readKeys();
checkBPM();
Music.setCutoffModAmount((analogRead(A1))*64);
// if(buttonChange || keyChange) {
switch(machineState) {
case 0:
playTrack();
break;
case 1:
selectNote();
break;
case 2:
selectStep();
break;
case 3: // nothing
break;
case 4:
selectTrack();
break;
case 5: // nothing
break;
case 6: // nothing
break;
case 7: // nothing
break;
default:
break;
}
updateLEDs();
// buttonChange = 0;
// }
}
void playTrack() {
if(keyChange) {
Serial.println("PLAY TRACK");
// code here
keyChange = 0;
}
}
void selectNote() {
noteSelected = notes[stepSelected + 8 * trackSelected];
oct = octave[stepSelected + 8 * trackSelected];
if(keyChange) {
for(int i = 0; i < NUM_KEYS-1; i++) {
if(keys & (1 << i)) noteSelected = i;
notes[stepSelected + 8 * trackSelected] = noteSelected;
}
if(keys & (1 << 7)) {
oct ^= 1;
octave[stepSelected + 8 * trackSelected] = oct;
}
for(int i = 0; i < NUM_STEPS; i++) {
noteValues[i] = rootNote + scale[notes[8 * trackSelected + i]] + octave[i + 8 * trackSelected] * 12;
Sequencer.insertNotes(track[trackSelected], noteValues, 8, 0);
}
keyChange = 0;
}
}
void selectStep() {
if(keyChange) {
Serial.println("SELECT STEP");
for(int i = 0; i < NUM_KEYS; i++) {
// code here
if(keys & (1 << i)) {
stepSelected = i;
Serial.print("Step selected: ");
Serial.println(stepSelected);
}
}
keyChange = 0;
}
}
void selectTrack() {
// if(keys > 0) {
if(keyChange) {
Serial.println("SELECT TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
// Serial.print("Rechecking sequence on position ");
// Serial.print(i);
// Serial.print(". It is set to sequence index ");
// Serial.println(track[i]);
Sequencer.setInternal(track[i], false);
if(keys & (1 << i)) {
trackSelected = i;
Serial.print("trackSelected shows ");
Serial.print(trackSelected);
Serial.print(" - Track selected: ");
Serial.println(track[trackSelected]);
}
Sequencer.setInternal(track[trackSelected], true);
}
keyChange = 0;
}
// code here
}
void setupSequences() {
for(int i = 0; i < NUM_TRACKS; i++) {
for(int j = 0; j < NUM_STEPS; j++) {
notes[8*i + j] = j;
}
track[i] = Sequencer.newSequence(NOTE_16, 8, LOOP);
Serial.print("Track created for sequence ");
Serial.print(track[i]);
Serial.print(" on position ");
Serial.println(i);
Sequencer.startSequence(track[i]);
for(int j = 0; j < NUM_STEPS; j++) {
noteValues[j] = rootNote + scale[notes[8 * i + j]] + octave[8 * i + j] * 12;
}
Sequencer.insertNotes(track[i], noteValues, 8, 0);
Sequencer.setInternal(track[i], true);
Sequencer.setExternal(track[i], false);
Serial.print("Internal set to ");
Serial.println(Sequencer.getInternal(track[i]));
}
for(int i = 0; i < NUM_TRACKS; i++) {
Serial.print("Rechecking sequence on position ");
Serial.print(i);
Serial.print(" - set to sequence index ");
Serial.println(track[i]);
}
}

View File

@ -0,0 +1,157 @@
/////////////
// BUTTONS //
/////////////
void readButtons() {
// buttons are active low
for(int i = 0; i < NUM_BUTTONS; i++) {
// int i = buttonIndex++;
// if(buttonIndex >= NUM_BUTTONS) buttonIndex = 0;
buttonNow = millis();
if((buttonNow - buttonTime[i]) > debounceTime) {
buttonRead = digitalRead(buttonPin[i]);
if(buttonRead != buttonState[i]) {
buttonState[i] = buttonRead;
buttonChange |= 1<<i;
buttonTime[i] = buttonNow;
machineState = 7 - buttonState[0] - buttonState[1] * 2 - buttonState[2] * 4;
}
}
}
}
//////////
// KEYS //
//////////
void readKeys() {
for (int i = 0; i < NUM_KEYS; i++) {
// int i = keyIndex++;
// if(keyIndex >= NUM_KEYS) keyIndex = 0;
keyNow = millis();
if((keyNow - keyTime[i]) > debounceTime) {
keyRead = analogRead(keyPin[i]);
// if(i==4) Serial.println(keyRead);
if(keyRead > KEY_THRESHOLD) {
keyValue = 1;
} else {
keyValue = 0;
}
// keyValue = (keyRead > KEY_THRESHOLD) ? 1 : 0 ;
if(keyValue != keyState[i]) {
keyState[i] = keyValue;
keyChange |= 1<<i;
keyTime[i] = keyNow;
}
if(keyState[i]) {
keys |= 1<<i;
} else {
keys &= ~(1<<i);
}
}
}
}
//////////
// POTS //
//////////
void checkBPM() {
int bpm = analogRead(A0)>>2;
if(bpm != _bpm) {
_bpm = bpm;
Serial.print("BPM set to ");
Serial.println(_bpm);
Sequencer.setbpm(_bpm);
if(_bpm == 0) {
Midi.setMidiIn(true);
Midi.setMidiThru(true);
Midi.setMidiOut(true);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(false);
} else {
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(true);
// Sequencer.sequencerContinue();
}
}
}
void initInterface() {
pinMode(buttonPin[0], INPUT_PULLUP);
pinMode(buttonPin[1], INPUT_PULLUP);
pinMode(buttonPin[2], INPUT_PULLUP);
pinMode(statusLed1,OUTPUT);
for (int i = 0; i<8; i++) {
pinMode(seqLed[i], OUTPUT);
}
startupAnimation();
}
void updateLEDs() {
switch(machineState) {
case 0:
leds = 0 | (1 << trackSelected);
break;
case 1:
leds = 0 | (1 << noteSelected);
leds = leds | (octave[stepSelected + 8 * trackSelected] << 7);
break;
case 2:
leds = 0 | (1 << stepSelected);
break;
case 3: // nothing
break;
case 4:
leds = 0 | (1 << trackSelected);
break;
case 5: // nothing
break;
case 6: // nothing
break;
case 7: // nothing
break;
default:
break;
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i], leds & (1 << i));
}
}
void startupAnimation() {
digitalWrite(statusLed1, HIGH);
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],LOW);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],LOW);
delay(30);
}
digitalWrite(statusLed1, LOW);
delay(100);
}

View File

@ -0,0 +1,110 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
// sequence ID
int s1, s2;
int _bpm, _eend, _beegin;
// sequence step index
int indx1 = 0;
int indx2 = 0;
const int nbr_notes1 = 8; // try with 16 :)
const int nbr_steps2 = 8;
//int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
int notes1[] = {36, 48, 31, 36, 60, 36, 48, 39, 24, 36, 72, 60, 43, 48, 27, 60};
int notes2[] = {0, 2, 3, 5, 6, 8, 10, 12};
int vels[] = {100, 72, 96, 64, 112, 88, 78, 96};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(13);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Sequencer.init(120);
// s1 = Sequencer.newSequence(NOTE_16, 16, LOOP, !REVERSE); // overloaded function
s1 = Sequencer.newSequence(NOTE_16, 16, LOOP);
Sequencer.startSequence(s1);
Sequencer.insertNotes(s1, notes1, 16, 0);
// Sequencer.insertNotes(s1, vels, 7, 8);
// Sequencer.insertNotes(s1, vels, 3, 2);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, false);
Midi.setMidiIn(true);
Midi.setMidiThru(true);
Midi.setMidiOut(true);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(false);
}
void loop() {
// Checking for incoming MIDI to use dashboard
Sequencer.update();
usbMIDI.read();
Midi.checkSerialMidi();
// checkBPM();
// checkBeegin();
// checkEend();
}
void checkBPM() {
int bpm = analogRead(A0)>>2;
if(bpm != _bpm) {
_bpm = bpm;
Serial.println(_bpm);
Sequencer.setbpm(_bpm);
if(_bpm == 0) {
Midi.setMidiIn(true);
Midi.setMidiThru(true);
Midi.setMidiOut(true);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(false);
} else {
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(true);
// Sequencer.sequencerContinue();
}
}
}
void checkBeegin() {
int beegin = analogRead(A0)>>6;
if(beegin != _beegin) {
_beegin = beegin;
Sequencer.setBegin(s1, _beegin);
}
}
void checkEend() {
int eend = analogRead(A1)>>6;
if(eend != _eend) {
_eend = eend;
Sequencer.setEnd(s1, _eend);
}
}

View File

@ -0,0 +1,103 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
// sequence ID
int s1, s2;
int _bpm, _eend, _beegin;
// sequence step index
int indx1 = 0;
int indx2 = 0;
const int nbr_notes1 = 8; // try with 16 :)
const int nbr_steps2 = 8;
//int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
int notes1[] = {36, 48, 31, 36, 60, 36, 48, 39, 24, 36, 72, 60, 43, 48, 27, 60};
int notes2[] = {0, 2, 3, 5, 6, 8, 10, 12};
int vels[] = {100, 72, 96, 64, 112, 88, 78, 96};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(21);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Sequencer.init(120);
// s1 = Sequencer.newSequence(NOTE_16, 16, LOOP, !REVERSE); // overloaded function
s1 = Sequencer.newSequence(NOTE_16, 16, LOOP);
Sequencer.startSequence(s1);
Sequencer.insertNotes(s1, notes1, 16, 0);
Sequencer.insertNotes(s1, vels, 7, 8);
Sequencer.insertNotes(s1, vels, 3, 2);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, false);
}
void loop() {
// Checking for incoming MIDI to use dashboard
Sequencer.update();
usbMIDI.read();
Midi.checkSerialMidi();
checkBPM();
// checkBeegin();
checkEend();
}
void checkBPM() {
int bpm = analogRead(A0)>>2;
if(bpm != _bpm) {
_bpm = bpm;
Serial.println(_bpm);
Sequencer.setbpm(_bpm);
if(_bpm == 0) {
Midi.setMidiIn(true);
Midi.setMidiThru(true);
Midi.setMidiOut(true);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(false);
} else {
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(true);
// Sequencer.sequencerContinue();
}
}
}
void checkBeegin() {
int beegin = analogRead(A0)>>6;
if(beegin != _beegin) {
_beegin = beegin;
Sequencer.setBegin(s1, _beegin);
}
}
void checkEend() {
int eend = analogRead(A1)>>6;
if(eend != _eend) {
_eend = eend;
Sequencer.setEnd(s1, _eend);
}
}

View File

@ -0,0 +1,286 @@
//______________________/\\\\\__________________________/\\\______________________________/\\\__________________________________________________________
// ____________________/\\\///__________________________\/\\\_____________________________\/\\\__________________________________________________________
// ___________________/\\\______________________________\/\\\_____________________________\/\\\_____/\\\__/\\\_______________________________/\\\\\\\\___
// _____/\\\\\\\\__/\\\\\\\\\_______/\\\\\______________\/\\\____________/\\\\\___________\/\\\____\//\\\/\\\___/\\\\\\\\\\_____/\\\\\\\\___/\\\////\\\__
// ___/\\\//////__\////\\\//______/\\\///\\\____________\/\\\\\\\\\____/\\\///\\\____/\\\\\\\\\_____\//\\\\\___\/\\\//////____/\\\/////\\\_\//\\\\\\\\\__
// __/\\\____________\/\\\_______/\\\__\//\\\___________\/\\\////\\\__/\\\__\//\\\__/\\\////\\\______\//\\\____\/\\\\\\\\\\__/\\\\\\\\\\\___\///////\\\__
// _\//\\\___________\/\\\______\//\\\__/\\\____________\/\\\__\/\\\_\//\\\__/\\\__\/\\\__\/\\\___/\\_/\\\_____\////////\\\_\//\\///////__________\/\\\__
// __\///\\\\\\\\____\/\\\_______\///\\\\\/_____________\/\\\\\\\\\___\///\\\\\/___\//\\\\\\\/\\_\//\\\\/_______/\\\\\\\\\\__\//\\\\\\\\\\________\/\\\\_
// ____\////////_____\///__________\/////_______________\/////////______\/////______\///////\//___\////________\//////////____\//////////_________\////__
// CFO BODYSEQ sequencer, 3 button version, reworked interaction, http://www.vsionhairies.info/
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
#define NUM_TRACKS 8
#define NUM_STEPS 8
#define NUM_SAMPLES 8
#define NUM_LEDS 8
int mode;
unsigned long debounceTime = 100;
unsigned long debounceTimeDefault = 100;
unsigned long debounceTimeLong = 500;
int _bpm;
int trackPlaying = 0 ;
int trackSelected = 0;
int sampleSelected = 0;
int stepSelected = 0;
int trackChained = -1;
int s1;
int indx = 0;
int indxLED;
uint8_t sample[NUM_TRACKS][NUM_SAMPLES][NUM_STEPS];
int leds;
int chainedLedState = 0;
unsigned long ledNow;
unsigned long ledTime = 0;
unsigned long ledPulse = 100;
bool inStartupMode = true;
// old stuff
const int seqLed[] = {3,4,5,6,7,8,9,10};
const int statusLed1 = 13;
//boolean debug = true;
/////////////
// BUTTONS //
/////////////
#define NUM_BUTTONS 3
const int buttonPin [] = {11,12,2};
int buttonIndex = 0;
int buttonRead = 0;
int buttonChange = 0;
int buttonState[] = {0, 0, 0};
unsigned long buttonNow = 0;
unsigned long buttonTime[] = {0, 0, 0};
int machineState = 0;
//////////
// KEYS //
//////////
#define NUM_KEYS 8
#define KEY_THRESHOLD 15
const int keyPin[] = {A2,A3,A4,A5,A6,A7,A8,A9};
int keyIndex = 0;
int keyRead = 0;
int keyValue = 0;
int keyChange = 0;
int keyState[] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned long keyNow = 0;
unsigned long keyTime[] = {0, 0, 0, 0, 0, 0, 0, 0};
int keys;
void setup() {
Music.init();
Music.setSampler(true);
Music.setSynth(false);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Sequencer.init(120);
// Sequencer.setInternalClock(true);
s1 = Sequencer.newSequence(NOTE_16, &s1cb);
// resetMemory();
loadSequences();
initInterface();
Sequencer.startSequence(s1);
}
void loop() {
Sequencer.update();
usbMIDI.read();
Midi.checkSerialMidi();
readButtons();
readKeys();
checkBPM();
checkBitcrush();
switch(machineState) {
case 0:
playTrack();
break;
case 1:
selectStep();
break;
case 2:
selectSample();
break;
case 3:
selectTrack();
break;
case 4:
selectTrack();
break;
case 5: // nothing
chainTrack();
break;
case 6:
copyTrack();
break;
case 7:
clearTrack();
break;
default:
break;
}
updateLEDs();
}
void playTrack() {
if(keyChange && keys) {
Serial.println("PLAY TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
if(trackPlaying == i) trackChained = -1;
if(trackChained < 0) trackPlaying = i;
else trackChained = i;
}
}
keyChange = 0;
}
}
void selectStep() {
if(keyChange) {
Serial.println("SELECT STEP");
for(int k = 0; k < NUM_KEYS; k++) {
if(keys & (1 << k)) {
stepSelected = k;
int j = sampleSelected;
int i = trackSelected;
sample[i][j][k] ^= 1;
EEPROM.write(k + NUM_SAMPLES * (j + i * NUM_TRACKS), sample[i][j][k]);
}
}
keyChange = 0;
}
}
void selectSample() {
if(keyChange) {
Serial.println("SELECT SAMPLE");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
sampleSelected = i;
}
}
keyChange = 0;
}
}
void selectTrack() {
if(keyChange) {
Serial.println("SELECT TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
trackSelected = i;
}
}
keyChange = 0;
}
}
void chainTrack() {
if(keyChange) {
Serial.println("SELECT TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
if(i == trackChained) trackChained = -1;
else trackChained = i;
}
}
keyChange = 0;
}
}
void copyTrack() {
if(keyChange) {
debounceTime = debounceTimeLong;
Serial.println("COPY TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
sample[i][j][k] = sample[trackSelected][j][k];
EEPROM.write(k + NUM_SAMPLES * (j + i * NUM_TRACKS), sample[i][j][k]);
}
}
}
}
keyChange = 0;
debounceTime = debounceTimeDefault;
}
}
void clearTrack() {
if(keyChange) {
Serial.println("CLEAR TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
sample[i][j][k] = 0;
EEPROM.write(k + NUM_SAMPLES * (j + i * NUM_TRACKS), 0);
}
}
}
}
keyChange = 0;
}
}
void resetMemory() {
for(int i=0; i<NUM_TRACKS; i++) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
EEPROM.write(k + NUM_SAMPLES * (j + i * NUM_TRACKS), 0);
}
}
}
}
void loadSequences() {
for(int i=0; i<NUM_TRACKS; i++) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
sample[i][j][k] = EEPROM.read(k + NUM_SAMPLES * (j + i * NUM_TRACKS));
}
}
}
}
void s1cb() {
indxLED = indx;
for(int i=0; i<NUM_SAMPLES; i++) {
if(sample[trackPlaying][i][indx]) Music.noteOnSample(i);
}
indx++;
if(indx >= NUM_STEPS) {
indx = 0;
if(trackChained < 0);
else {
int t = trackPlaying;
trackPlaying = trackChained;
trackChained = t;
}
}
}

View File

@ -0,0 +1,201 @@
/////////////
// BUTTONS //
/////////////
void readButtons() {
// buttons are active low
for(int i = 0; i < NUM_BUTTONS; i++) {
// int i = buttonIndex++;
// if(buttonIndex >= NUM_BUTTONS) buttonIndex = 0;
buttonNow = millis();
if((buttonNow - buttonTime[i]) > debounceTime) {
buttonRead = digitalRead(buttonPin[i]);
if(buttonRead != buttonState[i]) {
buttonState[i] = buttonRead;
buttonChange |= 1<<i;
buttonTime[i] = buttonNow;
machineState = 7 - buttonState[0] - buttonState[1] * 2 - buttonState[2] * 4;
}
}
}
}
//////////
// KEYS //
//////////
void readKeys() {
int keyr = 0;
int keyv = 0;
for (int i = 0; i < NUM_KEYS; i++) {
keyNow = millis();
if((keyNow - keyTime[i]) > debounceTime) {
keyRead = analogRead(keyPin[i]);
if(keyRead > KEY_THRESHOLD) {
keyValue = 1;
} else {
keyValue = 0;
}
if(i == 0) {
keyr = keyRead;
keyv = keyValue;
}
// keyValue = (keyRead > KEY_THRESHOLD) ? 1 : 0 ;
if(keyState[i] != keyValue) {
keyState[i] = keyValue;
keyChange |= 1<<i;
keyTime[i] = keyNow;
}
}
}
for (int i = 0; i < NUM_KEYS; i++) {
if(keyState[i] == 1) {
keys |= (1<<i);
} else if(keyState[i] == 0) {
keys &= ~(1<<i);
}
}
// Serial.printf("keyTime[0]=%10ld, keyr=%i, keyv=%i - keyState is %i%i%i%i%i%i%i%i, keys is %X \n", keyTime[0], keyr, keyv, keyState[0], keyState[1], keyState[2], keyState[3], keyState[4], keyState[5], keyState[6], keyState[7], keys);
}
//////////
// POTS //
//////////
void checkBPM() {
int bpm = analogRead(A0)>>2;
if(bpm != _bpm) {
_bpm = bpm;
Serial.print("BPM set to ");
Serial.println(_bpm);
Sequencer.setbpm(_bpm);
if(_bpm == 0) {
Midi.setMidiIn(true);
Midi.setMidiThru(true);
Midi.setMidiOut(true);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(false);
} else {
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(true);
// Sequencer.sequencerContinue();
}
}
}
void checkBitcrush() {
int bc = (1024 - analogRead(A1)) >> 7;
Music.setBitcrush(bc);
}
void initInterface() {
pinMode(buttonPin[0], INPUT_PULLUP);
pinMode(buttonPin[1], INPUT_PULLUP);
pinMode(buttonPin[2], INPUT_PULLUP);
pinMode(statusLed1,OUTPUT);
for (int i = 0; i<8; i++) {
pinMode(seqLed[i], OUTPUT);
}
startupAnimation();
}
void updateLEDs() {
ledNow = millis();
int t = trackSelected;
int s = sampleSelected;
leds = 0;
switch(machineState) {
case 0: // PLAY TRACK
leds |= (1 << trackPlaying);
if(trackChained >= 0) {
if((ledNow - ledTime) > ledPulse) {
chainedLedState ^= 1;
ledTime = ledNow;
}
leds |= (chainedLedState << trackChained);
}
break;
case 1: // SELECT STEP
// leds = 0;
for(int i=0; i<NUM_STEPS; i++) {
leds |= (sample[t][s][i] << i);
}
break;
case 2: // SELECT SAMPLE
leds |= (1 << sampleSelected);
break;
case 3: // SELECT TRACK
leds |= (1 << trackSelected);
break;
case 4: // SELECT TRACK
leds |= (1 << trackSelected);
break;
case 5: // CHAIN TRACKS PLAYING
leds |= (1 << trackPlaying);
if(trackChained >= 0) {
if((ledNow - ledTime) > ledPulse) {
chainedLedState ^= 1;
ledTime = ledNow;
}
leds |= (chainedLedState << trackChained);
}
break;
case 6: // COPY TRACK
leds |= (1 << trackSelected);
break;
case 7: // CLEAR TRACK
for(int i=0; i<NUM_KEYS; i++) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
leds |= (sample[i][j][k] << i);
}
}
}
break;
default:
break;
}
for (int i = 0; i<8; i++) {
leds |= (1 << indxLED);
digitalWrite(seqLed[i], leds & (1 << i));
// leds ^= (1 << indxLED);
}
}
void startupAnimation() {
digitalWrite(statusLed1, HIGH);
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],LOW);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],LOW);
delay(30);
}
digitalWrite(statusLed1, LOW);
delay(100);
}

View File

@ -0,0 +1,53 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_PROTOSEQ.h>
// sequence ID
int s1;
//int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
int notes1[] = {36, 48, 31, 36, 60, 36, 48, 39, 24, 36, 72, 60, 43, 48, 27, 60};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(13);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Sequencer.init(140);
s1 = Sequencer.newSequence(NOTE_16, 16, LOOP);
Sequencer.startSequence(s1);
Sequencer.insertNotes(s1, notes1, 16, 0);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, false);
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(true);
}
void loop() {
Sequencer.update();
usbMIDI.read();
Midi.checkSerialMidi();
}

View File

@ -0,0 +1,58 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_PROTOSEQ.h>
// sequence ID
int s1;
//int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
int notes1[] = {36, 48, 31, 36, 60, 36, 48, 39, 24, 36, 72, 60, 43, 48, 27, 60};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(13);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Sequencer.init(140);
s1 = Sequencer.newSequence(NOTE_16, 16, LOOP);
Sequencer.insertNotes(s1, notes1, 16, 0);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, false);
Sequencer.startSequence(s1);
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(true);
}
void loop() {
// Serial.print("loop - ");
// Serial.println(micros());
Sequencer.update();
// Serial.println("Sequencer.update()");
usbMIDI.read();
// Serial.println("usbMIDI.read()");
Midi.checkSerialMidi();
// Serial.println("Midi.checkSerialMidi()");
}

View File

@ -0,0 +1,53 @@
#define MIDI_CHANNEL 2
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_PROTOSEQ.h>
// sequence ID
int s1;
//int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
int notes1[] = {36, 48, 31, 36, 60, 36, 48, 39, 24, 36, 72, 60, 43, 48, 27, 60};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(13);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Sequencer.init(140);
s1 = Sequencer.newSequence(NOTE_16, 16, LOOP);
Sequencer.startSequence(s1);
Sequencer.insertNotes(s1, notes1, 16, 0);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, false);
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(false);
}
void loop() {
Sequencer.update();
usbMIDI.read();
Midi.checkSerialMidi();
}

View File

@ -0,0 +1,66 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
const int pot1 = A0, pot2 = A1;
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
Music.getPreset(16);
Music.setEnv1Decay(36);
Music.setEnv1Sustain(0);
}
void loop() {
usbMIDI.read();
updateSequence();
Music.setCutoff((1023-analogRead(pot1))*64);
Music.setCutoffModAmount((1023-analogRead(pot2))*64);
}
boolean noteIsOn = false;
int n = 0;
int dir = 1;
int rootNote = 36;
//int note[] = {0,0,0,0,0,0,0,0,0};
int note[] = {0,12,3,19,15,9,5,24,7};
long time = 0;
long lastTime = 0;
long timeDelay = 60;
void updateSequence() {
// This short routine loops note over and over again
time = millis();
if(time - lastTime > timeDelay) {
if(!noteIsOn) {
Music.noteOn(rootNote+note[n]);
noteIsOn = true;
n = n + dir;
if(n > 7)
{
dir = -1;
}
else if(n < 1)
{
dir = 1;
}
} else {
Music.noteOff();
noteIsOn = false;
}
lastTime = time;
}
}

View File

@ -0,0 +1 @@
Put Music Tutorial sketches in this folder

View File

@ -0,0 +1,60 @@
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
boolean noteIsOn = false;
int n = 0;
int dir = 1;
int rootNote = 36;
int note[] = {0,12,3,19,15,9,5,24,7};
long time = 0;
long lastTime = 0;
long timeDelay = 60;
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
// Choosing the square wave oscillator.
Music.setWaveform(SAW);
// Detuning the three oscillators slightly to create movement in the sound.
Music.setDetune(0.005);
// enabling the envelope lets us define an gain envelope for the synth
// without having to specify it in our loop() or physics code.
Music.enableEnvelope1();
Music.setEnv1Attack(8);
Music.setEnv1Decay(90);
Music.setEnv1Sustain(48);
Music.setEnv1Release(64);
}
void loop() {
// This short routine loops note over and over again
time = millis();
if(time - lastTime > timeDelay) {
if(!noteIsOn) {
Music.noteOn(rootNote+note[n]);
noteIsOn = true;
n = n + dir;
if(n > 7)
{
dir = -1;
}
else if(n < 1)
{
dir = 1;
}
} else {
Music.noteOff();
noteIsOn = false;
}
lastTime = time;
}
}

84
examples/sampler/sampler.ino Executable file
View File

@ -0,0 +1,84 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
// sequence ID
int s1;
// sequence step index
int indx1 = 0;
const int nbr_notes1 = 16;
int BD[] = {1,0,0,1, 0,0,1,0, 0,0,1,0, 0,0,0,0};
int SN[] = {0,0,0,0, 1,0,0,0, 0,0,0,0, 1,0,0,0};
int RS[] = {0,0,1,0, 0,1,0,0, 0,0,1,0, 0,1,0,0};
int CP[] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1};
int HH[] = {1,0,1,0, 1,1,0,1, 0,1,0,1, 0,1,0,1};
int OH[] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0};
int CL[] = {0,1,0,0, 0,0,1,0, 0,0,0,1, 0,1,1,0};
int CB[] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
//int BD[] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1};
//int SN[] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1};
//int RS[] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1};
//int CP[] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1};
//int HH[] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1};
//int OH[] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1};
//int CL[] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1};
//int CB[] = {1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.setSampler(true);
Music.setSynth(false);
Music.enableEnvelope1();
Music.enableEnvelope2();
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
// this is the sequencer code
Sequencer.init(120);
Sequencer.setInternalClock(true);
//Sequencer.newSequence(SUBDIV, CALLBACK);
s1 = Sequencer.newSequence(NOTE_16, &s1cb);
// Sequencer.setInternal(s1, true);
// Sequencer.setExternal(s1, false);
// start sequences
Sequencer.startSequence(s1);
}
void loop() {
// Checking for incoming MIDI to use dashboard
usbMIDI.read();
Sequencer.update();
Midi.checkSerialMidi();
}
// callback function for the step sequencer
void s1cb() {
if(BD[indx1]) Music.noteOnSample(0);
if(SN[indx1]) Music.noteOnSample(1);
if(RS[indx1]) Music.noteOnSample(2);
if(CP[indx1]) Music.noteOnSample(3);
if(HH[indx1]) Music.noteOnSample(4);
if(OH[indx1]) Music.noteOnSample(5);
if(CL[indx1]) Music.noteOnSample(6);
if(CB[indx1]) Music.noteOnSample(7);
indx1++;
if(indx1 >= nbr_notes1) indx1 = 0;
}

View File

@ -0,0 +1,131 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
// sequence ID
int s1, s2, s3, s4;
// sequence step index
int indx1 = 0;
int indx2 = 0;
int indx3 = 0;
int indx4 = 0;
const int nbr_notes1 = 16;
const int nbr_steps2 = 8;
const int nbr_notes3 = 8;
const int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
const int midiCC[] = {8, 8, 11, 21, 21, 11, 21, 31, 8};
const int midiValue[] = {0, 80, 68, 68, 68, 72, 72, 72, 0};
int BD[] = {1, 0, 0, 1, 0, 0, 1, 0};
int SN[] = {0, 0, 0, 0, 1, 0, 0, 0};
int RS[] = {0, 1, 0, 1, 0, 0, 1, 0};
int CP[] = {0, 0, 0, 0, 1, 0, 0, 0};
int HH[] = {1, 0, 1, 1, 0, 1, 0, 0};
int OH[] = {0, 0, 0, 0, 0, 0, 0, 0};
int CL[] = {0, 0, 1, 0, 0, 1, 0, 0};
int CB[] = {0, 0, 0, 0, 0, 0, 0, 1};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.setSampler(true);
Music.enableEnvelope1();
Music.enableEnvelope2();
// Loading a preset from EEPROM
Music.getPreset(21);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
// this is the sequencer code
Sequencer.init(120);
// Midi.setMidiIn(false);
// Midi.setMidiThru(false);
// Midi.setMidiOut(false);
// Midi.setMidiClockIn(false);
// Midi.setMidiClockThru(false);
// Midi.setMidiClockOut(true);
Sequencer.setInternalClock(true);
//Sequencer.newSequence(SUBDIV, CALLBACK);
// create new sequences and IDs
s1 = Sequencer.newSequence(NOTE_16, &s1cb);
s2 = Sequencer.newSequence(NOTE_32, &s2cb);
s3 = Sequencer.newSequence(NOTE_8, &s3cb);
s4 = Sequencer.newSequence(NOTE_16, &s4cb);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, false);
Sequencer.setInternal(s2, true);
Sequencer.setExternal(s2, false);
Sequencer.setInternal(s3, true);
Sequencer.setExternal(s3, false);
Sequencer.setInternal(s4, true);
Sequencer.setExternal(s4, false);
// start sequences
Sequencer.startSequence(s1);
Sequencer.startSequence(s2);
Sequencer.startSequence(s3); // start s4 instead of s3
}
void loop() {
// Checking for incoming MIDI to use dashboard
usbMIDI.read();
Sequencer.update();
Midi.checkSerialMidi();
}
// callback function for the step sequencers
void s1cb() {
Music.noteOn(notes1[indx1++] + 24, 127);
if(indx1 >= nbr_notes1) indx1 = 0;
}
void s2cb() {
Midi.controller(MIDI_CHANNEL - 1, midiCC[indx2], midiValue[indx2]);
indx2++;
if(indx2 >= nbr_steps2) indx2 = 0;
}
void s3cb() {
if(BD[indx3]) Music.noteOnSample(0);
if(SN[indx3]) Music.noteOnSample(1);
if(RS[indx3]) Music.noteOnSample(2);
if(CP[indx3]) Music.noteOnSample(3);
if(HH[indx3]) Music.noteOnSample(4);
if(OH[indx3]) Music.noteOnSample(5);
if(CL[indx3]) Music.noteOnSample(6);
if(CB[indx3]) Music.noteOnSample(7);
indx3++;
if(indx3 >= nbr_notes3) indx3 = 0;
}
void s4cb() {
if(BD[indx3]) Music.noteOnSample(0);
if(SN[indx3]) Music.noteOnSample(1);
if(RS[indx3]) Music.noteOnSample(2);
if(CP[indx1]) Music.noteOnSample(3);
if(HH[indx4++]) Music.noteOnSample(4);
if(OH[indx3]) Music.noteOnSample(5);
if(CL[indx4]) Music.noteOnSample(6);
if(CB[indx3++]) Music.noteOnSample(7);
indx3++;
if(indx3 >= nbr_notes3) indx3 = 0;
if(indx2 >= nbr_notes1) indx4 = 0;
}

View File

@ -0,0 +1,60 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
// sequence ID
int s1;
// sequence step index
int indx1 = 0;
const int nbr_notes1 = 16;
const int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
Music.getPreset(13);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
// this is the sequencer code
Sequencer.init(140);
// Midi.setMidiIn(false);
// Midi.setMidiThru(false);
// Midi.setMidiOut(false);
// Midi.setMidiClockIn(false);
// Midi.setMidiClockThru(false);
// Midi.setMidiClockOut(true);
Sequencer.setInternalClock(true);
s1 = Sequencer.newSequence(NOTE_16, &s1cb);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, false);
Sequencer.startSequence(s1);
// Loading a preset from EEPROM
}
void loop() {
// Checking for incoming MIDI to use dashboard
usbMIDI.read();
Sequencer.update();
Midi.checkSerialMidi();
}
// callback function for the step sequencer
void s1cb() {
Music.noteOn(notes1[indx1++] + 24, 127);
if(indx1 >= nbr_notes1) indx1 = 0;
}

View File

@ -0,0 +1,79 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
// sequence ID
int s1, s2;
// sequence step index
int indx1 = 0;
int indx2 = 0;
const int nbr_notes1 = 16;
const int nbr_steps2 = 8;
const int notes1[] = {12, 24, 7, 12, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
const int midiCC[] = {8, 8, 11, 21, 21, 11, 21, 31, 8};
const int midiValue[] = {0, 80, 68, 68, 68, 72, 72, 72, 0};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
// Loading a preset from EEPROM
Music.getPreset(13);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
// this is the sequencer code
Sequencer.init(120);
// Midi.setMidiIn(false);
// Midi.setMidiThru(false);
// Midi.setMidiOut(false);
// Midi.setMidiClockIn(false);
// Midi.setMidiClockThru(false);
// Midi.setMidiClockOut(true);
Sequencer.setInternalClock(true);
//Sequencer.newSequence(CALLBACK, SUBDIV);
// create new sequence and ID (s1)
s1 = Sequencer.newSequence(NOTE_16, &s1cb);
s2 = Sequencer.newSequence(NOTE_32, &s2cb);
Sequencer.setInternal(s1, true);
Sequencer.setExternal(s1, false);
Sequencer.setInternal(s2, true);
Sequencer.setExternal(s2, false);
// start sequence 1 and 2
Sequencer.startSequence(s1);
Sequencer.startSequence(s2);
}
void loop() {
// Checking for incoming MIDI to use dashboard
usbMIDI.read();
Sequencer.update();
Midi.checkSerialMidi();
}
// callback function for the step sequencer
void s1cb() {
Music.noteOn(notes1[indx1++] + 24, 127);
if(indx1 >= nbr_notes1) indx1 = 0;
}
void s2cb() {
Midi.controller(MIDI_CHANNEL - 1, midiCC[indx2], midiValue[indx2]);
indx2++;
if(indx2 >= nbr_steps2) indx2 = 0;
}

View File

@ -0,0 +1,86 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
// sequence ID
int s1, s2, s3;
// sequence step index
int indx1 = 0;
int indx2 = 0;
int indx3 = 0;
const int nbr_steps1 = 16;
const int nbr_steps2 = 8;
const int nbr_steps3 = 15;
const int nbr_steps4 = 4;
const int notes1[] = {12, 24, 7, 15, 36, 12, 24, 15, 0, 12, 48, 36, 19, 24, 3, 36};
const int notes2[] = {0, 7, 15, 24, 12, 19, 3, 24};
const int midiCC2[] = {8, 8, 11, 21, 31, 11, 21, 31, 8};
const int midiValue2[] = {0, 80, 68, 68, 68, 72, 72, 72, 0};
const int midiCC3[] = {14, 24, 34, 14, 34, 24, 14, 34, 24, 14, 34, 14, 24, 14, 24, 34};
const int midiValue3[] = {1, 2, 4, 2, 1, 4, 2, 1, 4, 2, 1, 4, 2, 2, 1, 4};
const int midiCC4[] = {11, 11, 11, 11};
const int midiValue4[] = {64, 67, 71, 76};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.getPreset(11);
Music.enableEnvelope1();
Music.enableEnvelope2();
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
// this is the sequencer code
Sequencer.init(112);
Sequencer.setInternalClock(true);
//Sequencer.newSequence(CALLBACK, SUBDIV);
// create new sequence and ID (s1)
s1 = Sequencer.newSequence(NOTE_8, &s1cb);
s2 = Sequencer.newSequence(NOTE_32, &s2cb);
s3 = Sequencer.newSequence(NOTE_96, &s3cb);
// start sequence 1
Sequencer.startSequence(s1);
// Sequencer.startSequence(s2);
Sequencer.startSequence(s3);
// Loading a preset from EEPROM
Music.setGain2(0.0);
Music.setGain3(0.0);
}
void loop() {
// Checking for incoming MIDI to use dashboard
usbMIDI.read();
Sequencer.update();
Midi.checkSerialMidi();
}
// callback function for the step sequencer
void s1cb() {
Music.noteOn(notes1[indx1++] + 48, 127);
if(indx1 >= nbr_steps1) indx1 = 0;
}
void s2cb() {
if(indx2 < nbr_steps2) Midi.controller(MIDI_CHANNEL - 1, midiCC2[indx2], midiValue2[indx2]);
indx2++;
if(indx2 >= nbr_steps2) indx2 = 0;
}
void s3cb() {
if(indx3 < nbr_steps4) Midi.controller(MIDI_CHANNEL - 1, midiCC4[indx3], midiValue4[indx3]);
indx3++;
if(indx3 >= nbr_steps4) indx3 = 0;
}

View File

@ -0,0 +1,76 @@
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
// sequence ID
int s1, s2;
// sequence step index
int indx1 = 0;
int indx2 = 0;
int indx3 = 0;
const int nbr_notes1 = 16;
const int nbr_notes2 = 8;
const int nbr_notes3 = 32;
const int notes1[] = {12, 24, 19, 12, 36, 12, 24, 15, 36, 12, 48, 36, 19, 24, 15, 36};
void setup() {
// We initialise the sound engine by calling Music.init() which outputs a tone
Music.init();
Music.enableEnvelope1();
Music.enableEnvelope2();
// Loading a preset from EEPROM
Music.getPreset(13);
// These guys just have to be here...
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
// this is the sequencer code
Sequencer.init(128);
Sequencer.setInternalClock(true);
//Sequencer.newSequence(CALLBACK, SUBDIV);
// create new sequence and ID (s1)
s1 = Sequencer.newSequence(NOTE_8, &s1cb);
s2 = Sequencer.newSequence(NOTE_6, &s2cb);
// start sequence 1
Sequencer.startSequence(s1);
Sequencer.startSequence(s2);
Music.setPortamento(124);
}
void loop() {
// Checking for incoming MIDI to use dashboard
usbMIDI.read();
Sequencer.update();
Midi.checkSerialMidi();
}
// callback function for the step sequencer
void s1cb() {
Music.noteOn(notes1[indx1++] + 36, 127);
if(indx2 >= nbr_notes1) indx1 = 0;
indx3++;
if(indx3 >= nbr_notes3) {
indx1 = 0;
indx2 = 0;
indx3 = 0;
}
}
void s2cb() {
Music.noteOn(notes1[indx1++] + 36, 127);
if(indx1 >= nbr_notes2) indx2 = 0;
}