87 lines
2.4 KiB
C
87 lines
2.4 KiB
C
/*
|
|
Direct-digital synthesis
|
|
ADSR Dynamic Volume Envelope Demo
|
|
*/
|
|
|
|
// ------- Preamble -------- //
|
|
#include "adsr.h" /* Defines, includes, and init functions */
|
|
|
|
int main(void) {
|
|
|
|
// -------- Inits --------- //
|
|
|
|
uint16_t accumulator = 0;
|
|
uint8_t volume = 0;
|
|
uint16_t noteClock = 0;
|
|
uint16_t tuningWord = C1;
|
|
|
|
uint8_t waveStep;
|
|
int16_t mixer=0;
|
|
char serialInput;
|
|
|
|
clock_prescale_set(clock_div_1); /* CPU clock 8 MHz */
|
|
initTimer0();
|
|
initUSART();
|
|
printString(" Serial Synth\r\n");
|
|
printString("Notes: asdfghjkl;'\r\n");
|
|
|
|
SPEAKER_DDR |= (1 << SPEAKER); /* speaker output */
|
|
|
|
// ------ Event loop ------ //
|
|
while (1) {
|
|
|
|
// Set PWM output
|
|
loop_until_bit_is_set(TIFR0, TOV0); /* wait for timer0 overflow */
|
|
OCR0A = 128 + (uint8_t) mixer;
|
|
TIFR0 |= (1 << TOV0); /* reset the overflow bit */
|
|
|
|
// Update the DDS
|
|
accumulator += tuningWord;
|
|
waveStep = accumulator >> 8;
|
|
mixer = fullTriangle[waveStep] * volume;
|
|
mixer = mixer >> 5;
|
|
|
|
/* Input processed here: check USART */
|
|
if (bit_is_set(UCSR0A, RXC0)) {
|
|
serialInput = UDR0; /* read in from USART */
|
|
tuningWord = lookupPitch(serialInput);
|
|
noteClock = 1;
|
|
}
|
|
|
|
/* Dynamic Volume stuff here */
|
|
if (noteClock) { /* if noteClock already running */
|
|
noteClock++;
|
|
if (noteClock < ATTACK_TIME) { /* attack */
|
|
/* wait until time to increase next step */
|
|
if (noteClock > ATTACK_RATE * volume) {
|
|
if (volume < 31) {
|
|
volume++;
|
|
}
|
|
}
|
|
}
|
|
else if (noteClock < DECAY_TIME) { /* decay */
|
|
if ((noteClock - ATTACK_TIME) >
|
|
(FULL_VOLUME - volume) * DECAY_RATE) {
|
|
if (volume > SUSTAIN_LEVEL) {
|
|
volume--;
|
|
}
|
|
}
|
|
}
|
|
else if (noteClock > RELEASE_TIME) { /* release */
|
|
if ((noteClock - RELEASE_TIME) >
|
|
(SUSTAIN_LEVEL - volume) * RELEASE_RATE) {
|
|
if (volume > 0) {
|
|
volume--;
|
|
}
|
|
else {
|
|
noteClock = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
} /* End event loop */
|
|
return 0; /* This line is never reached */
|
|
}
|