This commit is contained in:
gauthiier
2018-12-01 12:57:32 +01:00
parent 5aa8489eee
commit dd0197fa42
23 changed files with 3954 additions and 0 deletions
+286
View File
@@ -0,0 +1,286 @@
//______________________/\\\\\__________________________/\\\______________________________/\\\__________________________________________________________
// ____________________/\\\///__________________________\/\\\_____________________________\/\\\__________________________________________________________
// ___________________/\\\______________________________\/\\\_____________________________\/\\\_____/\\\__/\\\_______________________________/\\\\\\\\___
// _____/\\\\\\\\__/\\\\\\\\\_______/\\\\\______________\/\\\____________/\\\\\___________\/\\\____\//\\\/\\\___/\\\\\\\\\\_____/\\\\\\\\___/\\\////\\\__
// ___/\\\//////__\////\\\//______/\\\///\\\____________\/\\\\\\\\\____/\\\///\\\____/\\\\\\\\\_____\//\\\\\___\/\\\//////____/\\\/////\\\_\//\\\\\\\\\__
// __/\\\____________\/\\\_______/\\\__\//\\\___________\/\\\////\\\__/\\\__\//\\\__/\\\////\\\______\//\\\____\/\\\\\\\\\\__/\\\\\\\\\\\___\///////\\\__
// _\//\\\___________\/\\\______\//\\\__/\\\____________\/\\\__\/\\\_\//\\\__/\\\__\/\\\__\/\\\___/\\_/\\\_____\////////\\\_\//\\///////__________\/\\\__
// __\///\\\\\\\\____\/\\\_______\///\\\\\/_____________\/\\\\\\\\\___\///\\\\\/___\//\\\\\\\/\\_\//\\\\/_______/\\\\\\\\\\__\//\\\\\\\\\\________\/\\\\_
// ____\////////_____\///__________\/////_______________\/////////______\/////______\///////\//___\////________\//////////____\//////////_________\////__
// CFO BODYSEQ sequencer, 3 button version, reworked interaction, http://www.vsionhairies.info/
#define MIDI_CHANNEL 1
#include <spi4teensy3.h>
#include <EEPROM.h>
#include <CFO_BODYSEQ.h>
#define NUM_TRACKS 8
#define NUM_STEPS 8
#define NUM_SAMPLES 8
#define NUM_LEDS 8
int mode;
unsigned long debounceTime = 100;
unsigned long debounceTimeDefault = 100;
unsigned long debounceTimeLong = 500;
int _bpm;
int trackPlaying = 0 ;
int trackSelected = 0;
int sampleSelected = 0;
int stepSelected = 0;
int trackChained = -1;
int s1;
int indx = 0;
int indxLED;
uint8_t sample[NUM_TRACKS][NUM_SAMPLES][NUM_STEPS];
int leds;
int chainedLedState = 0;
unsigned long ledNow;
unsigned long ledTime = 0;
unsigned long ledPulse = 100;
bool inStartupMode = true;
// old stuff
const int seqLed[] = {3,4,5,6,7,8,9,10};
const int statusLed1 = 13;
//boolean debug = true;
/////////////
// BUTTONS //
/////////////
#define NUM_BUTTONS 3
const int buttonPin [] = {11,12,2};
int buttonIndex = 0;
int buttonRead = 0;
int buttonChange = 0;
int buttonState[] = {0, 0, 0};
unsigned long buttonNow = 0;
unsigned long buttonTime[] = {0, 0, 0};
int machineState = 0;
//////////
// KEYS //
//////////
#define NUM_KEYS 8
#define KEY_THRESHOLD 15
const int keyPin[] = {A2,A3,A4,A5,A6,A7,A8,A9};
int keyIndex = 0;
int keyRead = 0;
int keyValue = 0;
int keyChange = 0;
int keyState[] = {0, 0, 0, 0, 0, 0, 0, 0};
unsigned long keyNow = 0;
unsigned long keyTime[] = {0, 0, 0, 0, 0, 0, 0, 0};
int keys;
void setup() {
Music.init();
Music.setSampler(true);
Music.setSynth(false);
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleControlChange(OnControlChange);
usbMIDI.setHandleRealTimeSystem(RealTimeSystem);
analogReadAveraging(32);
Sequencer.init(120);
// Sequencer.setInternalClock(true);
s1 = Sequencer.newSequence(NOTE_16, &s1cb);
// resetMemory();
loadSequences();
initInterface();
Sequencer.startSequence(s1);
}
void loop() {
Sequencer.update();
usbMIDI.read();
Midi.checkSerialMidi();
readButtons();
readKeys();
checkBPM();
checkBitcrush();
switch(machineState) {
case 0:
playTrack();
break;
case 1:
selectStep();
break;
case 2:
selectSample();
break;
case 3:
selectTrack();
break;
case 4:
selectTrack();
break;
case 5: // nothing
chainTrack();
break;
case 6:
copyTrack();
break;
case 7:
clearTrack();
break;
default:
break;
}
updateLEDs();
}
void playTrack() {
if(keyChange && keys) {
Serial.println("PLAY TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
if(trackPlaying == i) trackChained = -1;
if(trackChained < 0) trackPlaying = i;
else trackChained = i;
}
}
keyChange = 0;
}
}
void selectStep() {
if(keyChange) {
Serial.println("SELECT STEP");
for(int k = 0; k < NUM_KEYS; k++) {
if(keys & (1 << k)) {
stepSelected = k;
int j = sampleSelected;
int i = trackSelected;
sample[i][j][k] ^= 1;
EEPROM.write(k + NUM_SAMPLES * (j + i * NUM_TRACKS), sample[i][j][k]);
}
}
keyChange = 0;
}
}
void selectSample() {
if(keyChange) {
Serial.println("SELECT SAMPLE");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
sampleSelected = i;
}
}
keyChange = 0;
}
}
void selectTrack() {
if(keyChange) {
Serial.println("SELECT TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
trackSelected = i;
}
}
keyChange = 0;
}
}
void chainTrack() {
if(keyChange) {
Serial.println("SELECT TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
if(i == trackChained) trackChained = -1;
else trackChained = i;
}
}
keyChange = 0;
}
}
void copyTrack() {
if(keyChange) {
debounceTime = debounceTimeLong;
Serial.println("COPY TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
sample[i][j][k] = sample[trackSelected][j][k];
EEPROM.write(k + NUM_SAMPLES * (j + i * NUM_TRACKS), sample[i][j][k]);
}
}
}
}
keyChange = 0;
debounceTime = debounceTimeDefault;
}
}
void clearTrack() {
if(keyChange) {
Serial.println("CLEAR TRACK");
for(int i = 0; i < NUM_KEYS; i++) {
if(keys & (1 << i)) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
sample[i][j][k] = 0;
EEPROM.write(k + NUM_SAMPLES * (j + i * NUM_TRACKS), 0);
}
}
}
}
keyChange = 0;
}
}
void resetMemory() {
for(int i=0; i<NUM_TRACKS; i++) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
EEPROM.write(k + NUM_SAMPLES * (j + i * NUM_TRACKS), 0);
}
}
}
}
void loadSequences() {
for(int i=0; i<NUM_TRACKS; i++) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
sample[i][j][k] = EEPROM.read(k + NUM_SAMPLES * (j + i * NUM_TRACKS));
}
}
}
}
void s1cb() {
indxLED = indx;
for(int i=0; i<NUM_SAMPLES; i++) {
if(sample[trackPlaying][i][indx]) Music.noteOnSample(i);
}
indx++;
if(indx >= NUM_STEPS) {
indx = 0;
if(trackChained < 0);
else {
int t = trackPlaying;
trackPlaying = trackChained;
trackChained = t;
}
}
}
+201
View File
@@ -0,0 +1,201 @@
/////////////
// BUTTONS //
/////////////
void readButtons() {
// buttons are active low
for(int i = 0; i < NUM_BUTTONS; i++) {
// int i = buttonIndex++;
// if(buttonIndex >= NUM_BUTTONS) buttonIndex = 0;
buttonNow = millis();
if((buttonNow - buttonTime[i]) > debounceTime) {
buttonRead = digitalRead(buttonPin[i]);
if(buttonRead != buttonState[i]) {
buttonState[i] = buttonRead;
buttonChange |= 1<<i;
buttonTime[i] = buttonNow;
machineState = 7 - buttonState[0] - buttonState[1] * 2 - buttonState[2] * 4;
}
}
}
}
//////////
// KEYS //
//////////
void readKeys() {
int keyr = 0;
int keyv = 0;
for (int i = 0; i < NUM_KEYS; i++) {
keyNow = millis();
if((keyNow - keyTime[i]) > debounceTime) {
keyRead = analogRead(keyPin[i]);
if(keyRead > KEY_THRESHOLD) {
keyValue = 1;
} else {
keyValue = 0;
}
if(i == 0) {
keyr = keyRead;
keyv = keyValue;
}
// keyValue = (keyRead > KEY_THRESHOLD) ? 1 : 0 ;
if(keyState[i] != keyValue) {
keyState[i] = keyValue;
keyChange |= 1<<i;
keyTime[i] = keyNow;
}
}
}
for (int i = 0; i < NUM_KEYS; i++) {
if(keyState[i] == 1) {
keys |= (1<<i);
} else if(keyState[i] == 0) {
keys &= ~(1<<i);
}
}
// Serial.printf("keyTime[0]=%10ld, keyr=%i, keyv=%i - keyState is %i%i%i%i%i%i%i%i, keys is %X \n", keyTime[0], keyr, keyv, keyState[0], keyState[1], keyState[2], keyState[3], keyState[4], keyState[5], keyState[6], keyState[7], keys);
}
//////////
// POTS //
//////////
void checkBPM() {
int bpm = analogRead(A0)>>2;
if(bpm != _bpm) {
_bpm = bpm;
Serial.print("BPM set to ");
Serial.println(_bpm);
Sequencer.setbpm(_bpm);
if(_bpm == 0) {
Midi.setMidiIn(true);
Midi.setMidiThru(true);
Midi.setMidiOut(true);
Midi.setMidiClockIn(true);
Midi.setMidiClockThru(true);
Midi.setMidiClockOut(true);
Sequencer.setInternalClock(false);
} else {
Midi.setMidiIn(false);
Midi.setMidiThru(false);
Midi.setMidiOut(false);
Midi.setMidiClockIn(false);
Midi.setMidiClockThru(false);
Midi.setMidiClockOut(false);
Sequencer.setInternalClock(true);
// Sequencer.sequencerContinue();
}
}
}
void checkBitcrush() {
int bc = (1024 - analogRead(A1)) >> 7;
Music.setBitcrush(bc);
}
void initInterface() {
pinMode(buttonPin[0], INPUT_PULLUP);
pinMode(buttonPin[1], INPUT_PULLUP);
pinMode(buttonPin[2], INPUT_PULLUP);
pinMode(statusLed1,OUTPUT);
for (int i = 0; i<8; i++) {
pinMode(seqLed[i], OUTPUT);
}
startupAnimation();
}
void updateLEDs() {
ledNow = millis();
int t = trackSelected;
int s = sampleSelected;
leds = 0;
switch(machineState) {
case 0: // PLAY TRACK
leds |= (1 << trackPlaying);
if(trackChained >= 0) {
if((ledNow - ledTime) > ledPulse) {
chainedLedState ^= 1;
ledTime = ledNow;
}
leds |= (chainedLedState << trackChained);
}
break;
case 1: // SELECT STEP
// leds = 0;
for(int i=0; i<NUM_STEPS; i++) {
leds |= (sample[t][s][i] << i);
}
break;
case 2: // SELECT SAMPLE
leds |= (1 << sampleSelected);
break;
case 3: // SELECT TRACK
leds |= (1 << trackSelected);
break;
case 4: // SELECT TRACK
leds |= (1 << trackSelected);
break;
case 5: // CHAIN TRACKS PLAYING
leds |= (1 << trackPlaying);
if(trackChained >= 0) {
if((ledNow - ledTime) > ledPulse) {
chainedLedState ^= 1;
ledTime = ledNow;
}
leds |= (chainedLedState << trackChained);
}
break;
case 6: // COPY TRACK
leds |= (1 << trackSelected);
break;
case 7: // CLEAR TRACK
for(int i=0; i<NUM_KEYS; i++) {
for(int j=0; j<NUM_SAMPLES; j++) {
for(int k=0; k<NUM_STEPS; k++) {
leds |= (sample[i][j][k] << i);
}
}
}
break;
default:
break;
}
for (int i = 0; i<8; i++) {
leds |= (1 << indxLED);
digitalWrite(seqLed[i], leds & (1 << i));
// leds ^= (1 << indxLED);
}
}
void startupAnimation() {
digitalWrite(statusLed1, HIGH);
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[i],LOW);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],HIGH);
delay(30);
}
for (int i = 0; i<8; i++) {
digitalWrite(seqLed[7-i],LOW);
delay(30);
}
digitalWrite(statusLed1, LOW);
delay(100);
}