diff options
Diffstat (limited to 'quantum/beeps.c')
| -rw-r--r-- | quantum/beeps.c | 231 |
1 files changed, 145 insertions, 86 deletions
diff --git a/quantum/beeps.c b/quantum/beeps.c index 8d1f81f21..edcc84aca 100644 --- a/quantum/beeps.c +++ b/quantum/beeps.c | |||
| @@ -1,11 +1,20 @@ | |||
| 1 | #include "beeps.h" | 1 | #include <stdio.h> |
| 2 | #include <string.h> | ||
| 2 | #include <math.h> | 3 | #include <math.h> |
| 3 | #include <avr/pgmspace.h> | 4 | #include <avr/pgmspace.h> |
| 4 | #include <avr/interrupt.h> | 5 | #include <avr/interrupt.h> |
| 5 | #include <avr/io.h> | 6 | #include <avr/io.h> |
| 6 | 7 | ||
| 8 | #include "beeps.h" | ||
| 9 | #include "keymap_common.h" | ||
| 10 | #include "wave.h" | ||
| 11 | |||
| 7 | #define PI 3.14159265 | 12 | #define PI 3.14159265 |
| 8 | 13 | ||
| 14 | #define SAMPLE_DIVIDER 70 | ||
| 15 | #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/256) | ||
| 16 | // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap | ||
| 17 | |||
| 9 | void delay_us(int count) { | 18 | void delay_us(int count) { |
| 10 | while(count--) { | 19 | while(count--) { |
| 11 | _delay_us(1); | 20 | _delay_us(1); |
| @@ -15,7 +24,7 @@ void delay_us(int count) { | |||
| 15 | int voices = 0; | 24 | int voices = 0; |
| 16 | double frequency = 0; | 25 | double frequency = 0; |
| 17 | int volume = 0; | 26 | int volume = 0; |
| 18 | int position = 0; | 27 | long position = 0; |
| 19 | 28 | ||
| 20 | double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | 29 | double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
| 21 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | 30 | int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; |
| @@ -23,6 +32,19 @@ bool sliding = false; | |||
| 23 | #define RANGE 1000 | 32 | #define RANGE 1000 |
| 24 | volatile int i=0; //elements of the wave | 33 | volatile int i=0; //elements of the wave |
| 25 | 34 | ||
| 35 | // uint8_t sine[128]; | ||
| 36 | // uint8_t tri[128]; | ||
| 37 | // uint8_t squ[128]; | ||
| 38 | // uint8_t* sine_start; | ||
| 39 | // uint8_t* sine_end; | ||
| 40 | // uint8_t* tri_start; | ||
| 41 | // uint8_t* tri_end; | ||
| 42 | |||
| 43 | // uint8_t* s_start; | ||
| 44 | // uint8_t* s_end; | ||
| 45 | // uint8_t* s_ptr; | ||
| 46 | |||
| 47 | |||
| 26 | 48 | ||
| 27 | void beeps() { | 49 | void beeps() { |
| 28 | play_notes(); | 50 | play_notes(); |
| @@ -36,8 +58,7 @@ void send_freq(double freq, int vol) { | |||
| 36 | 58 | ||
| 37 | void stop_all_notes() { | 59 | void stop_all_notes() { |
| 38 | voices = 0; | 60 | voices = 0; |
| 39 | TCCR3A = 0; | 61 | TIMSK0 &= ~_BV(OCIE0A); |
| 40 | TCCR3B = 0; | ||
| 41 | frequency = 0; | 62 | frequency = 0; |
| 42 | volume = 0; | 63 | volume = 0; |
| 43 | 64 | ||
| @@ -48,6 +69,7 @@ void stop_all_notes() { | |||
| 48 | } | 69 | } |
| 49 | 70 | ||
| 50 | void stop_note(double freq) { | 71 | void stop_note(double freq) { |
| 72 | freq = freq / SAMPLE_RATE; | ||
| 51 | for (int i = 7; i >= 0; i--) { | 73 | for (int i = 7; i >= 0; i--) { |
| 52 | if (frequencies[i] == freq) { | 74 | if (frequencies[i] == freq) { |
| 53 | frequencies[i] = 0; | 75 | frequencies[i] = 0; |
| @@ -64,151 +86,176 @@ void stop_note(double freq) { | |||
| 64 | if (voices < 0) | 86 | if (voices < 0) |
| 65 | voices = 0; | 87 | voices = 0; |
| 66 | if (voices == 0) { | 88 | if (voices == 0) { |
| 67 | TCCR3A = 0; | 89 | TIMSK0 &= ~_BV(OCIE0A); |
| 68 | TCCR3B = 0; | ||
| 69 | frequency = 0; | 90 | frequency = 0; |
| 70 | volume = 0; | 91 | volume = 0; |
| 71 | } else { | 92 | } else { |
| 72 | double freq = frequencies[voices - 1]; | 93 | double freq = frequencies[voices - 1]; |
| 73 | int vol = volumes[voices - 1]; | 94 | int vol = volumes[voices - 1]; |
| 95 | double starting_f = frequency; | ||
| 74 | if (frequency < freq) { | 96 | if (frequency < freq) { |
| 75 | sliding = true; | 97 | sliding = true; |
| 76 | for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) { | 98 | for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 500.0)) { |
| 77 | send_freq(f, vol); | 99 | frequency = f; |
| 78 | } | 100 | } |
| 79 | sliding = false; | 101 | sliding = false; |
| 80 | } else if (frequency > freq) { | 102 | } else if (frequency > freq) { |
| 81 | sliding = true; | 103 | sliding = true; |
| 82 | for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) { | 104 | for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 500.0)) { |
| 83 | send_freq(f, vol); | 105 | frequency = f; |
| 84 | } | 106 | } |
| 85 | sliding = false; | 107 | sliding = false; |
| 86 | } | 108 | } |
| 87 | send_freq(freq, vol); | 109 | // send_freq(freq, vol); |
| 88 | frequency = freq; | 110 | frequency = freq; |
| 89 | volume = vol; | 111 | volume = vol; |
| 90 | } | 112 | } |
| 91 | } | 113 | } |
| 92 | 114 | ||
| 93 | void init_notes() { | 115 | void init_notes() { |
| 94 | // TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (1 << WGM10); | ||
| 95 | // TCCR1B = (1 << COM1B1) | (0 << COM1A0) | (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10); | ||
| 96 | 116 | ||
| 97 | // DDRC |= (1<<6); | 117 | // for(int i = 0; i < 128; i++) { |
| 118 | // sine[i] = sin(i * PI / 64) * 128 + 128; | ||
| 119 | // tri[i] = 256 - abs((i - 64) * 4); | ||
| 120 | // } | ||
| 121 | // sine_start = &sine; | ||
| 122 | // sine_end = &sine + 128; | ||
| 123 | // tri_start = &tri; | ||
| 124 | // tri_end = &tri + 128; | ||
| 98 | 125 | ||
| 99 | // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); | 126 | // new |
| 100 | // TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30); | ||
| 101 | 127 | ||
| 102 | // ICR3 = 0xFFFF; | ||
| 103 | // OCR3A = (int)((float)wave[i]*ICR3/RANGE); //go to next array element | ||
| 104 | 128 | ||
| 129 | PLLFRQ = _BV(PDIV2); | ||
| 130 | PLLCSR = _BV(PLLE); | ||
| 131 | while(!(PLLCSR & _BV(PLOCK))); | ||
| 132 | PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ | ||
| 133 | |||
| 134 | /* Init a fast PWM on Timer4 */ | ||
| 135 | TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ | ||
| 136 | TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ | ||
| 137 | OCR4A = 0; | ||
| 105 | 138 | ||
| 106 | // cli(); | 139 | /* Enable the OC4A output */ |
| 140 | DDRC |= _BV(PORTC6); | ||
| 107 | 141 | ||
| 108 | // /* Enable interrupt on timer2 == 127, with clk/8 prescaler. At 16MHz, | ||
| 109 | // this gives a timer interrupt at 15625Hz. */ | ||
| 110 | // TIMSK3 = (1 << OCIE3A); | ||
| 111 | 142 | ||
| 112 | // /* clear/reset timer on match */ | ||
| 113 | // // TCCR3A = 1<<WGM31 | 0<<WGM30; CTC mode, reset on match | ||
| 114 | // // TCCR3B = 0<<CS32 | 1<<CS31 | 0<<CS30; /* clk, /8 prescaler */ | ||
| 115 | 143 | ||
| 116 | // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); | 144 | /* First disable the timer overflow interrupt while we're configuring */ |
| 117 | // TCCR3B = (0 << WGM33) | (0 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30); | 145 | // TIMSK0 &= ~(1<<TOIE0); |
| 146 | |||
| 147 | // /* Configure timer4 in normal mode (pure counting, no PWM etc.) */ | ||
| 148 | // TCCR0A &= ~((1<<WGM01) | (1<<WGM00)); | ||
| 149 | // TCCR0B &= ~(1<<WGM02); | ||
| 118 | 150 | ||
| 151 | // /* Disable Compare Match A interrupt enable (only want overflow) */ | ||
| 152 | // TIMSK0 &= ~(1<<OCIE0A); | ||
| 153 | |||
| 154 | // TCCR0B |= (1<<CS01); // Set bits | ||
| 155 | // TCCR0B &= ~(1<<CS00) | ~(1<<CS02); // Clear bit | ||
| 156 | |||
| 157 | // /* Save value globally for later reload in ISR */ | ||
| 158 | // tcnt0 = 45 - 1; | ||
| 119 | 159 | ||
| 120 | // TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10); | 160 | // /* Finally load end enable the timer */ |
| 121 | // TCCR1B = (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10); | 161 | // TCNT0 = tcnt0; |
| 122 | // // SPCR = 0x50; | 162 | // TIMSK0 |= (1<<TOIE0); |
| 123 | // // SPSR = 0x01; | ||
| 124 | // DDRC |= (1<<6); | ||
| 125 | // // ICR3 = 0xFFFF; | ||
| 126 | // // OCR3A=80; | ||
| 127 | // PORTC |= (1<<6); | ||
| 128 | 163 | ||
| 129 | // sei(); | ||
| 130 | } | 164 | } |
| 131 | 165 | ||
| 132 | // #define highByte(c) ((c >> 8) & 0x00FF) | 166 | int max = 0xFF; |
| 133 | // #define lowByte(c) (c & 0x00FF) | 167 | float sum = 0; |
| 168 | int value = 128; | ||
| 169 | float place = 0; | ||
| 134 | 170 | ||
| 135 | ISR(TIMER3_COMPA_vect) { | 171 | ISR(TIMER0_COMPA_vect) { |
| 136 | 172 | ||
| 137 | if (ICR3 > 0 && !sliding) { | ||
| 138 | switch (position) { | ||
| 139 | case 0: { | ||
| 140 | int duty = (((double)F_CPU) / (frequency)); | ||
| 141 | ICR3 = duty; // Set max to the period | ||
| 142 | OCR3A = duty >> 1; // Set compare to half the period | ||
| 143 | break; | ||
| 144 | } | ||
| 145 | case 1: { | ||
| 146 | int duty = (((double)F_CPU) / (frequency*2)); | ||
| 147 | ICR3 = duty; // Set max to the period | ||
| 148 | OCR3A = duty >> 1; // Set compare to half the period | ||
| 149 | break; | ||
| 150 | } | ||
| 151 | case 2: { | ||
| 152 | int duty = (((double)F_CPU) / (frequency*3)); | ||
| 153 | ICR3 = duty; // Set max to the period | ||
| 154 | OCR3A = duty >> 1; // Set compare to half the period | ||
| 155 | break; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | position = (position + 1) % 3; | ||
| 159 | } | ||
| 160 | // /* OCR2A has been cleared, per TCCR2A above */ | ||
| 161 | // // OCR3A = 127; | ||
| 162 | 173 | ||
| 163 | // // pos1 += incr1; | ||
| 164 | // // pos2 += incr2; | ||
| 165 | // // pos3 += incr3; | ||
| 166 | 174 | ||
| 167 | // // sample = sinewave[highByte(pos1)] + sinewave[highByte(pos2)] + sinewave[highByte(pos3)]; | 175 | // value = *(sine_start+=(long)frequencies[0]); |
| 176 | // OCR4A = value; | ||
| 177 | // if (sine_start >= sine_end) { | ||
| 178 | // sine_start = &sine[(sine_start - sine_end) % 128]; | ||
| 179 | // } | ||
| 168 | 180 | ||
| 169 | // // OCR3A = sample; | ||
| 170 | 181 | ||
| 182 | // OCR4A = pgm_read_byte(sine_start); | ||
| 183 | // // sine_start = &sine[(sine_start - &sine[0] + (int)frequencies[0]) % 128]; | ||
| 184 | // sine_start += (int)frequencies[0]; | ||
| 185 | // if (sine_start >= sine_end) { | ||
| 186 | // sine_start = &sine[(sine_start - sine_end) % 128]; | ||
| 187 | // } | ||
| 188 | |||
| 189 | // OCR4A = pgm_read_byte(s_ptr); | ||
| 190 | // s_ptr = s_start + (uint8_t)place; | ||
| 191 | // OCR4A = pgm_read_byte(s_ptr); | ||
| 192 | |||
| 193 | |||
| 194 | // SINE | ||
| 195 | OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]); | ||
| 196 | |||
| 197 | // SQUARE | ||
| 198 | // if (((int)place) >= 1024){ | ||
| 199 | // OCR4A = 0xFF; | ||
| 200 | // } else { | ||
| 201 | // OCR4A = 0x00; | ||
| 202 | // } | ||
| 203 | |||
| 204 | // SAWTOOTH | ||
| 205 | // OCR4A = (int)place / 4; | ||
| 206 | |||
| 207 | // TRIANGLE | ||
| 208 | // if (((int)place) >= 1024) { | ||
| 209 | // OCR4A = (int)place / 2; | ||
| 210 | // } else { | ||
| 211 | // OCR4A = 2048 - (int)place / 2; | ||
| 212 | // } | ||
| 213 | |||
| 214 | place += frequency; | ||
| 215 | if (place >= SINE_LENGTH) | ||
| 216 | place -= SINE_LENGTH; | ||
| 217 | |||
| 218 | } | ||
| 171 | 219 | ||
| 172 | // OCR3A=pgm_read_byte(&sinewave[pos1]); | ||
| 173 | // pos1++; | ||
| 174 | // // PORTC &= ~(1<<6); | ||
| 175 | 220 | ||
| 176 | // /* buffered, 1x gain, active mode */ | 221 | ISR(TIMER0_COMPB_vect) |
| 177 | // // SPDR = highByte(sample) | 0x70; | 222 | { |
| 178 | // // while (!(SPSR & (1<<SPIF))); | ||
| 179 | 223 | ||
| 180 | // // SPDR = lowByte(sample); | 224 | /* Disable the interrupt */ |
| 181 | // // while (!(SPSR & (1<<SPIF))); | 225 | TIMSK0 &= ~_BV(OCIE0B); |
| 182 | 226 | ||
| 183 | // // PORTC |= (1<<6); | ||
| 184 | } | 227 | } |
| 185 | 228 | ||
| 186 | void play_note(double freq, int vol) { | 229 | void play_note(double freq, int vol) { |
| 187 | 230 | ||
| 231 | freq = freq / SAMPLE_RATE; | ||
| 188 | if (freq > 0) { | 232 | if (freq > 0) { |
| 189 | DDRC |= (1<<6); | ||
| 190 | 233 | ||
| 191 | TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); | 234 | // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (1 << WGM30); |
| 192 | TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); | 235 | // TCCR3B = (0 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30); |
| 193 | 236 | ||
| 237 | // TIMSK3 = 0x0; | ||
| 194 | if (frequency != 0) { | 238 | if (frequency != 0) { |
| 239 | double starting_f = frequency; | ||
| 195 | if (frequency < freq) { | 240 | if (frequency < freq) { |
| 196 | for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) { | 241 | for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 500.0)) { |
| 197 | send_freq(f, vol); | 242 | frequency = f; |
| 198 | } | 243 | } |
| 199 | } else if (frequency > freq) { | 244 | } else if (frequency > freq) { |
| 200 | for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) { | 245 | for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 500.0)) { |
| 201 | send_freq(f, vol); | 246 | frequency = f; |
| 202 | } | 247 | } |
| 203 | } | 248 | } |
| 204 | } | 249 | } |
| 205 | send_freq(freq, vol); | 250 | // send_freq(freq, vol); |
| 206 | frequency = freq; | 251 | frequency = freq; |
| 207 | volume = vol; | 252 | volume = vol; |
| 208 | 253 | ||
| 209 | frequencies[voices] = frequency; | 254 | frequencies[voices] = frequency; |
| 210 | volumes[voices] = volume; | 255 | volumes[voices] = volume; |
| 211 | voices++; | 256 | voices++; |
| 257 | // position = 0; | ||
| 258 | // TCNT0 = 0; | ||
| 212 | } | 259 | } |
| 213 | // ICR3 = 0xFFFF; | 260 | // ICR3 = 0xFFFF; |
| 214 | // for (int i = 0; i < 10000; i++) { | 261 | // for (int i = 0; i < 10000; i++) { |
| @@ -218,6 +265,18 @@ void play_note(double freq, int vol) { | |||
| 218 | 265 | ||
| 219 | // TCCR3A = 0; | 266 | // TCCR3A = 0; |
| 220 | // TCCR3B = 0; | 267 | // TCCR3B = 0; |
| 268 | |||
| 269 | |||
| 270 | TIMSK0 &= ~_BV(OCIE0A) | ~_BV(OCIE0B); | ||
| 271 | |||
| 272 | TCCR0A = _BV(WGM01); | ||
| 273 | TCCR0B = _BV(CS01); | ||
| 274 | OCR0A = SAMPLE_DIVIDER - 1; | ||
| 275 | OCR0B = 1; | ||
| 276 | |||
| 277 | TIMSK0 |= _BV(OCIE0A); | ||
| 278 | // sei(); | ||
| 279 | |||
| 221 | } | 280 | } |
| 222 | 281 | ||
| 223 | // void note(int x, float length) { | 282 | // void note(int x, float length) { |
