diff options
-rw-r--r-- | arduino/fht_test.ino | 68 | ||||
-rw-r--r-- | museduino/museduino.ino | 272 |
2 files changed, 272 insertions, 68 deletions
diff --git a/arduino/fht_test.ino b/arduino/fht_test.ino deleted file mode 100644 index 0e2f83c..0000000 --- a/arduino/fht_test.ino +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
1 | |||
2 | // FHT Options | ||
3 | #define FHT_N 256 | ||
4 | #define SCALE 256 | ||
5 | #define WINDOW 1 | ||
6 | #define REORDER 1 | ||
7 | #define LOG_OUT 1 | ||
8 | #define LIN_OUT 0 | ||
9 | #define LIN_OUT8 0 | ||
10 | #define OCTAVE 0 | ||
11 | #define OCT_NORM 0 | ||
12 | |||
13 | #define BINS 128 | ||
14 | |||
15 | #include <FHT.h> | ||
16 | |||
17 | void aquire_data() { | ||
18 | noInterrupts(); | ||
19 | |||
20 | for (int i = 0; i < FHT_N; i++) { | ||
21 | while(!(ADCSRA & 0x10)); // wait for adc to be ready | ||
22 | ADCSRA = 0xf5; // restart adc | ||
23 | byte m = ADCL; // fetch adc data | ||
24 | byte j = ADCH; | ||
25 | int k = (j << 8) | m; // form into an int | ||
26 | k -= 0x0200; // form into a signed int | ||
27 | k <<= 6; // form into a 16b signed int | ||
28 | fht_input[i] = k; // put real data into bins | ||
29 | } | ||
30 | |||
31 | interrupts(); | ||
32 | } | ||
33 | |||
34 | void crunch_data() { | ||
35 | fht_window(); | ||
36 | fht_reorder(); | ||
37 | fht_run(); | ||
38 | //fht_mag_octave(); | ||
39 | fht_mag_log(); | ||
40 | } | ||
41 | |||
42 | void setup() { | ||
43 | |||
44 | Serial.begin(115200); | ||
45 | |||
46 | TIMSK0 = 0; // turn off timer0 for lower jitter | ||
47 | ADCSRA = 0xe5; // set the adc to free running mode | ||
48 | ADMUX = 0x40; // use adc0 | ||
49 | DIDR0 = 0x01; // turn off the digital input for adc0 | ||
50 | |||
51 | } | ||
52 | |||
53 | char buf[2550] = ""; | ||
54 | |||
55 | void loop() { | ||
56 | aquire_data(); | ||
57 | crunch_data(); | ||
58 | |||
59 | for (int i = 0; i < BINS; i++) { | ||
60 | Serial.print(fht_log_out[i]); | ||
61 | Serial.print(' '); | ||
62 | } | ||
63 | |||
64 | Serial.print('\n'); | ||
65 | |||
66 | delay(10000); | ||
67 | } | ||
68 | |||
diff --git a/museduino/museduino.ino b/museduino/museduino.ino new file mode 100644 index 0000000..b20e4ab --- /dev/null +++ b/museduino/museduino.ino | |||
@@ -0,0 +1,272 @@ | |||
1 | |||
2 | /********************* | ||
3 | |||
4 | EIG-2006 - Projet Arduino | ||
5 | |||
6 | Museduino | ||
7 | |||
8 | TRAN-GIRARD Pacien | ||
9 | NICOLE RĂ©mi | ||
10 | |||
11 | **********************/ | ||
12 | |||
13 | |||
14 | /***** Parameters *****/ | ||
15 | |||
16 | // FHT options | ||
17 | #define FHT_N 256 | ||
18 | #define SCALE 256 | ||
19 | |||
20 | #define WINDOW 1 | ||
21 | #define REORDER 1 | ||
22 | |||
23 | #define LOG_OUT 0 | ||
24 | #define LIN_OUT 0 | ||
25 | #define LIN_OUT8 1 | ||
26 | |||
27 | #define OCTAVE 0 | ||
28 | #define OCT_NORM 0 | ||
29 | |||
30 | // Data aquisition options | ||
31 | #define USE_FAST_AQUISITION 0 | ||
32 | #define PRESCALE_FACTOR 256 | ||
33 | #define DUMMY_SAMPLES 1 | ||
34 | #define WAIT_CYCLES 0 | ||
35 | |||
36 | // Data bins | ||
37 | #define BINS 128 // FHT_N /2 | ||
38 | #define OCTAVES 8 // log2(FHT_N) | ||
39 | |||
40 | // Note matching options | ||
41 | #define IGNORE_FIRST_BINS 2 | ||
42 | #define AMPLITUDE_THRESHOLD 10 | ||
43 | |||
44 | // MIDI output | ||
45 | #define MIDI_INSTRUMENT 103 | ||
46 | #define MIDI_VOLUME 120 | ||
47 | #define MIDI_RESET_PIN 4 | ||
48 | |||
49 | |||
50 | /***** System setup *****/ | ||
51 | |||
52 | #include <FHT.h> | ||
53 | #include <SoftwareSerial.h> | ||
54 | |||
55 | SoftwareSerial shieldSerial(2, 3); // RX, TX | ||
56 | |||
57 | void setup_midi_shield() { | ||
58 | // setup soft serial link for MIDI control | ||
59 | shieldSerial.begin(31250); | ||
60 | |||
61 | // reset the VS1053 | ||
62 | pinMode(MIDI_RESET_PIN, OUTPUT); | ||
63 | |||
64 | digitalWrite(MIDI_RESET_PIN, LOW); | ||
65 | delay(100); | ||
66 | |||
67 | digitalWrite(MIDI_RESET_PIN, HIGH); | ||
68 | delay(100); | ||
69 | |||
70 | // set volume and instrument | ||
71 | talkMIDI(0xB0, 0x07, MIDI_VOLUME); | ||
72 | talkMIDI(0xC0, MIDI_INSTRUMENT, 0); | ||
73 | } | ||
74 | |||
75 | void setup_serial_link() { | ||
76 | Serial.begin(115200); | ||
77 | } | ||
78 | |||
79 | void setup_adc() { | ||
80 | #if USE_FAST_AQUISITION == 1 | ||
81 | ADCSRA = 0xe5; // set the adc to free running mode | ||
82 | ADMUX = 0x40; // use adc0 | ||
83 | DIDR0 = 0x01; // turn off the digital input for adc0 | ||
84 | #endif | ||
85 | } | ||
86 | |||
87 | void setup() { | ||
88 | setup_serial_link(); | ||
89 | setup_midi_shield(); | ||
90 | setup_adc(); | ||
91 | } | ||
92 | |||
93 | |||
94 | /***** Data transforms *****/ | ||
95 | |||
96 | void run_fht() { | ||
97 | #if WINDOW == 1 | ||
98 | fht_window(); | ||
99 | #endif | ||
100 | |||
101 | #if REORDER == 1 | ||
102 | fht_reorder(); | ||
103 | #endif | ||
104 | |||
105 | fht_run(); | ||
106 | } | ||
107 | |||
108 | void mag_fht() { | ||
109 | #if LOG_OUT == 1 | ||
110 | fht_mag_log(); | ||
111 | #elif LIN_OUT == 1 | ||
112 | fht_mag_lin(); | ||
113 | #elif LIN_OUT8 == 1 | ||
114 | fht_mag_lin8(); | ||
115 | #endif | ||
116 | } | ||
117 | |||
118 | int find_max_index() { | ||
119 | #if LOG_OUT == 1 | ||
120 | uint8_t* data = fht_log_out; | ||
121 | uint8_t m = 0; | ||
122 | #elif LIN_OUT == 1 | ||
123 | uint16_t* data = fht_lin_out; | ||
124 | uint16_t m = 0; | ||
125 | #elif LIN_OUT8 == 1 | ||
126 | uint8_t* data = fht_lin_out8; | ||
127 | uint8_t m = 0; | ||
128 | #endif | ||
129 | |||
130 | int k = 0; | ||
131 | for (int i = IGNORE_FIRST_BINS; i < BINS; i++) { | ||
132 | if (data[i] > m && data[i] >= AMPLITUDE_THRESHOLD) { | ||
133 | m = data[i]; | ||
134 | k = i; | ||
135 | } | ||
136 | } | ||
137 | return k; | ||
138 | } | ||
139 | |||
140 | int find_midi_note(float freq) { | ||
141 | float delta = 3.4028235E+38; // max float value | ||
142 | int note = 0; | ||
143 | for (int i = 0; i < 120; i++) { // exec time must be constant | ||
144 | float new_delta = abs(calc_midi_note_freq(i) - freq); | ||
145 | if (new_delta < delta) { | ||
146 | delta = new_delta; | ||
147 | note = i; | ||
148 | } | ||
149 | } | ||
150 | return note; | ||
151 | } | ||
152 | |||
153 | float calc_bin_frequency(int k) { | ||
154 | #if DUMMY_SAMPLES == 0 | ||
155 | return (float(k) - 0.0616541) / 0.0287293; | ||
156 | #elif DUMMY_SAMPLES == 1 | ||
157 | return (float(k) - 0.00827068) / 0.0573534; | ||
158 | #endif | ||
159 | } | ||
160 | |||
161 | float calc_midi_note_freq(int midi_note) { | ||
162 | return 8.1757989156 * pow(2, float(midi_note)/12); | ||
163 | } | ||
164 | |||
165 | |||
166 | /***** I/O wrappers *****/ | ||
167 | |||
168 | void talkMIDI(byte cmd, byte data1, byte data2) { | ||
169 | shieldSerial.write(cmd); | ||
170 | shieldSerial.write(data1); | ||
171 | |||
172 | // Some commands only have one data byte. | ||
173 | // All cmds less than 0xBn have 2 data bytes. | ||
174 | // (sort of: http://253.ccarh.org/handout/midiprotocol/) | ||
175 | if( (cmd & 0xF0) <= 0xB0) | ||
176 | shieldSerial.write(data2); | ||
177 | } | ||
178 | |||
179 | void noteOn(byte channel, byte note, byte attack_velocity) { | ||
180 | talkMIDI((0x90 | channel), note, attack_velocity); | ||
181 | } | ||
182 | |||
183 | void noteOff(byte channel, byte note, byte release_velocity) { | ||
184 | talkMIDI((0x80 | channel), note, release_velocity); | ||
185 | } | ||
186 | |||
187 | void aquire_data() { | ||
188 | noInterrupts(); | ||
189 | |||
190 | #if USE_FAST_AQUISITION == 1 | ||
191 | |||
192< |