59 lines
1.6 KiB
C
59 lines
1.6 KiB
C
#include "main.h"
|
|
|
|
/*
|
|
const uint8_t PROGMEM notes[OCTAVES][NOTES_PER_OCTAVE] = {
|
|
{ 140, 62, 118, 106, 94, 88, 79, 64, 112, 98, , 37 }, // 1024 prescaler octave 2
|
|
{ 141, 126, 238, 212, 188, 178, 158, 133, 225, 200, 168, 150 } // 64 prescaler octave 4
|
|
};
|
|
*/
|
|
|
|
const uint8_t PROGMEM notes[OCTAVES][NOTES_PER_OCTAVE] = {
|
|
{ 35, 31, 59, 53, 47, 44, 39, 32, 56, 49, 41, 37 }, // 1024 prescaler octave 2
|
|
{ 141, 126, 238, 212, 188, 178, 158, 133, 225, 200, 168, 150 } // 64 prescaler octave 4
|
|
};
|
|
|
|
|
|
void play_note(beat_t note, uint8_t speaker) {
|
|
if (note.note == rest) { // Handle special rest case
|
|
if (speaker == 0) {
|
|
// Turn off timer clock source, disabling
|
|
TCCR0B &= ~( (1 << CS02) | (1 << CS01) | (1 << CS00));
|
|
// Turn off output pin
|
|
PORTB &= ~(1 << PORTB2);
|
|
} else {
|
|
// turn off timer clock source, disabling
|
|
TCCR1B &= ~( (1 << CS12) | (1 << CS11) | (1 << CS10));
|
|
// turn off output pin
|
|
PORTB &= ~(1 << PORTB3);
|
|
}
|
|
} else {
|
|
// Set up so note changes always happen after rests,
|
|
// so we know CS[2:0] = 0
|
|
// See pages 86 and 114
|
|
uint8_t prescale = 0;
|
|
if (note.octave == 0) {
|
|
// set prescaler to 1024
|
|
prescale = 4;
|
|
} else {
|
|
// set prescaler to 64
|
|
prescale = 3;
|
|
}
|
|
|
|
// Get value to write to output compare
|
|
uint8_t period = pgm_read_byte((PGM_P*) ¬es[note.octave][note.note]);
|
|
|
|
// Actually set clock source
|
|
if (speaker == 0) {
|
|
TCNT0 = 0; // reset counter
|
|
OCR0A = period; // set note period
|
|
TCCR0B |= prescale;
|
|
} else {
|
|
TCNT1H = 0; // reset counter
|
|
TCNT1L = 0;
|
|
OCR1AL = period; // set note period
|
|
OCR1AH = period >> 8;
|
|
TCCR1B |= prescale;
|
|
}
|
|
}
|
|
}
|