diff options
| author | Vineet K <git@vineetk.net> | 2024-04-21 20:46:46 -0400 |
|---|---|---|
| committer | Shokara Kou <kou@13f0.net> | 2024-04-21 20:46:56 -0400 |
| commit | ece65dcc2a11b6f22eed9ce583075f82ca177064 (patch) | |
| tree | 5d3869565dd61996911e3fa9f6992bbda4561250 | |
| parent | 6a28f45c514cdacf47d466f14b0bc69abccd064f (diff) | |
play NES SMB Underground theme for testing
| -rw-r--r-- | notes.c | 213 |
1 files changed, 179 insertions, 34 deletions
| @@ -8,6 +8,9 @@ | |||
| 8 | #include <avr/io.h> | 8 | #include <avr/io.h> |
| 9 | #include <avr/interrupt.h> | 9 | #include <avr/interrupt.h> |
| 10 | 10 | ||
| 11 | #define F_CPU 16e6 | ||
| 12 | #include <util/delay.h> | ||
| 13 | |||
| 11 | #define T1_PRESCALAR 8 | 14 | #define T1_PRESCALAR 8 |
| 12 | #define FREQ(f) (16e6 / f / T1_PRESCALAR / 2) | 15 | #define FREQ(f) (16e6 / f / T1_PRESCALAR / 2) |
| 13 | 16 | ||
| @@ -18,8 +21,11 @@ | |||
| 18 | #define P_TX 1 | 21 | #define P_TX 1 |
| 19 | #define P_SPKR 2 | 22 | #define P_SPKR 2 |
| 20 | 23 | ||
| 24 | #define MARIO 50 | ||
| 25 | |||
| 21 | unsigned short freqs[] = { | 26 | unsigned short freqs[] = { |
| 22 | // PD3-7 | 27 | // PD3-7 |
| 28 | #if 0 | ||
| 23 | FREQ(100), | 29 | FREQ(100), |
| 24 | FREQ(200), | 30 | FREQ(200), |
| 25 | FREQ(250), | 31 | FREQ(250), |
| @@ -27,18 +33,74 @@ unsigned short freqs[] = { | |||
| 27 | FREQ(350), | 33 | FREQ(350), |
| 28 | // PB0-4 | 34 | // PB0-4 |
| 29 | FREQ(400), | 35 | FREQ(400), |
| 36 | #else | ||
| 37 | FREQ(131), // middle c | ||
| 38 | FREQ(262), | ||
| 39 | FREQ(110), | ||
| 40 | FREQ(220), | ||
| 41 | FREQ(117), | ||
| 42 | FREQ(233), | ||
| 43 | #endif | ||
| 30 | FREQ(500), | 44 | FREQ(500), |
| 31 | FREQ(600), | 45 | FREQ(6000), |
| 32 | FREQ(700), | 46 | FREQ(5000), |
| 33 | FREQ(750), | 47 | FREQ(5500), |
| 34 | // PC0-4 | 48 | // PC0-4 |
| 35 | FREQ(1000), | 49 | FREQ(4000), |
| 36 | FREQ(1250), | 50 | FREQ(7250), |
| 37 | FREQ(1500), | 51 | FREQ(6500), |
| 38 | FREQ(1750), | 52 | FREQ(5750), |
| 39 | FREQ(2000), | 53 | FREQ(5000), |
| 54 | FREQ(5000), | ||
| 55 | FREQ(6000), | ||
| 56 | FREQ(7000), | ||
| 57 | FREQ(8000), | ||
| 58 | FREQ(8000), | ||
| 59 | FREQ(8000), | ||
| 60 | FREQ(8000), | ||
| 61 | FREQ(8000), | ||
| 62 | |||
| 63 | // notes | ||
| 64 | [MARIO] = FREQ(131), // C3 | ||
| 65 | FREQ(262), // C4 | ||
| 66 | FREQ(110), // A2 | ||
| 67 | FREQ(220), // A3 | ||
| 68 | FREQ(117), // Bb2 | ||
| 69 | FREQ(233), // Bb3 | ||
| 70 | |||
| 71 | FREQ(87), | ||
| 72 | FREQ(175), | ||
| 73 | FREQ(73), | ||
| 74 | FREQ(147), | ||
| 75 | FREQ(78), | ||
| 76 | FREQ(156), | ||
| 77 | |||
| 78 | FREQ(156), | ||
| 79 | FREQ(147), | ||
| 80 | FREQ(139), | ||
| 81 | FREQ(131), | ||
| 82 | FREQ(156), | ||
| 83 | FREQ(147), | ||
| 84 | FREQ(104), | ||
| 85 | FREQ(98), | ||
| 86 | FREQ(139), | ||
| 87 | |||
| 88 | FREQ(156), | ||
| 89 | FREQ(185), | ||
| 90 | FREQ(175), | ||
| 91 | FREQ(165), | ||
| 92 | FREQ(233), | ||
| 93 | FREQ(220), | ||
| 94 | FREQ(208), | ||
| 95 | FREQ(156), | ||
| 96 | FREQ(123), | ||
| 97 | FREQ(123), | ||
| 98 | FREQ(110), | ||
| 99 | FREQ(104), | ||
| 40 | 100 | ||
| 41 | [32] = 0 // used as a 'silent' note | 101 | ['"'] = FREQ(16000), |
| 102 | |||
| 103 | [255] = 0 // used as a 'silent' note | ||
| 42 | }; | 104 | }; |
| 43 | unsigned char note = 0; | 105 | unsigned char note = 0; |
| 44 | // 0 = buttons write note+cycles+\xff to UART | 106 | // 0 = buttons write note+cycles+\xff to UART |
| @@ -108,6 +170,36 @@ usart_read(void) | |||
| 108 | return UDR0; | 170 | return UDR0; |
| 109 | } | 171 | } |
| 110 | 172 | ||
| 173 | void | ||
| 174 | playtone(void) | ||
| 175 | { | ||
| 176 | // Prepare Timer/Counter | ||
| 177 | TCNT1 = 1; | ||
| 178 | OCR1A = freqs[note]; | ||
| 179 | TCCR1B |= 1 << CS11; | ||
| 180 | |||
| 181 | // Monitor OutPut Compare Flag | ||
| 182 | while ((TIFR1 & (1 << OCF1A)) == 0); | ||
| 183 | |||
| 184 | // Toggles port For Speaker | ||
| 185 | PORTD ^= 1 << P_SPKR; | ||
| 186 | TIFR1 |= 1 << OCF1A; | ||
| 187 | TCCR1B &= ~(1 << CS11); | ||
| 188 | } | ||
| 189 | |||
| 190 | void | ||
| 191 | play_note(unsigned char _note, unsigned short _cycles) | ||
| 192 | { | ||
| 193 | note = _note; | ||
| 194 | |||
| 195 | if (note != 255) { | ||
| 196 | for (unsigned short i = 0; i < _cycles; i++) | ||
| 197 | playtone(); | ||
| 198 | } else { | ||
| 199 | _delay_ms(_cycles); | ||
| 200 | } | ||
| 201 | } | ||
| 202 | |||
| 111 | int | 203 | int |
| 112 | main(void) | 204 | main(void) |
| 113 | { | 205 | { |
| @@ -139,7 +231,7 @@ main(void) | |||
| 139 | usart_send(mode); | 231 | usart_send(mode); |
| 140 | } | 232 | } |
| 141 | // check if any buttons are pressed, otherwise don't play a note | 233 | // check if any buttons are pressed, otherwise don't play a note |
| 142 | if (mode != '1' && ((PINB & PCMSK0) | (PINC & PCMSK1) | (PIND & PCMSK2)) == 0) { | 234 | if (mode == '0' && ((PINB & PCMSK0) | (PINC & PCMSK1) | (PIND & PCMSK2)) == 0) { |
| 143 | // if a button was released, then send note and cycles played | 235 | // if a button was released, then send note and cycles played |
| 144 | if (cycles > 0) { | 236 | if (cycles > 0) { |
| 145 | usart_send(tmp); | 237 | usart_send(tmp); |
| @@ -152,23 +244,14 @@ main(void) | |||
| 152 | } | 244 | } |
| 153 | 245 | ||
| 154 | if (mode == '0') { | 246 | if (mode == '0') { |
| 155 | // Prepare Timer/Counter | ||
| 156 | TCNT1 = 1; | ||
| 157 | tmp = note; | 247 | tmp = note; |
| 158 | OCR1A = freqs[note]; | ||
| 159 | TCCR1B |= 1 << CS11; | ||
| 160 | 248 | ||
| 161 | // Monitor OutPut Compare Flag | 249 | playtone(); |
| 162 | while ((TIFR1 & (1 << OCF1A)) == 0); | ||
| 163 | 250 | ||
| 164 | // Toggles port For Speaker | ||
| 165 | PORTD ^= 1 << P_SPKR; | ||
| 166 | TIFR1 |= 1 << OCF1A; | ||
| 167 | TCCR1B &= ~(1 << CS11); | ||
| 168 | cycles = (cycles + 1) % 0xffff; | 251 | cycles = (cycles + 1) % 0xffff; |
| 169 | } else if (mode == '1') { | 252 | } else if (mode == '1') { |
| 170 | note = usart_read(); | 253 | note = usart_read(); |
| 171 | if (note >= '0') note -= '0'; | 254 | if (note >= 'Z') note -= '0'; |
| 172 | tmp = usart_read(); | 255 | tmp = usart_read(); |
| 173 | cycles = tmp << 8; | 256 | cycles = tmp << 8; |
| 174 | tmp = usart_read(); | 257 | tmp = usart_read(); |
| @@ -176,26 +259,88 @@ main(void) | |||
| 176 | tmp = usart_read(); | 259 | tmp = usart_read(); |
| 177 | 260 | ||
| 178 | // reset to default mode when an invalid note is read | 261 | // reset to default mode when an invalid note is read |
| 179 | if (tmp != 'z' || note > '@') { | 262 | if (tmp != 'z' || note >= '|') { |
| 180 | mode = '0'; | 263 | mode = '0'; |
| 181 | continue; | 264 | continue; |
| 182 | } | 265 | } |
| 183 | 266 | ||
| 184 | for (unsigned short i = 0; i < cycles; i++) { | 267 | for (unsigned short i = 0; i < cycles; i++) |
| 185 | usart_send(HIGH(cycles)); | 268 | playtone(); |
| 186 | usart_send(LOW(cycles)); | 269 | } else if (mode == '2') { |
| 187 | usart_send(0); | 270 | play_note(MARIO + 0, 131 * 0.3); |
| 271 | play_note(MARIO + 1, 262 * 0.3); | ||
| 272 | play_note(MARIO + 2, 110 * 0.3); | ||
| 273 | play_note(MARIO + 3, 220 * 0.3); | ||
| 274 | play_note(MARIO + 4, 117 * 0.3); | ||
| 275 | play_note(MARIO + 5, 233 * 0.3); | ||
| 276 | play_note(255, 1800); | ||
| 277 | play_note(MARIO + 0, 131 * 0.3); | ||
| 278 | play_note(MARIO + 1, 262 * 0.3); | ||
| 279 | play_note(MARIO + 2, 110 * 0.3); | ||
| 280 | play_note(MARIO + 3, 220 * 0.3); | ||
| 281 | play_note(MARIO + 4, 117 * 0.3); | ||
| 282 | play_note(MARIO + 5, 233 * 0.3); | ||
| 283 | play_note(255, 1800); | ||
| 188 | 284 | ||
| 189 | TCNT1 = 1; | 285 | play_note(MARIO + 6, 87 * 0.3); |
| 190 | OCR1A = freqs[note]; | 286 | play_note(MARIO + 7, 175 * 0.3); |
| 191 | TCCR1B |= 1 << CS11; | 287 | play_note(MARIO + 8, 73 * 0.3); |
| 288 | play_note(MARIO + 9, 147 * 0.3); | ||
| 289 | play_note(MARIO + 10, 78 * 0.3); | ||
| 290 | play_note(MARIO + 11, 156 * 0.3); | ||
| 291 | play_note(255, 1800); | ||
| 292 | play_note(MARIO + 6, 87 * 0.3); | ||
| 293 | play_note(MARIO + 7, 175 * 0.3); | ||
| 294 | play_note(MARIO + 8, 73 * 0.3); | ||
| 295 | play_note(MARIO + 9, 147 * 0.3); | ||
| 296 | play_note(MARIO + 10, 78 * 0.3); | ||
| 297 | play_note(MARIO + 11, 156 * 0.3); | ||
| 298 | play_note(255, 1800); | ||
| 192 | 299 | ||
| 193 | while ((TIFR1 & (1 << OCF1A)) == 0); | 300 | play_note(MARIO + 12, 156 * 0.3); |
| 301 | play_note(255, 25); | ||
| 302 | play_note(MARIO + 13, 147 * 0.3); | ||
| 303 | play_note(255, 25); | ||
| 304 | play_note(MARIO + 14, 139 * 0.3); | ||
| 305 | play_note(255, 25); | ||
| 306 | play_note(MARIO + 15, 131 * 0.6); | ||
| 307 | play_note(255, 25); | ||
| 308 | play_note(MARIO + 16, 156 * 0.3); | ||
| 309 | play_note(255, 25); | ||
| 310 | play_note(MARIO + 17, 147 * 0.6); | ||
| 311 | play_note(255, 25); | ||
| 312 | play_note(MARIO + 18, 104 * 0.6); | ||
| 313 | play_note(255, 25); | ||
| 314 | play_note(MARIO + 19, 98 * 0.6); | ||
| 315 | play_note(255, 25); | ||
| 316 | play_note(MARIO + 20, 139 * 0.6); | ||
| 194 | 317 | ||
| 195 | PORTD ^= 1 << P_SPKR; | 318 | play_note(MARIO + 21, 156 * 0.3); |
| 196 | TIFR1 |= 1 << OCF1A; | 319 | play_note(255, 25); |
| 197 | TCCR1B &= ~(1 << CS11); | 320 | play_note(MARIO + 22, 185 * 0.3); |
| 198 | } | 321 | play_note(255, 25); |
| 322 | play_note(MARIO + 23, 175 * 0.3); | ||
| 323 | play_note(255, 25); | ||
| 324 | play_note(MARIO + 24, 165 * 0.3); | ||
| 325 | play_note(255, 25); | ||
| 326 | play_note(MARIO + 25, 233 * 0.3); | ||
| 327 | play_note(255, 25); | ||
| 328 | play_note(MARIO + 26, 220 * 0.3); | ||
| 329 | play_note(255, 25); | ||
| 330 | play_note(MARIO + 27, 208 * 0.6); | ||
| 331 | play_note(255, 25); | ||
| 332 | play_note(MARIO + 28, 156 * 0.6); | ||
| 333 | play_note(255, 25); | ||
| 334 | play_note(MARIO + 29, 123 * 0.6); | ||
| 335 | play_note(255, 25); | ||
| 336 | play_note(MARIO + 30, 123 * 0.6); | ||
| 337 | play_note(255, 25); | ||
| 338 | play_note(MARIO + 31, 110 * 0.6); | ||
| 339 | play_note(255, 25); | ||
| 340 | play_note(MARIO + 32, 104 * 0.6); | ||
| 341 | play_note(255, 25); | ||
| 342 | |||
| 343 | play_note(255, 3600); | ||
| 199 | } | 344 | } |
| 200 | } | 345 | } |
| 201 | } | 346 | } |
