commit 8d3482ec6fe2edd3a2279c2d1a688db806fc5952 Author: mikolaj.s <228592@edu.p.lodz.pl> Date: Wed Jun 1 08:34:17 2022 +0200 dodanie plikow diff --git a/MCP4xxx.h b/MCP4xxx.h new file mode 100644 index 0000000..58bcaec --- /dev/null +++ b/MCP4xxx.h @@ -0,0 +1,21 @@ +#include "spi.h" + +/* +#define nWR 7 //bit aktywacja zapisu do rejestru przetwornika +#define DC 6 //bit nieużywany (Don't Care) +#define GA 5 //bit wyboru wzmocnienia +#define SHDN 4 //bit aktywacji wyjścia + +#define GAIN_X1 1 +#define GAIN_X2 0 +*/ + +#define CONF1 0b00110000 //gain x1 +#define CONF2 0b00010000 //gain x2 + +void analogWrite(uint8_t data){ + SS_LOW; + spiTransfer(CONF1 | (data>>4)); + spiTransfer(data<<4); + SS_HIGH; +} \ No newline at end of file diff --git a/effects.h b/effects.h new file mode 100644 index 0000000..e51f052 --- /dev/null +++ b/effects.h @@ -0,0 +1,109 @@ +#include "MCP4xxx.h" + +#define BUFFER_LENGTH 1851 +//Przeliczenie przesunięcia w próbkach na czas dla fs = 10 kHz +#define _0MS 0 +#define _1MS 10 +#define _5MS 50 +#define _10MS 100 +#define _15MS 150 +#define _16MS 160 +#define _18MS 180 +#define _20MS 200 +#define _23MS 230 +#define _25MS 250 +#define _30MS 300 +#define _35MS 350 +#define _40MS 400 +#define _41MS 410 +#define _50MS 500 +#define _60MS 600 +#define _70MS 700 +#define _80MS 800 +#define _85MS 850 +#define _90MS 900 +#define _100MS 1000 +#define _105MS 1050 +#define _110MS 1100 +#define _120MS 1200 +#define _135MS 1350 +#define _140MS 1400 +#define _150MS 1500 +#define _160MS 1600 +#define _170MS 1700 +#define _175MS 1750 +#define _180MS 1800 +#define _185MS 1850 + + +int16_t reverb(uint8_t buffer [BUFFER_LENGTH], uint16_t bufferIndex, uint8_t roomSize){ + int16_t echo1Index = bufferIndex - _35MS; + if(echo1Index < 0) echo1Index += BUFFER_LENGTH; + int16_t echo2Index = bufferIndex - _60MS; + if(echo2Index < 0) echo2Index += BUFFER_LENGTH; + int16_t echo3Index = bufferIndex - _85MS; + if(echo3Index < 0) echo3Index += BUFFER_LENGTH; + int16_t echo4Index = bufferIndex - _110MS; + if(echo4Index < 0) echo4Index += BUFFER_LENGTH; + int16_t echo5Index = bufferIndex - _135MS; + if(echo5Index < 0) echo5Index += BUFFER_LENGTH; + int16_t echo6Index = bufferIndex - _160MS; + if(echo6Index < 0) echo6Index += BUFFER_LENGTH; + int16_t echo7Index = bufferIndex - _185MS; + if(echo6Index < 0) echo7Index += BUFFER_LENGTH; + + //wyznaczenie zmiennych tymczasowych (bez składowych stałych) + int16_t echo1Temp = -128 + buffer[echo1Index]; + int16_t echo2Temp = -128 + buffer[echo2Index]; + int16_t echo3Temp = -128 + buffer[echo3Index]; + int16_t echo4Temp = -128 + buffer[echo4Index]; + int16_t echo5Temp = -128 + buffer[echo5Index]; + int16_t echo6Temp = -128 + buffer[echo6Index]; + int16_t echo7Temp = -128 + buffer[echo6Index]; + + //obliczenie wartości próbki do przekazania DAC i przywrócenie składowej stałej + if(roomSize == 1){ + return (1*echo1Temp + 3*echo2Temp + 2*echo3Temp)/30 +128; + } else if(roomSize == 2){ + return (1*echo1Temp + 3*echo2Temp + 2*echo3Temp + 2*echo4Temp)/30 +128; + } else if(roomSize == 3){ + return (1*echo1Temp + 3*echo2Temp + 3*echo3Temp + 2*echo4Temp + 1*echo5Temp)/30 +128; + } else if(roomSize == 4){ + return (2*echo1Temp + 4*echo2Temp + 3*echo3Temp + 2*echo4Temp + 1*echo5Temp)/30 +128; + } else if(roomSize == 5){ + return (2*echo1Temp + 4*echo2Temp + 3*echo3Temp + 3*echo4Temp + 2*echo5Temp + 1*echo6Temp)/30 +128; + } else if(roomSize == 6){ + return (2*echo1Temp + 5*echo2Temp + 4*echo3Temp + 3*echo4Temp + 3*echo5Temp + 1*echo6Temp)/30 +128; + } else if(roomSize == 7){ + return (2*echo1Temp + 5*echo2Temp + 5*echo3Temp + 4*echo4Temp + 3*echo5Temp + 2*echo6Temp + 1*echo7Temp)/30 +128; + } else if(roomSize == 8){ + return (3*echo1Temp + 6*echo2Temp + 5*echo3Temp + 4*echo4Temp + 4*echo5Temp + 2*echo6Temp + 2*echo7Temp)/30 +128; + } else { + return (3*echo1Temp + 7*echo2Temp + 6*echo3Temp + 5*echo4Temp + 4*echo5Temp + 3*echo6Temp + 2*echo7Temp)/30 +128; + } + + +} + + +int16_t distortion(uint8_t cutoff, uint8_t adcVal){ + //jeżeli wartość przekracza ustawiony próg, to jest ona do nigo zmniejszana (ucinanie górnej części przebiegu) + if (adcVal > cutoff){ + return cutoff; + } else { + return adcVal; + } +} + + +int16_t chorusFlanger(uint8_t buffer [BUFFER_LENGTH], uint16_t bufferIndex, uint16_t delayVal, uint8_t attenuationLevel){ + int16_t echoIndex = bufferIndex - delayVal; + if(echoIndex < 0) echoIndex += BUFFER_LENGTH; + int16_t echoTemp = -128 + buffer[echoIndex]; + + return echoTemp/(1+attenuationLevel) + 128; +} + +int16_t tremolo(uint8_t adcVal, uint8_t amplitudeLevel){ + return ((adcVal - 128)*(amplitudeLevel+70))/271 + 128; +} \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..f8b0c03 --- /dev/null +++ b/main.cpp @@ -0,0 +1,356 @@ +#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 \ No newline at end of file diff --git a/spi.h b/spi.h new file mode 100644 index 0000000..11f4e69 --- /dev/null +++ b/spi.h @@ -0,0 +1,63 @@ +#include +#include + +#define SS_LOW PORTB &= ~(1<