378 lines
9.5 KiB
Arduino
378 lines
9.5 KiB
Arduino
|
|
#include <FASTSENSOR.h>
|
||
|
|
#include <WORDS.h>
|
||
|
|
#include <Audio.h>
|
||
|
|
#include <SOUND.h>
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* TOUCH
|
||
|
|
------------------------*/
|
||
|
|
|
||
|
|
static const int PIN_A = 1; // white
|
||
|
|
static const int PIN_B = 3; // red
|
||
|
|
static const int PIN_C = 5; // black
|
||
|
|
static const int PIN_D = 16; // green
|
||
|
|
static const int PIN_E = 17; // yellow
|
||
|
|
static const int PIN_F = 22; // blue -> orange -> yellow
|
||
|
|
|
||
|
|
static int cutoff = 20;
|
||
|
|
|
||
|
|
SENSOR_t s_A(PIN_A, cutoff);
|
||
|
|
SENSOR_t s_B(PIN_B, cutoff);
|
||
|
|
SENSOR_t s_C(PIN_C, cutoff);
|
||
|
|
SENSOR_t s_D(PIN_D, cutoff);
|
||
|
|
SENSOR_t s_E(PIN_E, cutoff);
|
||
|
|
SENSOR_t s_F(PIN_F, cutoff);
|
||
|
|
|
||
|
|
static int READ_DELAY = 150;
|
||
|
|
|
||
|
|
///forward declare
|
||
|
|
|
||
|
|
void synth_toggle(bool p, int pin);
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* WORDS
|
||
|
|
------------------------*/
|
||
|
|
|
||
|
|
static E_WORDS voice_A_words[] = {E1, E2, L0, L1, L2};
|
||
|
|
static E_WORDS voice_B_words[] = {E3, L3};
|
||
|
|
static E_WORDS voice_C_words[] = {E4, E5, E6, L4, L5, L6};
|
||
|
|
static E_WORDS voice_D_words[] = {E7, E8, E9, L7, L8, L9, L10};
|
||
|
|
static E_WORDS voice_E_words[] = {E10, E11, E12, E13, L11, L12};
|
||
|
|
|
||
|
|
static int MAX_WORD = 4;
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* AUDIO
|
||
|
|
------------------------*/
|
||
|
|
// Use these with the Teensy 4 Audio Shield
|
||
|
|
#define SDCARD_CS_PIN 10
|
||
|
|
#define SDCARD_MOSI_PIN 11
|
||
|
|
#define SDCARD_SCK_PIN 13
|
||
|
|
#define SDCARD_SCK_PIN 13
|
||
|
|
|
||
|
|
|
||
|
|
AudioOutputI2S audioOutput;
|
||
|
|
AudioControlSGTL5000 sgtl5000_1;
|
||
|
|
|
||
|
|
// WAV
|
||
|
|
|
||
|
|
AudioPlaySdWav wav_A;
|
||
|
|
AudioPlaySdWav wav_B;
|
||
|
|
AudioPlaySdWav wav_C;
|
||
|
|
AudioPlaySdWav wav_D;
|
||
|
|
AudioPlaySdWav wav_E;
|
||
|
|
AudioPlaySdWav wav_F;
|
||
|
|
|
||
|
|
WAVPLAY_t wavplay_A(PIN_A, &wav_A, EA, LA, voice_A_words, 5, synth_toggle);
|
||
|
|
WAVPLAY_t wavplay_B(PIN_B, &wav_B, EB, LB, voice_B_words, 2, synth_toggle);
|
||
|
|
WAVPLAY_t wavplay_C(PIN_C, &wav_C, EC, LC, voice_C_words, 6, synth_toggle);
|
||
|
|
WAVPLAY_t wavplay_D(PIN_D, &wav_D, ED, LD, voice_D_words, 7, synth_toggle);
|
||
|
|
WAVPLAY_t wavplay_E(PIN_E, &wav_E, EE, LE, voice_E_words, 6, synth_toggle);
|
||
|
|
|
||
|
|
AudioMixer4 wav_mixer1;
|
||
|
|
AudioMixer4 wav_mixer2;
|
||
|
|
|
||
|
|
AudioConnection patchCordA1(wav_A, 0, wav_mixer1, 0);
|
||
|
|
AudioConnection patchCordA2(wav_A, 1, wav_mixer2, 0);
|
||
|
|
AudioConnection patchCordB1(wav_B, 0, wav_mixer1, 1);
|
||
|
|
AudioConnection patchCordB2(wav_B, 1, wav_mixer2, 1);
|
||
|
|
AudioConnection patchCordC1(wav_C, 0, wav_mixer1, 2);
|
||
|
|
AudioConnection patchCordC2(wav_C, 1, wav_mixer2, 2);
|
||
|
|
AudioConnection patchCordD1(wav_D, 0, wav_mixer1, 3);
|
||
|
|
AudioConnection patchCordD2(wav_D, 1, wav_mixer2, 3);
|
||
|
|
|
||
|
|
// SYNTH
|
||
|
|
|
||
|
|
float freq = 300;
|
||
|
|
DETUNE_t synth(freq);
|
||
|
|
|
||
|
|
AudioMixer4 synth_mixer;
|
||
|
|
|
||
|
|
AudioConnection patchCord1(synth.sine3, 0, synth_mixer, 2);
|
||
|
|
AudioConnection patchCord2(synth.sine2, 0, synth_mixer, 1);
|
||
|
|
AudioConnection patchCord3(synth.sine1, 0, synth_mixer, 0);
|
||
|
|
|
||
|
|
// MIX
|
||
|
|
|
||
|
|
AudioMixer4 main_mixer_L;
|
||
|
|
AudioMixer4 main_mixer_R;
|
||
|
|
|
||
|
|
AudioConnection patchCord12(synth_mixer, 0, main_mixer_L, 1);
|
||
|
|
AudioConnection patchCord13(synth_mixer, 0, main_mixer_R, 1);
|
||
|
|
AudioConnection patchCord14(wav_mixer1, 0, main_mixer_L, 0);
|
||
|
|
AudioConnection patchCord15(wav_mixer2, 0, main_mixer_R, 0);
|
||
|
|
|
||
|
|
//!!!!-----!!!
|
||
|
|
|
||
|
|
AudioConnection patchCordE1(wav_E, 0, main_mixer_L, 2);
|
||
|
|
AudioConnection patchCordE2(wav_E, 1, main_mixer_R, 2);
|
||
|
|
AudioConnection patchCordF1(wav_F, 0, main_mixer_L, 3);
|
||
|
|
AudioConnection patchCordF2(wav_F, 1, main_mixer_R, 3);
|
||
|
|
|
||
|
|
//!!!!-----!!!
|
||
|
|
|
||
|
|
AudioConnection patchCord16(main_mixer_R, 0, audioOutput, 1);
|
||
|
|
AudioConnection patchCord17(main_mixer_L, 0, audioOutput, 0);
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* STATES
|
||
|
|
------------------------*/
|
||
|
|
|
||
|
|
SENSOR_t* synth_sensor = NULL;
|
||
|
|
int synth_PIN = -1;
|
||
|
|
bool gain_up = false;
|
||
|
|
|
||
|
|
float synth_gain_v = 0;
|
||
|
|
float synth_gain_max = 0.7;
|
||
|
|
float synth_gain_interval_ms = 1500;
|
||
|
|
float synth_gain_increments_ms = 0.01;
|
||
|
|
long synth_last_increment = 0;
|
||
|
|
|
||
|
|
bool sensor_touch[6] = {false, false, false, false, false, false};
|
||
|
|
|
||
|
|
void synth_toggle(bool p, int pin) {
|
||
|
|
if(synth_PIN == pin && !p) {
|
||
|
|
gain_up = false;
|
||
|
|
synth_gain(0);
|
||
|
|
synth_sensor = NULL;
|
||
|
|
synth_PIN = -1;
|
||
|
|
} else if(p && synth_PIN < 0) {
|
||
|
|
synth_PIN = pin;
|
||
|
|
if(pin == PIN_A) synth_sensor = &s_A;
|
||
|
|
else if(pin == PIN_B) synth_sensor = &s_B;
|
||
|
|
else if(pin == PIN_C) synth_sensor = &s_C;
|
||
|
|
else if(pin == PIN_D) synth_sensor = &s_D;
|
||
|
|
else if(pin == PIN_E) synth_sensor = &s_E;
|
||
|
|
else if(pin == PIN_F) synth_sensor = &s_F;
|
||
|
|
gain_up = true;
|
||
|
|
synth_gain(0.5);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void random_wav(AudioPlaySdWav* wav, E_WORDS* e_words) {
|
||
|
|
int w = (int)random(0, MAX_WORD);
|
||
|
|
wav->play(words[e_words[w]]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* CALLBACK
|
||
|
|
------------------------*/
|
||
|
|
|
||
|
|
void toggle_signal_cb(bool p, int pin) {
|
||
|
|
|
||
|
|
SENSOR_t* sensor = NULL;
|
||
|
|
|
||
|
|
switch(pin) {
|
||
|
|
case PIN_A:
|
||
|
|
if(p) wavplay_A.play();
|
||
|
|
else wavplay_A.stop();
|
||
|
|
sensor = &s_A;
|
||
|
|
sensor_touch[0] = p;
|
||
|
|
break;
|
||
|
|
case PIN_B:
|
||
|
|
if(p) wavplay_B.play();
|
||
|
|
else wavplay_B.stop();
|
||
|
|
sensor = &s_B;
|
||
|
|
sensor_touch[1] = p;
|
||
|
|
break;
|
||
|
|
case PIN_C:
|
||
|
|
if(p) wavplay_C.play();
|
||
|
|
else wavplay_C.stop();
|
||
|
|
sensor = &s_C;
|
||
|
|
sensor_touch[2] = p;
|
||
|
|
break;
|
||
|
|
case PIN_D:
|
||
|
|
if(p) wavplay_D.play();
|
||
|
|
else wavplay_D.stop();
|
||
|
|
sensor = &s_D;
|
||
|
|
sensor_touch[3] = p;
|
||
|
|
break;
|
||
|
|
case PIN_E:
|
||
|
|
if(p) wavplay_E.play();
|
||
|
|
else wavplay_E.stop();
|
||
|
|
sensor = &s_E;
|
||
|
|
sensor_touch[4] = p;
|
||
|
|
break;
|
||
|
|
case PIN_F:
|
||
|
|
if(p) wavplay_B.play();
|
||
|
|
else wavplay_B.stop();
|
||
|
|
sensor = &s_F;
|
||
|
|
sensor_touch[5] = p;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// state_synth(p, pin, sensor);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* SETUPS
|
||
|
|
------------------------*/
|
||
|
|
|
||
|
|
|
||
|
|
void setup() {
|
||
|
|
Serial.begin(57600);
|
||
|
|
|
||
|
|
setup_audio();
|
||
|
|
|
||
|
|
setup_sensors();
|
||
|
|
|
||
|
|
synth_gain(0);
|
||
|
|
wav_gain(0.75);
|
||
|
|
}
|
||
|
|
|
||
|
|
void setup_sensors() {
|
||
|
|
// baselines
|
||
|
|
s_A.baseline(50, 50);
|
||
|
|
s_B.baseline(50, 50);
|
||
|
|
s_C.baseline(50, 50);
|
||
|
|
s_D.baseline(50, 50);
|
||
|
|
s_E.baseline(50, 50);
|
||
|
|
s_F.baseline(50, 50);
|
||
|
|
|
||
|
|
// callbacks
|
||
|
|
s_A.plug_toggle_cb(toggle_signal_cb);
|
||
|
|
s_B.plug_toggle_cb(toggle_signal_cb);
|
||
|
|
s_C.plug_toggle_cb(toggle_signal_cb);
|
||
|
|
s_D.plug_toggle_cb(toggle_signal_cb);
|
||
|
|
s_E.plug_toggle_cb(toggle_signal_cb);
|
||
|
|
s_F.plug_toggle_cb(toggle_signal_cb);
|
||
|
|
}
|
||
|
|
|
||
|
|
void setup_audio() {
|
||
|
|
AudioMemory(8);
|
||
|
|
sgtl5000_1.enable();
|
||
|
|
sgtl5000_1.volume(0.5);
|
||
|
|
SPI.setMOSI(SDCARD_MOSI_PIN);
|
||
|
|
SPI.setSCK(SDCARD_SCK_PIN);
|
||
|
|
if (!(SD.begin(SDCARD_CS_PIN))) {
|
||
|
|
while (1) {
|
||
|
|
Serial.println("Unable to access the SD card");
|
||
|
|
delay(1000);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* LOOP
|
||
|
|
------------------------*/
|
||
|
|
|
||
|
|
void loop() {
|
||
|
|
|
||
|
|
s_A.update();
|
||
|
|
s_B.update();
|
||
|
|
s_C.update();
|
||
|
|
s_D.update();
|
||
|
|
s_E.update();
|
||
|
|
s_F.update();
|
||
|
|
|
||
|
|
// float synth_gain_max = 0.5;
|
||
|
|
// float synth_gain_interval_ms = 1500;
|
||
|
|
// float synth_gain_increments_ms = synth_gain_max / 1500;
|
||
|
|
// long synth_last_increment = -1;
|
||
|
|
|
||
|
|
if(synth_PIN > 0) {
|
||
|
|
int d = synth_sensor->map_range_raw(0, freq);
|
||
|
|
synth.set_detune(d);
|
||
|
|
|
||
|
|
// if(gain_up && synth_gain_v < synth_gain_max) {
|
||
|
|
// synth_gain_v += synth_gain_increments_ms;
|
||
|
|
// if(synth_gain_v > synth_gain_max)
|
||
|
|
// synth_gain_v = synth_gain_max;
|
||
|
|
// synth_gain(synth_gain_v);
|
||
|
|
|
||
|
|
// } else if(!gain_up && synth_gain_v > 0) {
|
||
|
|
// synth_gain_v -= synth_gain_increments_ms;
|
||
|
|
// if(synth_gain_v < 0) {
|
||
|
|
// synth_gain_v = 0;
|
||
|
|
// synth_sensor = NULL;
|
||
|
|
// synth_PIN = -1;
|
||
|
|
// }
|
||
|
|
// synth_gain(synth_gain_v);
|
||
|
|
// }
|
||
|
|
}
|
||
|
|
|
||
|
|
if(sensor_touch[0]) wavplay_A.update();
|
||
|
|
if(sensor_touch[1]) wavplay_B.update();
|
||
|
|
if(sensor_touch[2]) wavplay_C.update();
|
||
|
|
if(sensor_touch[3]) wavplay_D.update();
|
||
|
|
if(sensor_touch[4]) wavplay_E.update();
|
||
|
|
if(sensor_touch[5]) wavplay_B.update();
|
||
|
|
|
||
|
|
serial_plot_range(0, 100);
|
||
|
|
// serial_plot();
|
||
|
|
// serial_plot_base();
|
||
|
|
// serial_plot_range(0, 100);
|
||
|
|
|
||
|
|
delay(READ_DELAY);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* GAIN FUNCS
|
||
|
|
------------------------*/
|
||
|
|
|
||
|
|
void synth_gain(float g){
|
||
|
|
synth_mixer.gain(0, g);
|
||
|
|
synth_mixer.gain(1, g);
|
||
|
|
synth_mixer.gain(2, g);
|
||
|
|
}
|
||
|
|
|
||
|
|
void wav_gain(float g){
|
||
|
|
wav_mixer1.gain(0, g);
|
||
|
|
wav_mixer1.gain(1, g);
|
||
|
|
wav_mixer1.gain(2, g);
|
||
|
|
wav_mixer1.gain(3, g);
|
||
|
|
|
||
|
|
wav_mixer2.gain(0, g);
|
||
|
|
wav_mixer2.gain(1, g);
|
||
|
|
wav_mixer2.gain(2, g);
|
||
|
|
wav_mixer2.gain(3, g);
|
||
|
|
|
||
|
|
// shoudl add wav_e + f but whatever
|
||
|
|
}
|
||
|
|
|
||
|
|
/*-----------------------
|
||
|
|
* PLOT FUNCS
|
||
|
|
------------------------*/
|
||
|
|
|
||
|
|
void serial_plot_range(int min_v, int max_v) {
|
||
|
|
Serial.print(s_A.map_range(min_v, max_v)); Serial.print(" ");
|
||
|
|
Serial.print(s_B.map_range(min_v, max_v)); Serial.print(" ");
|
||
|
|
Serial.print(s_C.map_range(min_v, max_v)); Serial.print(" ");
|
||
|
|
Serial.print(s_D.map_range(min_v, max_v)); Serial.print(" ");
|
||
|
|
Serial.print(s_E.map_range(min_v, max_v)); Serial.print(" ");
|
||
|
|
Serial.print(s_F.map_range(min_v, max_v)); Serial.print(" ");
|
||
|
|
Serial.println("");
|
||
|
|
}
|
||
|
|
|
||
|
|
void serial_plot_base(){
|
||
|
|
Serial.print(s_A.base); Serial.print(" ");
|
||
|
|
Serial.print(s_B.base); Serial.print(" ");
|
||
|
|
Serial.print(s_C.base); Serial.print(" ");
|
||
|
|
Serial.print(s_D.base); Serial.print(" ");
|
||
|
|
Serial.print(s_E.base); Serial.print(" ");
|
||
|
|
Serial.print(s_F.base); Serial.print(" ");
|
||
|
|
Serial.println("");
|
||
|
|
}
|
||
|
|
|
||
|
|
void serial_plot() {
|
||
|
|
Serial.print(s_A.v); Serial.print(" ");
|
||
|
|
Serial.print(s_B.v); Serial.print(" ");
|
||
|
|
Serial.print(s_C.v); Serial.print(" ");
|
||
|
|
Serial.print(s_D.v); Serial.print(" ");
|
||
|
|
Serial.print(s_E.v); Serial.print(" ");
|
||
|
|
Serial.print(s_F.v); Serial.print(" ");
|
||
|
|
Serial.println("");
|
||
|
|
}
|
||
|
|
|
||
|
|
void serial_plot_dv() {
|
||
|
|
Serial.print(s_A.dv); Serial.print(" ");
|
||
|
|
Serial.print(s_B.dv); Serial.print(" ");
|
||
|
|
Serial.print(s_C.dv); Serial.print(" ");
|
||
|
|
Serial.print(s_D.dv); Serial.print(" ");
|
||
|
|
Serial.print(s_E.dv); Serial.print(" ");
|
||
|
|
Serial.print(s_F.dv); Serial.print(" ");
|
||
|
|
Serial.println("");
|
||
|
|
}
|