oxford
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
// #include <Arduino.h>
|
||||
#include <FastTouch.h>
|
||||
|
||||
static float alpha = 0.2;
|
||||
static int baseline_fluctuation = 5;
|
||||
static int baseline_fluctuation_hits = 100;
|
||||
static int max_s = 60;
|
||||
|
||||
typedef void(*toggle_cb)(bool, int);
|
||||
|
||||
struct SENSOR_t {
|
||||
|
||||
int PIN, base, num_base, max_c, v, prev, raw, cutoff_s;
|
||||
int dv;
|
||||
unsigned long timestamp_calib;
|
||||
toggle_cb fn_toggle_cb;
|
||||
bool call_toggle = false;
|
||||
|
||||
SENSOR_t(const int& pin, int cutoff) {
|
||||
PIN = pin;
|
||||
max_c = max_s;
|
||||
num_base = 0;
|
||||
cutoff_s = cutoff;
|
||||
fn_toggle_cb = NULL;
|
||||
}
|
||||
|
||||
void plug_toggle_cb(toggle_cb fn) {
|
||||
fn_toggle_cb = fn;
|
||||
}
|
||||
|
||||
void baseline(int n, int d) {
|
||||
float cum = 0;
|
||||
for (int i = 0; i < n; i++){
|
||||
update(false, false);
|
||||
if(abs(dv) < baseline_fluctuation){
|
||||
cum += v;
|
||||
}
|
||||
delay(d);
|
||||
|
||||
}
|
||||
base = (int)floor(cum / n);
|
||||
}
|
||||
|
||||
void calibrate() {
|
||||
// if(abs(dv) < baseline_fluctuation) {
|
||||
// num_base++;
|
||||
// if (num_base > baseline_fluctuation_hits)
|
||||
// base = (int) (alpha * (float)v + (1.0 - alpha) * (float)base);
|
||||
// } else {
|
||||
// num_base = 0;
|
||||
// }
|
||||
if(v > max_c) max_c = v;
|
||||
timestamp_calib = millis();
|
||||
}
|
||||
|
||||
void update(bool calib = true, bool filt = true) {
|
||||
raw = fastTouchRead(PIN);
|
||||
if(filt)
|
||||
v = filter(raw);
|
||||
else
|
||||
v = raw;
|
||||
dv = v - prev;
|
||||
if(calib) calibrate();
|
||||
|
||||
if(fn_toggle_cb) {
|
||||
int m_v = map(v, base, max_c, 0, 100);
|
||||
int m_prev = map(prev, base, max_c, 0, 100);
|
||||
if(m_prev < cutoff_s && m_v >= cutoff_s)
|
||||
fn_toggle_cb(true, PIN);
|
||||
else if(m_prev > cutoff_s && m_v <= cutoff_s)
|
||||
fn_toggle_cb(false, PIN);
|
||||
}
|
||||
|
||||
prev = v;
|
||||
|
||||
}
|
||||
|
||||
int map_range(int min_v, int max_v) {
|
||||
return map(v, base, max_c, min_v, max_v);
|
||||
}
|
||||
|
||||
int map_range_raw(int min_v, int max_v) {
|
||||
return map(raw, base, max_c, min_v, max_v);
|
||||
}
|
||||
|
||||
int filter(int n) {
|
||||
return (int) (alpha * n + (1.0 - alpha) * prev);
|
||||
}
|
||||
|
||||
bool touch() {
|
||||
return (v > cutoff_s);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
static float alpha = 0.2;
|
||||
static int baseline_fluctuation = 75;
|
||||
static int max_s = 3000;
|
||||
|
||||
typedef struct SENSOR_t {
|
||||
|
||||
int PIN, base, num_base, max_c, v, prev;
|
||||
int dv;
|
||||
unsigned long timestamp_calib;
|
||||
|
||||
SENSOR_t(int& pin) {
|
||||
PIN = pin;
|
||||
max_c = max_s;
|
||||
num_base = 0;
|
||||
}
|
||||
|
||||
void baseline(int n, int d) {
|
||||
int cum = 0;
|
||||
for (int i = 0; i < n; i++){
|
||||
update(false, false);
|
||||
if(abs(dv) < baseline_fluctuation){
|
||||
cum += v;
|
||||
}
|
||||
delay(d);
|
||||
}
|
||||
base = (int)(cum / n);
|
||||
}
|
||||
|
||||
void calibrate() {
|
||||
if(abs(dv) < baseline_fluctuation) {
|
||||
num_base++;
|
||||
if (num_base > 25)
|
||||
base = (int) (alpha * (float)v + (1.0 - alpha) * (float)base);
|
||||
} else {
|
||||
num_base = 0;
|
||||
}
|
||||
if(v > max_c) max_c = v;
|
||||
timestamp_calib = millis();
|
||||
}
|
||||
|
||||
void update(bool calib = true, bool filt = true) {
|
||||
int d = touchRead(PIN);
|
||||
if(filt)
|
||||
v = filter(d);
|
||||
else
|
||||
v = d;
|
||||
dv = v - prev;
|
||||
prev = v;
|
||||
if(calib) calibrate();
|
||||
}
|
||||
|
||||
int map_range(int min_v, int max_v) {
|
||||
return map(v, base, max_c, min_v, max_v);
|
||||
}
|
||||
|
||||
int filter(int n) {
|
||||
return (int) (alpha * n + (1.0 - alpha) * prev);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,135 @@
|
||||
#pragma once
|
||||
|
||||
#include <Audio.h>
|
||||
#include "WORDS.h"
|
||||
|
||||
static int time_interval_random_start = 2000;
|
||||
|
||||
typedef void(*synth_toggle_cb)(bool, int);
|
||||
|
||||
void _random_wav(AudioPlaySdWav* wav, E_WORDS* e_words, int MAX_WORD) {
|
||||
int w = (int)random(0, MAX_WORD);
|
||||
wav->play(words[e_words[w]]);
|
||||
}
|
||||
|
||||
enum WAVPLAY_STATE {
|
||||
LATIN, ENGLISH, RANDOM, NONE
|
||||
};
|
||||
|
||||
typedef struct WAVPLAY_t {
|
||||
|
||||
int pin;
|
||||
AudioPlaySdWav* wav;
|
||||
E_PHRASES en_phrase;
|
||||
E_PHRASES la_phrase;
|
||||
E_WORDS* random_words;
|
||||
int nbr_random_words;
|
||||
synth_toggle_cb synth_toggle_func = NULL;
|
||||
|
||||
long random_start;
|
||||
|
||||
WAVPLAY_STATE state;
|
||||
|
||||
WAVPLAY_t(const int p, AudioPlaySdWav* w, E_PHRASES en, E_PHRASES la, E_WORDS* wds, int nbr_wds, synth_toggle_cb synth_func) {
|
||||
pin = p;
|
||||
wav = w;
|
||||
en_phrase = en;
|
||||
la_phrase = la;
|
||||
random_words = wds;
|
||||
nbr_random_words = nbr_wds;
|
||||
state = NONE;
|
||||
synth_toggle_func = synth_func;
|
||||
}
|
||||
|
||||
void play(){
|
||||
|
||||
switch(state) {
|
||||
case NONE:
|
||||
wav->play(phrases[la_phrase]);
|
||||
delay(25);
|
||||
state = LATIN;
|
||||
// Serial.println("state none > latin");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void stop(){
|
||||
wav->stop();
|
||||
if(state == RANDOM) synth_toggle_func(false, pin);
|
||||
state = NONE;
|
||||
}
|
||||
|
||||
void update(){
|
||||
|
||||
if(state == NONE) return;
|
||||
|
||||
if(wav->isPlaying()) {
|
||||
// Serial.println("...");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(state) {
|
||||
case LATIN:
|
||||
wav->play(phrases[en_phrase]);
|
||||
state = ENGLISH;
|
||||
// Serial.println("state latin > english");
|
||||
break;
|
||||
case ENGLISH:
|
||||
// _random_wav(wav, random_words, nbr_random_words);
|
||||
state = RANDOM;
|
||||
random_start = millis();
|
||||
synth_toggle_func(true, pin);
|
||||
// Serial.println("state english > random");
|
||||
break;
|
||||
case RANDOM:
|
||||
if(millis() - random_start > time_interval_random_start) {
|
||||
_random_wav(wav, random_words, nbr_random_words);
|
||||
// Serial.println("random");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef struct DETUNE_t {
|
||||
|
||||
AudioSynthWaveformSine sine3;
|
||||
AudioSynthWaveformSine sine2;
|
||||
AudioSynthWaveformSine sine1;
|
||||
|
||||
int base_freq = 0;
|
||||
|
||||
DETUNE_t(int freq) {
|
||||
set_frequency(freq);
|
||||
}
|
||||
|
||||
void set_frequency(int freq) {
|
||||
sine1.frequency(freq);
|
||||
sine2.frequency(freq);
|
||||
sine3.frequency(freq);
|
||||
base_freq = freq;
|
||||
}
|
||||
|
||||
void set_detune(float detune) {
|
||||
int det_mid = (int)(detune/2.0);
|
||||
sine2.frequency(base_freq + det_mid);
|
||||
|
||||
if(detune > 100)
|
||||
sine3.frequency(base_freq - det_mid);
|
||||
else
|
||||
sine3.frequency(base_freq - 2 * det_mid);
|
||||
|
||||
int r = (int)random(0, 100);
|
||||
if(r > 33)
|
||||
sine1.frequency(det_mid/2);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
static const char* const words[] = {
|
||||
"E1.read.wav",
|
||||
"E2.old_tales.wav",
|
||||
"E3.traversed_provinces.wav",
|
||||
"E4.crossed_seas.wav",
|
||||
"E5.visited.wav",
|
||||
"E6.new_peoples.wav",
|
||||
"E7.to_see.wav",
|
||||
"E8.face_to_face.wav",
|
||||
"E9.persons.wav",
|
||||
"E10.they_only.wav",
|
||||
"E11.knew.wav",
|
||||
"E12.from.wav",
|
||||
"E13.books.wav",
|
||||
"L0.legimus.wav",
|
||||
"L1.in_veteribus.wav",
|
||||
"L2.historiis.wav",
|
||||
"L3.quosdam_lustrasse_provincias.wav",
|
||||
"L4.novos.wav",
|
||||
"L5.adiisse_populos.wav",
|
||||
"L6.maria_transisse.wav",
|
||||
"L7.ut_eos.wav",
|
||||
"L8.quos.wav",
|
||||
"L9.ex_libris.wav",
|
||||
"L10.noverant.wav",
|
||||
"L11.coram.wav",
|
||||
"L12.quoque_viderent.wav",
|
||||
"ENGLISH.wav",
|
||||
"LATIN.wav"
|
||||
};
|
||||
|
||||
enum E_WORDS {
|
||||
E1,E2,E3,E4,E5,E6,E7,E8,E9,E10,E11,E12,E13,L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,EN,LAT
|
||||
};
|
||||
|
||||
|
||||
static const char* const phrases[] = {
|
||||
|
||||
"EA.we_read_in_old_tales.wav",
|
||||
"EB.that_men_traversed_provinces.wav",
|
||||
"EC.crossed_seas_and_visited_new_peoples.wav",
|
||||
"ED.to_see_face_to_face_persons.wav",
|
||||
"EE.whom_they_only_knew_from_books.wav",
|
||||
"LA.legimus_in_vereribus_historiis.wav",
|
||||
"LB.quodam_lustrasse_provincias.wav",
|
||||
"LC.novos_adiisse_populos_maria_transisse.wav",
|
||||
"LD.ut_eos_quos_ex_libris_noverant.wav",
|
||||
"LE.coram_quoque_viderent.wav"
|
||||
};
|
||||
|
||||
enum E_PHRASES {
|
||||
EA, EB, EC, ED, EE, LA, LB, LC, LD, LE
|
||||
};
|
||||
Reference in New Issue
Block a user