examples
This commit is contained in:
parent
5aa8489eee
commit
85c52ea5c9
447
examples/CFO_BODYSEQ_2buttons/CFO_BODYSEQ_2buttons.ino
Executable file
447
examples/CFO_BODYSEQ_2buttons/CFO_BODYSEQ_2buttons.ino
Executable 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
465
examples/CFO_BODYSEQ_3buttons/CFO_BODYSEQ_3buttons.ino
Executable file
465
examples/CFO_BODYSEQ_3buttons/CFO_BODYSEQ_3buttons.ino
Executable 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
524
examples/CFO_BODYSEQ_3buttons_experimental/CFO_BODYSEQ_3buttons_experimental.ino
Executable file
524
examples/CFO_BODYSEQ_3buttons_experimental/CFO_BODYSEQ_3buttons_experimental.ino
Executable 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();
|
||||
|
||||
}
|
||||
539
examples/CFO_BODYSEQ_3buttons_midi_synced/CFO_BODYSEQ_3buttons_midi_synced.ino
Executable file
539
examples/CFO_BODYSEQ_3buttons_midi_synced/CFO_BODYSEQ_3buttons_midi_synced.ino
Executable 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
234
examples/CFO_BODYSEQ_O/CFO_BODYSEQ_O.ino
Executable file
234
examples/CFO_BODYSEQ_O/CFO_BODYSEQ_O.ino
Executable 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]);
|
||||
}
|
||||
}
|
||||
157
examples/CFO_BODYSEQ_O/interface.ino
Executable file
157
examples/CFO_BODYSEQ_O/interface.ino
Executable 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);
|
||||
}
|
||||
|
||||
110
examples/CFO_BODYSEQ_P/CFO_BODYSEQ_P.ino
Executable file
110
examples/CFO_BODYSEQ_P/CFO_BODYSEQ_P.ino
Executable 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);
|
||||
}
|
||||
}
|
||||
103
examples/CFO_BODYSEQ_Q/CFO_BODYSEQ_Q.ino
Executable file
103
examples/CFO_BODYSEQ_Q/CFO_BODYSEQ_Q.ino
Executable 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);
|
||||
}
|
||||
}
|
||||
286
examples/CFO_BODYSEQ_SAMPLER/CFO_BODYSEQ_SAMPLER.ino
Executable file
286
examples/CFO_BODYSEQ_SAMPLER/CFO_BODYSEQ_SAMPLER.ino
Executable 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
201
examples/CFO_BODYSEQ_SAMPLER/interface.ino
Executable file
201
examples/CFO_BODYSEQ_SAMPLER/interface.ino
Executable 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);
|
||||
}
|
||||
|
||||
53
examples/CFO_PROTOSEQ/CFO_PROTOSEQ.ino
Executable file
53
examples/CFO_PROTOSEQ/CFO_PROTOSEQ.ino
Executable 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();
|
||||
}
|
||||
|
||||
58
examples/CFO_PROTOSEQ_KLOCKMEISTER/CFO_PROTOSEQ_KLOCKMEISTER.ino
Executable file
58
examples/CFO_PROTOSEQ_KLOCKMEISTER/CFO_PROTOSEQ_KLOCKMEISTER.ino
Executable 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()");
|
||||
}
|
||||
|
||||
53
examples/CFO_PROTOSEQ_SLAVE/CFO_PROTOSEQ_SLAVE.ino
Executable file
53
examples/CFO_PROTOSEQ_SLAVE/CFO_PROTOSEQ_SLAVE.ino
Executable 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();
|
||||
}
|
||||
|
||||
66
examples/Music/Init_midi/Init_midi.ino
Executable file
66
examples/Music/Init_midi/Init_midi.ino
Executable 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;
|
||||
}
|
||||
}
|
||||
1
examples/Music/Music_tutorial_files.txt
Executable file
1
examples/Music/Music_tutorial_files.txt
Executable file
@ -0,0 +1 @@
|
||||
Put Music Tutorial sketches in this folder
|
||||
60
examples/Music/_6_noteOn_noteOff/_6_noteOn_noteOff.ino
Executable file
60
examples/Music/_6_noteOn_noteOff/_6_noteOn_noteOff.ino
Executable 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
84
examples/sampler/sampler.ino
Executable 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;
|
||||
}
|
||||
131
examples/sampler_and_sequenced_audio/sampler_and_sequenced_audio.ino
Executable file
131
examples/sampler_and_sequenced_audio/sampler_and_sequenced_audio.ino
Executable 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;
|
||||
}
|
||||
60
examples/sequenced_audio/sequenced_audio.ino
Executable file
60
examples/sequenced_audio/sequenced_audio.ino
Executable 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;
|
||||
}
|
||||
79
examples/sequenced_audio2/sequenced_audio2.ino
Executable file
79
examples/sequenced_audio2/sequenced_audio2.ino
Executable 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;
|
||||
}
|
||||
86
examples/sequenced_audio3/sequenced_audio3.ino
Executable file
86
examples/sequenced_audio3/sequenced_audio3.ino
Executable 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;
|
||||
}
|
||||
76
examples/sequenced_audio4/sequenced_audio4.ino
Executable file
76
examples/sequenced_audio4/sequenced_audio4.ino
Executable 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;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user