#include "effects.h" #define TESTING 0 #define REVERB 1 #define CHORUS 2 #define FLANGER 3 #define ECHO 4 #define DISTORTION 5 #define TREMOLO 6 volatile uint8_t sampleReady = 0; //zmienna kotrolująca możliwość podania nowej wartości do DAC volatile uint8_t adcVal = 0; volatile uint8_t effect = REVERB; //wybrany efekt volatile uint32_t counter = 0; const uint8_t sine [101] = {0,0,0,0,1,1,2,2,3,4,5,6,7,8,10,11,12,14,16,17,19,21,23,25,27,29,32,34,36,39,41,44,46,49, 52,55,57,60,63,66,69,72,75,78,81,84,87,91,94,97,100,103,106,109,113,116,119,122,125,128,131,134,137,140,143,145,148, 151,154,156,159,161,164,166,168,171,173,175,177,179,181,183,184,186,188,189,190,192,193,194,195,196,197,198,198,199, 199,200,200,200,200}; volatile uint8_t effectSetting = 5; const uint8_t effectSettingVector [9] = {0, 5, 15, 30, 55, 90, 130, 180, 255}; volatile uint8_t encoderDir = 0; //0 - w lewo, 1 - w prawo volatile uint8_t encoderServed = 1; //timer0 służy tylko do aktywacji odczytu przez ADC (i do debouncingu) ISR(TIMER0_COMPA_vect){ counter++; } ISR(TIMER1_OVF_vect){ OCR1A = effectSettingVector[effectSetting -1];//20 * effectSetting - 15; //od 25 do 225 } ISR(INT0_vect){ if(encoderServed){ if(!(PIND & 0x08)){ encoderDir = 0; } else if(PIND & 0x08){ encoderDir = 1; } encoderServed = 0; } } ISR(ADC_vect){ adcVal = ADCH; sampleReady = 1; //dopiero po odczytaniu nowej wartości ADC uruchomiona jest możliwość podania nowej wartości do DAC } int main(void){ //wyprowadzenie do sterowania wejsciem sygnalu nieprzetworzonego DDRC |= 1<= _50MS){ if(!(PIND & 0x10) && !buttonPressed){ //Jeżeli przed zmianą na echo znajduje się coś w buforze, to istnieje ryzyko wystąpienia zapętlenia próbki, //stąd zerowanie buforu. if(effect == ECHO - 1) { for(uint16_t i = 0; i < BUFFER_LENGTH; i++){ buffer[i] = 128; } } effect++; if(effect > TREMOLO) effect = REVERB; buttonPressed = 1; } else if(PIND & 0x10 && buttonPressed) buttonPressed = 0; counterButton = counter; } //obsługa przycisku od aktywacji efektu i diody sygnalizującej aktywację efektu if(counter - counterButton2 >= _50MS){ if(!(PIND & 0x02) && !buttonPressed2){ if(effectOn){ effectOn = 0; PORTB &= ~(1<= _20MS && !encoderServed){ if(encoderDir == 1){ if(effectSetting < 9) effectSetting++; } else { if(effectSetting > 1) effectSetting--; } counterEncoder = counter; encoderServed = 1; } if(sampleReady){ if(effect < ECHO) buffer[bufferIndex] = adcVal; //zapisanie aktualnej próbki na najnowszą pozycję w buforze //pod warunkiem że efekt to REVERB, CHORUS lub FLANGER if(effect == TESTING){ valueToSend = adcVal; PORTD &= ~((1<= 200){ if(chorusDirChange == 0){ sineIndex++; if(sineIndex >= 100) chorusDirChange = 1; } else { sineIndex--; if(sineIndex == 0) chorusDirChange = 0; } chorusCounter = 0; } PORTD |= (1<= 100){ if(flangerDirChange == 0){ flangerDelayTime++; if(flangerDelayTime >= _10MS) flangerDirChange = 1; } else { flangerDelayTime--; if(flangerDelayTime == _0MS) flangerDirChange = 0; } flangerCounter = 0; } PORTD |= (1< BUFFER_LENGTH) echoIndex -= BUFFER_LENGTH; buffer[echoIndex] = (adcVal - 128)/2 + 2*(buffer[bufferIndex] - 128)/3 + 128; // wpisanie z opóźnieniem i tłumieniem aktualnej wartości valueToSend = buffer[bufferIndex]; PORTD |= (1<= 1 + effectSetting){ if(tremoloDirChange == 0){ sineIndex++; if(sineIndex >= 100) tremoloDirChange = 1; } else { sineIndex--; if(sineIndex == 0) tremoloDirChange = 0; } tremoloCounter = 0; } PORTD |= (1< 255){ valueToSend = 255; } else if(valueToSend < 0){ valueToSend = 0; } if (effectOn) { analogWrite(valueToSend); } else { analogWrite(128); } sampleReady = 0; //zmiana indeksu dla kolejnej próbki bufferIndex++; if(bufferIndex >= BUFFER_LENGTH) bufferIndex = 0; } } } //Wykorzystana pamięć //sampleReady = 1 B //adcVal = 1 B //effect = 1 B //counter = 4 B //sine = 101 B //effectSetting = 1 B //effectSettingVector = 9 B //encoderLeft = 1 B //encoderRight = 1 B //encoderServed = 1 B //valueToSend = 2 B //bufor = 1851 B //bufferIndex = 2 B //counterButton1 = 4 B //buttonPressed1 = 1 B //counterButton2 = 4 B //buttonPressed2 = 1 B //effectOn = 1 B //counterEncoder = 4 B //chorusSineIndex = 1 B //chorusCounter = 1 B //chorusDirChange = 1 B //flangerDelayTime = 1 B //flangerCounter = 1 B //flangerDirChange = 1 B //echoIndex = 2 B //14 zmiennych w reverbie //echo#Index... = 14 B (7x2 B) //echo#Temp... = 14 B (7x2 B) //3 zmienne w chorusie/flangerze //echoIndex = 2 B //echoTemp = 2 B //W najgorszym przypadku łącznie: 2031 B //Pozostaje: (2048 - 2031) B = 17 B