aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Humbert <jack.humb@gmail.com>2016-01-20 00:06:52 -0500
committerJack Humbert <jack.humb@gmail.com>2016-01-20 00:06:52 -0500
commiteb61700912f1713ba27d34c23d7f07be66ee6513 (patch)
tree7781c85a3e67a3af34a31a09d6736f07b6a492fe
parent6e3c36360ed291b9ca2bd014571236308a933d0c (diff)
downloadqmk_firmware-eb61700912f1713ba27d34c23d7f07be66ee6513.tar.gz
qmk_firmware-eb61700912f1713ba27d34c23d7f07be66ee6513.zip
better integrations
-rw-r--r--keyboard/planck/Makefile7
-rw-r--r--keyboard/planck/keymaps/keymap_default.c8
-rw-r--r--keyboard/planck/keymaps/keymap_lock.c60
-rw-r--r--keyboard/planck/planck.h4
-rw-r--r--quantum/audio.c362
-rw-r--r--quantum/audio.h (renamed from quantum/beeps.h)4
-rw-r--r--quantum/beeps.c265
-rw-r--r--quantum/keymap_midi.c4
-rw-r--r--quantum/quantum.mk7
-rw-r--r--tmk_core/common.mk3
-rw-r--r--tmk_core/protocol/lufa/lufa.c7
11 files changed, 402 insertions, 329 deletions
diff --git a/keyboard/planck/Makefile b/keyboard/planck/Makefile
index fdf8c1640..7b06446d7 100644
--- a/keyboard/planck/Makefile
+++ b/keyboard/planck/Makefile
@@ -50,8 +50,7 @@ TMK_DIR = ../../tmk_core
50TARGET_DIR = . 50TARGET_DIR = .
51 51
52# # project specific files 52# # project specific files
53SRC = planck.c \ 53SRC = planck.c
54 backlight.c
55 54
56ifdef KEYMAP 55ifdef KEYMAP
57 SRC := keymaps/keymap_$(KEYMAP).c $(SRC) 56 SRC := keymaps/keymap_$(KEYMAP).c $(SRC)
@@ -124,9 +123,13 @@ COMMAND_ENABLE = yes # Commands for debug and configuration
124# NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work 123# NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
125# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality 124# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
126MIDI_ENABLE = YES # MIDI controls 125MIDI_ENABLE = YES # MIDI controls
126AUDIO_ENABLE = YES # Audio output on port C6
127# UNICODE_ENABLE = YES # Unicode 127# UNICODE_ENABLE = YES # Unicode
128# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID 128# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID
129 129
130ifdef BACKLIGHT_ENABLE
131 SRC += backlight.c
132endif
130 133
131# Optimize size but this may cause error "relocation truncated to fit" 134# Optimize size but this may cause error "relocation truncated to fit"
132#EXTRALDFLAGS = -Wl,--relax 135#EXTRALDFLAGS = -Wl,--relax
diff --git a/keyboard/planck/keymaps/keymap_default.c b/keyboard/planck/keymaps/keymap_default.c
index 49670dafd..a9c2a0681 100644
--- a/keyboard/planck/keymaps/keymap_default.c
+++ b/keyboard/planck/keymaps/keymap_default.c
@@ -2,7 +2,9 @@
2// this is the style you want to emulate. 2// this is the style you want to emulate.
3 3
4#include "planck.h" 4#include "planck.h"
5#include "backlight.h" 5#ifdef BACKLIGHT_ENABLE
6 #include "backlight.h"
7#endif
6 8
7// Each layer gets a name for readability, which is then used in the keymap matrix below. 9// Each layer gets a name for readability, which is then used in the keymap matrix below.
8// The underscores don't mean anything - you can have a layer called STUFF or any other name. 10// The underscores don't mean anything - you can have a layer called STUFF or any other name.
@@ -58,7 +60,9 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
58 case 0: 60 case 0:
59 if (record->event.pressed) { 61 if (record->event.pressed) {
60 register_code(KC_RSFT); 62 register_code(KC_RSFT);
61 backlight_step(); 63 #ifdef BACKLIGHT_ENABLE
64 backlight_step();
65 #endif
62 } else { 66 } else {
63 unregister_code(KC_RSFT); 67 unregister_code(KC_RSFT);
64 } 68 }
diff --git a/keyboard/planck/keymaps/keymap_lock.c b/keyboard/planck/keymaps/keymap_lock.c
index 7a99b57c9..0deb212cc 100644
--- a/keyboard/planck/keymaps/keymap_lock.c
+++ b/keyboard/planck/keymaps/keymap_lock.c
@@ -1,8 +1,10 @@
1#include "keymap_common.h" 1#include "keymap_common.h"
2// #include "backlight.h" 2#ifdef BACKLIGHT_ENABLE
3 #include "backlight.h"
4#endif
3#include "action_layer.h" 5#include "action_layer.h"
4#include "keymap_midi.h" 6#include "keymap_midi.h"
5#include "beeps.h" 7#include "audio.h"
6#include <avr/boot.h> 8#include <avr/boot.h>
7 9
8const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 10const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@@ -86,7 +88,9 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
86 play_notes(&walk_up, 3, false); 88 play_notes(&walk_up, 3, false);
87 // play_note(440, 20); 89 // play_note(440, 20);
88 // register_code(KC_RSFT); 90 // register_code(KC_RSFT);
89 // backlight_set(BACKLIGHT_LEVELS); 91 #ifdef BACKLIGHT_ENABLE
92 backlight_set(BACKLIGHT_LEVELS);
93 #endif
90 default_layer_and(0); 94 default_layer_and(0);
91 default_layer_or((1<<5)); 95 default_layer_or((1<<5));
92 96
@@ -118,17 +122,14 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
118 // register_code(hextokeycode((lock & 0x0F))); 122 // register_code(hextokeycode((lock & 0x0F)));
119 // unregister_code(hextokeycode((lock & 0x0F))); 123 // unregister_code(hextokeycode((lock & 0x0F)));
120 124
121 // note(0+12, 20);
122 // note(0+24, 20);
123 } else { 125 } else {
124 unregister_code(KC_RSFT); 126 unregister_code(KC_RSFT);
125 play_notes(&walk_dn, 3, false); 127 play_notes(&walk_dn, 3, false);
126 // backlight_set(0); 128 #ifdef BACKLIGHT_ENABLE
129 backlight_set(0);
130 #endif
127 default_layer_and(0); 131 default_layer_and(0);
128 default_layer_or(0); 132 default_layer_or(0);
129 // note(0+24, 20);
130 // note(0, 20);
131 // play_note(4, 20);
132 } 133 }
133 break; 134 break;
134 } 135 }
@@ -149,44 +150,5 @@ float start_up[][2] = {
149 150
150void * matrix_init_user(void) { 151void * matrix_init_user(void) {
151 init_notes(); 152 init_notes();
152
153 play_notes(&start_up, 9, false); 153 play_notes(&start_up, 9, false);
154 // play_note(((double)261.6*3)*pow(2.0,(36)/12.0), 0xF); 154} \ No newline at end of file
155 // _delay_ms(50);
156
157 // play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
158 // _delay_ms(25);
159 // stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
160
161 // play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
162 // _delay_ms(25);
163 // stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
164
165
166 // stop_note(((double)261.6*3)*pow(2.0,(36)/12.0));
167
168
169 // play_note(((double)261.6*3)*pow(2.0,(62)/12.0), 0xF);
170 // _delay_ms(50);
171 // stop_note(((double)261.6*3)*pow(2.0,(62)/12.0));
172
173
174 // play_note(((double)261.6*3)*pow(2.0,(64)/12.0), 0xF);
175 // _delay_ms(50);
176 // stop_note(((double)261.6*3)*pow(2.0,(64)/12.0));
177
178}
179
180
181// void * matrix_scan_user(void) {
182// if (layer_state & (1<<2)) {
183// if (!playing_notes)
184// play_notes(&start_up, 9, true);
185// } else if (layer_state & (1<<3)) {
186// if (!playing_notes)
187// play_notes(&start_up, 9, true);
188// } else {
189// if (playing_notes)
190// stop_all_notes();
191// }
192// } \ No newline at end of file
diff --git a/keyboard/planck/planck.h b/keyboard/planck/planck.h
index 32c08f3b0..e775ea7c6 100644
--- a/keyboard/planck/planck.h
+++ b/keyboard/planck/planck.h
@@ -3,7 +3,9 @@
3 3
4#include "matrix.h" 4#include "matrix.h"
5#include "keymap_common.h" 5#include "keymap_common.h"
6// #include "backlight.h" 6#ifdef BACKLIGHT_ENABLE
7 #include "backlight.h"
8#endif
7#include <stddef.h> 9#include <stddef.h>
8#ifdef MIDI_ENABLE 10#ifdef MIDI_ENABLE
9 #include <keymap_midi.h> 11 #include <keymap_midi.h>
diff --git a/quantum/audio.c b/quantum/audio.c
new file mode 100644
index 000000000..3a3a1a491
--- /dev/null
+++ b/quantum/audio.c
@@ -0,0 +1,362 @@
1#include <stdio.h>
2#include <string.h>
3#include <math.h>
4#include <avr/pgmspace.h>
5#include <avr/interrupt.h>
6#include <avr/io.h>
7
8#include "audio.h"
9#include "keymap_common.h"
10
11#define PI 3.14159265
12
13// #define PWM_AUDIO
14
15#ifdef PWM_AUDIO
16 #include "wave.h"
17 #define SAMPLE_DIVIDER 39
18 #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048)
19 // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
20#endif
21
22void delay_us(int count) {
23 while(count--) {
24 _delay_us(1);
25 }
26}
27
28int voices = 0;
29int voice_place = 0;
30double frequency = 0;
31int volume = 0;
32long position = 0;
33
34double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
35int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
36bool sliding = false;
37
38int max = 0xFF;
39float sum = 0;
40int value = 128;
41float place = 0;
42float places[8] = {0, 0, 0, 0, 0, 0, 0, 0};
43
44uint16_t place_int = 0;
45bool repeat = true;
46uint8_t * sample;
47uint16_t sample_length = 0;
48
49
50bool notes = false;
51bool note = false;
52float note_frequency = 0;
53float note_length = 0;
54uint16_t note_position = 0;
55float (* notes_pointer)[][2];
56uint8_t notes_length;
57bool notes_repeat;
58uint8_t current_note = 0;
59
60void stop_all_notes() {
61 voices = 0;
62 #ifdef PWM_AUDIO
63 TIMSK3 &= ~_BV(OCIE3A);
64 #else
65 TIMSK3 &= ~_BV(OCIE3A);
66 TCCR3A &= ~_BV(COM3A1);
67 #endif
68 notes = false;
69 note = false;
70 frequency = 0;
71 volume = 0;
72
73 for (int i = 0; i < 8; i++) {
74 frequencies[i] = 0;
75 volumes[i] = 0;
76 }
77}
78
79void stop_note(double freq) {
80 #ifdef PWM_AUDIO
81 freq = freq / SAMPLE_RATE;
82 #endif
83 for (int i = 7; i >= 0; i--) {
84 if (frequencies[i] == freq) {
85 frequencies[i] = 0;
86 volumes[i] = 0;
87 for (int j = i; (j < 7); j++) {
88 frequencies[j] = frequencies[j+1];
89 frequencies[j+1] = 0;
90 volumes[j] = volumes[j+1];
91 volumes[j+1] = 0;
92 }
93 }
94 }
95 voices--;
96 if (voices < 0)
97 voices = 0;
98 if (voices == 0) {
99 #ifdef PWM_AUDIO
100 TIMSK3 &= ~_BV(OCIE3A);
101 #else
102 TIMSK3 &= ~_BV(OCIE3A);
103 TCCR3A &= ~_BV(COM3A1);
104 #endif
105 frequency = 0;
106 volume = 0;
107 note = false;
108 } else {
109 double freq = frequencies[voices - 1];
110 int vol = volumes[voices - 1];
111 double starting_f = frequency;
112 if (frequency < freq) {
113 sliding = true;
114 for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) {
115 frequency = f;
116 }
117 sliding = false;
118 } else if (frequency > freq) {
119 sliding = true;
120 for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) {
121 frequency = f;
122 }
123 sliding = false;
124 }
125 frequency = freq;
126 volume = vol;
127 }
128}
129
130void init_notes() {
131
132 #ifdef PWM_AUDIO
133 PLLFRQ = _BV(PDIV2);
134 PLLCSR = _BV(PLLE);
135 while(!(PLLCSR & _BV(PLOCK)));
136 PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
137
138 /* Init a fast PWM on Timer4 */
139 TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
140 TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
141 OCR4A = 0;
142
143 /* Enable the OC4A output */
144 DDRC |= _BV(PORTC6);
145
146 TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
147
148 TCCR3A = 0x0; // Options not needed
149 TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
150 OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
151 #else
152 DDRC |= _BV(PORTC6);
153
154 TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
155
156 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
157 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
158 #endif
159}
160
161
162ISR(TIMER3_COMPA_vect) {
163
164 if (note) {
165 #ifdef PWM_AUDIO
166 if (voices == 1) {
167 // SINE
168 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2;
169
170 // SQUARE
171 // if (((int)place) >= 1024){
172 // OCR4A = 0xFF >> 2;
173 // } else {
174 // OCR4A = 0x00;
175 // }
176
177 // SAWTOOTH
178 // OCR4A = (int)place / 4;
179
180 // TRIANGLE
181 // if (((int)place) >= 1024) {
182 // OCR4A = (int)place / 2;
183 // } else {
184 // OCR4A = 2048 - (int)place / 2;
185 // }
186
187 place += frequency;
188
189 if (place >= SINE_LENGTH)
190 place -= SINE_LENGTH;
191
192 } else {
193 int sum = 0;
194 for (int i = 0; i < voices; i++) {
195 // SINE
196 sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2;
197
198 // SQUARE
199 // if (((int)places[i]) >= 1024){
200 // sum += 0xFF >> 2;
201 // } else {
202 // sum += 0x00;
203 // }
204
205 places[i] += frequencies[i];
206
207 if (places[i] >= SINE_LENGTH)
208 places[i] -= SINE_LENGTH;
209 }
210 OCR4A = sum;
211 }
212 #else
213 if (frequency > 0) {
214 // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period
215 // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period
216 if (place > 10) {
217 voice_place = (voice_place + 1) % voices;
218 place = 0.0;
219 }
220 ICR3 = (int)(((double)F_CPU) / frequencies[voice_place]); // Set max to the period
221 OCR3A = (int)(((double)F_CPU) / frequencies[voice_place]) >> 1; // Set compare to half the period
222 place++;
223 }
224 #endif
225 }
226
227 // SAMPLE
228 // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]);
229
230 // place_int++;
231
232 // if (place_int >= sample_length)
233 // if (repeat)
234 // place_int -= sample_length;
235 // else
236 // TIMSK3 &= ~_BV(OCIE3A);
237
238
239 if (notes) {
240 #ifdef PWM_AUDIO
241 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
242
243 place += note_frequency;
244 if (place >= SINE_LENGTH)
245 place -= SINE_LENGTH;
246 #else
247 if (note_frequency > 0) {
248 ICR3 = (int)(((double)F_CPU) / note_frequency); // Set max to the period
249 OCR3A = (int)(((double)F_CPU) / note_frequency) >> 1; // Set compare to half the period
250 }
251 #endif
252
253
254 note_position++;
255 if (note_position >= note_length) {
256 current_note++;
257 if (current_note >= notes_length) {
258 if (notes_repeat) {
259 current_note = 0;
260 } else {
261 #ifdef PWM_AUDIO
262 TIMSK3 &= ~_BV(OCIE3A);
263 #else
264 TIMSK3 &= ~_BV(OCIE3A);
265 TCCR3A &= ~_BV(COM3A1);
266 #endif
267 notes = false;
268 return;
269 }
270 }
271 #ifdef PWM_AUDIO
272 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
273 note_length = (*notes_pointer)[current_note][1];
274 #else
275 note_frequency = (*notes_pointer)[current_note][0];
276 note_length = (*notes_pointer)[current_note][1] / 4;
277 #endif
278 note_position = 0;
279 }
280
281 }
282
283}
284
285void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) {
286 if (note)
287 stop_all_notes();
288 notes = true;
289
290 notes_pointer = np;
291 notes_length = n_length;
292 notes_repeat = n_repeat;
293
294 place = 0;
295 current_note = 0;
296 #ifdef PWM_AUDIO
297 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
298 note_length = (*notes_pointer)[current_note][1];
299 #else
300 note_frequency = (*notes_pointer)[current_note][0];
301 note_length = (*notes_pointer)[current_note][1] / 4;
302 #endif
303 note_position = 0;
304
305
306 #ifdef PWM_AUDIO
307 TIMSK3 |= _BV(OCIE3A);
308 #else
309 TIMSK3 |= _BV(OCIE3A);
310 TCCR3A |= _BV(COM3A1);
311 #endif
312}
313
314void play_sample(uint8_t * s, uint16_t l, bool r) {
315 stop_all_notes();
316 place_int = 0;
317 sample = s;
318 sample_length = l;
319 repeat = r;
320
321 #ifdef PWM_AUDIO
322 TIMSK3 |= _BV(OCIE3A);
323 #else
324 #endif
325}
326
327void play_note(double freq, int vol) {
328 if (notes)
329 stop_all_notes();
330 note = true;
331 #ifdef PWM_AUDIO
332 freq = freq / SAMPLE_RATE;
333 #endif
334 if (freq > 0) {
335 if (frequency != 0) {
336 double starting_f = frequency;
337 if (frequency < freq) {
338 for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) {
339 frequency = f;
340 }
341 } else if (frequency > freq) {
342 for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) {
343 frequency = f;
344 }
345 }
346 }
347 frequency = freq;
348 volume = vol;
349
350 frequencies[voices] = frequency;
351 volumes[voices] = volume;
352 voices++;
353 }
354
355 #ifdef PWM_AUDIO
356 TIMSK3 |= _BV(OCIE3A);
357 #else
358 TIMSK3 |= _BV(OCIE3A);
359 TCCR3A |= _BV(COM3A1);
360 #endif
361
362} \ No newline at end of file
diff --git a/quantum/beeps.h b/quantum/audio.h
index 4ccc34497..99203cea7 100644
--- a/quantum/beeps.h
+++ b/quantum/audio.h
@@ -3,13 +3,9 @@
3#include <avr/io.h> 3#include <avr/io.h>
4#include <util/delay.h> 4#include <util/delay.h>
5 5
6bool playing_notes;
7
8void play_sample(uint8_t * s, uint16_t l, bool r); 6void play_sample(uint8_t * s, uint16_t l, bool r);
9void play_note(double freq, int vol); 7void play_note(double freq, int vol);
10void stop_note(double freq); 8void stop_note(double freq);
11void stop_all_notes(); 9void stop_all_notes();
12void init_notes(); 10void init_notes();
13
14
15void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat); \ No newline at end of file 11void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat); \ No newline at end of file
diff --git a/quantum/beeps.c b/quantum/beeps.c
deleted file mode 100644
index 7586ebc52..000000000
--- a/quantum/beeps.c
+++ /dev/null
@@ -1,265 +0,0 @@
1#include <stdio.h>
2#include <string.h>
3#include <math.h>
4#include <avr/pgmspace.h>
5#include <avr/interrupt.h>
6#include <avr/io.h>
7
8#include "beeps.h"
9#include "keymap_common.h"
10#include "wave.h"
11
12#define PI 3.14159265
13
14#define SAMPLE_DIVIDER 39
15#define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048)
16// Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
17
18void delay_us(int count) {
19 while(count--) {
20 _delay_us(1);
21 }
22}
23
24int voices = 0;
25double frequency = 0;
26int volume = 0;
27long position = 0;
28
29double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
30int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
31bool sliding = false;
32#define RANGE 1000
33volatile int i=0; //elements of the wave
34
35int max = 0xFF;
36float sum = 0;
37int value = 128;
38float place = 0;
39
40uint16_t place_int = 0;
41bool repeat = true;
42uint8_t * sample;
43uint16_t sample_length = 0;
44
45
46bool notes = false;
47float note_frequency = 0;
48float note_length = 0;
49uint16_t note_position = 0;
50float (* notes_pointer)[][2];
51uint8_t notes_length;
52bool notes_repeat;
53uint8_t current_note = 0;
54
55void stop_all_notes() {
56 voices = 0;
57 TIMSK3 &= ~_BV(OCIE3A);
58 notes = false;
59 playing_notes = false;
60 frequency = 0;
61 volume = 0;
62
63 for (int i = 0; i < 8; i++) {
64 frequencies[i] = 0;
65 volumes[i] = 0;
66 }
67}
68
69void stop_note(double freq) {
70 freq = freq / SAMPLE_RATE;
71 for (int i = 7; i >= 0; i--) {
72 if (frequencies[i] == freq) {
73 frequencies[i] = 0;
74 volumes[i] = 0;
75 for (int j = i; (j < 7); j++) {
76 frequencies[j] = frequencies[j+1];
77 frequencies[j+1] = 0;
78 volumes[j] = volumes[j+1];
79 volumes[j+1] = 0;
80 }
81 }
82 }
83 voices--;
84 if (voices < 0)
85 voices = 0;
86 if (voices == 0) {
87 TIMSK3 &= ~_BV(OCIE3A);
88 frequency = 0;
89 volume = 0;
90 } else {
91 double freq = frequencies[voices - 1];
92 int vol = volumes[voices - 1];
93 double starting_f = frequency;
94 if (frequency < freq) {
95 sliding = true;
96 for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 500.0)) {
97 frequency = f;
98 }
99 sliding = false;
100 } else if (frequency > freq) {
101 sliding = true;
102 for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 500.0)) {
103 frequency = f;
104 }
105 sliding = false;
106 }
107 frequency = freq;
108 volume = vol;
109 }
110}
111
112void init_notes() {
113
114 PLLFRQ = _BV(PDIV2);
115 PLLCSR = _BV(PLLE);
116 while(!(PLLCSR & _BV(PLOCK)));
117 PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
118
119 /* Init a fast PWM on Timer4 */
120 TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
121 TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
122 OCR4A = 0;
123
124 /* Enable the OC4A output */
125 DDRC |= _BV(PORTC6);
126
127 TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
128
129 TCCR3A = 0x0; // Options not needed
130 TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
131 OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
132
133 playing_notes = false;
134
135}
136
137
138ISR(TIMER3_COMPA_vect) {
139
140
141 // SINE
142 // OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]);
143
144 // SQUARE
145 // if (((int)place) >= 1024){
146 // OCR4A = 0xFF;
147 // } else {
148 // OCR4A = 0x00;
149 // }
150
151 // SAWTOOTH
152 // OCR4A = (int)place / 4;
153
154 // TRIANGLE
155 // if (((int)place) >= 1024) {
156 // OCR4A = (int)place / 2;
157 // } else {
158 // OCR4A = 2048 - (int)place / 2;
159 // }
160
161 // place += frequency;
162
163 // if (place >= SINE_LENGTH)
164 // if (repeat)
165 // place -= SINE_LENGTH;
166 // else
167 // TIMSK3 &= ~_BV(OCIE3A);
168
169 // SAMPLE
170 // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]);
171
172 // place_int++;
173
174 // if (place_int >= sample_length)
175 // if (repeat)
176 // place_int -= sample_length;
177 // else
178 // TIMSK3 &= ~_BV(OCIE3A);
179
180
181 if (notes) {
182 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
183
184 place += note_frequency;
185 if (place >= SINE_LENGTH)
186 place -= SINE_LENGTH;
187 note_position++;
188 if (note_position >= note_length) {
189 current_note++;
190 if (current_note >= notes_length) {
191 if (notes_repeat) {
192 current_note = 0;
193 } else {
194 TIMSK3 &= ~_BV(OCIE3A);
195 notes = false;
196 playing_notes = false;
197 return;
198 }
199 }
200 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
201 note_length = (*notes_pointer)[current_note][1];
202 note_position = 0;
203 }
204
205 }
206
207}
208
209void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) {
210 notes = true;
211
212 notes_pointer = np;
213 notes_length = n_length;
214 notes_repeat = n_repeat;
215
216 place = 0;
217 current_note = 0;
218 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
219 note_length = (*notes_pointer)[current_note][1];
220 // note_frequency = 880.0 / SAMPLE_RATE;
221 // note_length = 1000;
222 note_position = 0;
223
224
225 TIMSK3 |= _BV(OCIE3A);
226 playing_notes = true;
227}
228
229void play_sample(uint8_t * s, uint16_t l, bool r) {
230 place_int = 0;
231 sample = s;
232 sample_length = l;
233 repeat = r;
234
235 TIMSK3 |= _BV(OCIE3A);
236 playing_notes = true;
237}
238
239void play_note(double freq, int vol) {
240
241 freq = freq / SAMPLE_RATE;
242 if (freq > 0) {
243 if (frequency != 0) {
244 double starting_f = frequency;
245 if (frequency < freq) {
246 for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 500.0)) {
247 frequency = f;
248 }
249 } else if (frequency > freq) {
250 for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 500.0)) {
251 frequency = f;
252 }
253 }
254 }
255 frequency = freq;
256 volume = vol;
257
258 frequencies[voices] = frequency;
259 volumes[voices] = volume;
260 voices++;
261 }
262
263 TIMSK3 |= _BV(OCIE3A);
264
265} \ No newline at end of file
diff --git a/quantum/keymap_midi.c b/quantum/keymap_midi.c
index 3a1408e22..e37ea3103 100644
--- a/quantum/keymap_midi.c
+++ b/quantum/keymap_midi.c
@@ -100,10 +100,10 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
100 if (record->event.pressed) { 100 if (record->event.pressed) {
101 // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); 101 // midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
102 midi_send_noteon(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127); 102 midi_send_noteon(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
103 play_note(((double)261.626)*pow(2.0, 0.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF); 103 play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
104 } else { 104 } else {
105 // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127); 105 // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
106 midi_send_noteoff(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127); 106 midi_send_noteoff(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
107 stop_note(((double)261.626)*pow(2.0, 0.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row))); 107 stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
108 } 108 }
109} \ No newline at end of file 109} \ No newline at end of file
diff --git a/quantum/quantum.mk b/quantum/quantum.mk
index c82e47872..81a53f203 100644
--- a/quantum/quantum.mk
+++ b/quantum/quantum.mk
@@ -9,8 +9,11 @@ ifndef CUSTOM_MATRIX
9endif 9endif
10 10
11ifdef MIDI_ENABLE 11ifdef MIDI_ENABLE
12 SRC += $(QUANTUM_DIR)/keymap_midi.c \ 12 SRC += $(QUANTUM_DIR)/keymap_midi.c
13 $(QUANTUM_DIR)/beeps.c 13endif
14
15ifdef AUDIO_ENABLE
16 SRC += $(QUANTUM_DIR)/audio.c
14endif 17endif
15 18
16ifdef UNICODE_ENABLE 19ifdef UNICODE_ENABLE
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index edbcc282a..89c366f55 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -53,6 +53,9 @@ ifdef MIDI_ENABLE
53 OPT_DEFS += -DMIDI_ENABLE 53 OPT_DEFS += -DMIDI_ENABLE
54endif 54endif
55 55
56ifdef AUDIO_ENABLE
57 OPT_DEFS += -DAUDIO_ENABLE
58endif
56 59
57ifdef USB_6KRO_ENABLE 60ifdef USB_6KRO_ENABLE
58 OPT_DEFS += -DUSB_6KRO_ENABLE 61 OPT_DEFS += -DUSB_6KRO_ENABLE
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index f04790f4e..5d40dcf7b 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -52,8 +52,8 @@
52#include "descriptor.h" 52#include "descriptor.h"
53#include "lufa.h" 53#include "lufa.h"
54 54
55#ifdef MIDI_ENABLE 55#ifdef AUDIO_ENABLE
56 #include <beeps.h> 56 #include <audio.h>
57#endif 57#endif
58 58
59#ifdef BLUETOOTH_ENABLE 59#ifdef BLUETOOTH_ENABLE
@@ -946,6 +946,8 @@ int main(void)
946#ifdef MIDI_ENABLE 946#ifdef MIDI_ENABLE
947void fallthrough_callback(MidiDevice * device, 947void fallthrough_callback(MidiDevice * device,
948 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){ 948 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
949
950#ifdef AUDIO_ENABLE
949 if (cnt == 3) { 951 if (cnt == 3) {
950 switch (byte0 & 0xF0) { 952 switch (byte0 & 0xF0) {
951 case MIDI_NOTEON: 953 case MIDI_NOTEON:
@@ -959,6 +961,7 @@ void fallthrough_callback(MidiDevice * device,
959 if (byte0 == MIDI_STOP) { 961 if (byte0 == MIDI_STOP) {
960 stop_all_notes(); 962 stop_all_notes();
961 } 963 }
964#endif
962} 965}
963 966
964void cc_callback(MidiDevice * device, 967void cc_callback(MidiDevice * device,