/* 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 */ }