This shows you the differences between two versions of the page.
pm:prj2023:dene:pedalaefectechitara [2023/05/25 20:25] stefan_dragos.badea [Rezultate Obţinute] |
pm:prj2023:dene:pedalaefectechitara [2023/05/27 18:00] (current) stefan_dragos.badea [Download] |
||
---|---|---|---|
Line 27: | Line 27: | ||
Placuta va prelua semnalul analogic dat de chitara si il va converti in semnal digital folosind ADC-ul integrat. Initial placuta reda sunetul clean, efecte putand fi activate/dezactivate din telecomanda. Semnalul digital modificat se transmite la DAC-ul extern prin I2C, de unde pleaca mai departe la modalitatea de output (amplificator/interfara audio). | Placuta va prelua semnalul analogic dat de chitara si il va converti in semnal digital folosind ADC-ul integrat. Initial placuta reda sunetul clean, efecte putand fi activate/dezactivate din telecomanda. Semnalul digital modificat se transmite la DAC-ul extern prin I2C, de unde pleaca mai departe la modalitatea de output (amplificator/interfara audio). | ||
- | Semnalul analogic va fi filtrat prin cateva filtre trece sus/jos. | + | Semnalul analogic este filtrat atat la intrare cat si la iesire. Intrarea trece pentr-un filtru trece sus care blocheaza frecventele de sub ~66Hz. Iesirea trece printr-un filtru trece-jos ce blocheaza frecventele peste ~16kHz. |
{{:pm:prj2023:dene:hardware.png|}} | {{:pm:prj2023:dene:hardware.png|}} | ||
Line 41: | Line 41: | ||
* https://github.com/Arduino-IRremote/Arduino-IRremote | * https://github.com/Arduino-IRremote/Arduino-IRremote | ||
- | Planuiesc sa implementez mai multe efecte de sunet, printre care: | + | == Intrare: == |
- | * distortion | + | Intrarea se face prin ADC-ul integrat in placa, cu voltajul de referinta intern de 1.1V. Modulul DAC are o rezolutie de doar 8 biti asa ca primul pas dupa citire este sa tarnsform numerele pe 10 biti in 8 biti, dupa care sa aplic efectele de sunet. |
- | * tremolo | + | <code C> |
- | * flanger | + | unsigned int sensorValue = analogRead(A0); |
- | * echo | + | sensorValue = (sensorValue + 1) / 4 - 1; |
+ | </code> | ||
+ | |||
+ | |||
+ | == Senzorul si telecomanda IR: == | ||
+ | Fiecare buton de pe telecomanda este mapat la un numar de 2 cifre. Pentru a selecta/deselecta fiecare efect, folosesc un vector ca un map. Daca valoarea din map pentru un buton este 0, efectul este oprit, altfel este pornit. Butonul '0' dezactiveaza toate efectele. | ||
+ | <code C> | ||
+ | int pressed_key = IrReceiver.decodedIRData.command; | ||
+ | if (pressed_key != IR_BUTTON_0) | ||
+ | activeEffects[pressed_key] = ~activeEffects[pressed_key]; | ||
+ | else | ||
+ | memset(activeEffects, 0, sizeof(activeEffects)); | ||
+ | </code> | ||
+ | |||
+ | == Efecte: == | ||
+ | In spatele efectelor sta o matematica destul de simpla folosita pentru a altera semnalul. Am implementat 4 efecte: distiortion, tremolo, flanger si echo. | ||
+ | |||
+ | Distortion se realizeaza prin cresterea/supraincarcarea semnalului audio printr-o functie simpla. | ||
+ | <code C> | ||
+ | float apply_distortion(float x) { | ||
+ | float y = 1; | ||
+ | |||
+ | if (x < 0.33f) | ||
+ | y = 2.3 * x; | ||
+ | | ||
+ | else if (x < 0.66f) | ||
+ | y = (3 - (2 - 3 * x) * (2 - 3 * x)) / 3; | ||
+ | |||
+ | return y; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Tremolo presupune combinarea semnalului cu o fucntie sinusoidala. Am folosit contorul 'index' pentru simularea trecerii timpului. | ||
+ | <code C> | ||
+ | int index = 0; | ||
+ | float apply_tremolo(float x) { | ||
+ | index++; | ||
+ | float Fs = TIMER_1HZ / 8; | ||
+ | float Fx = 5; | ||
+ | float alpha = 0.35; | ||
+ | float trem = (1 + alpha * sin(2 * M_PI * index * (Fx / Fs))); | ||
+ | float y = trem * x; | ||
+ | |||
+ | return y; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Pentru celelalte 2 efecte am avut nevoie de valorile anterioare ale semnalului asa ca am pastrat un vector cu acestea. Pentru a economisi memorie si tinand cont ca valorile cu care lucrez sunt pe 8 biti din cauza rezolutiei DAC-ului extern, acest vector este cu elemnte tip 'char'. | ||
+ | |||
+ | Flanger este un efect ce presupune redarea in acelasi timp a 2 semnale identice cu un delay variabil intre ele. Pentru simularea trecerii timpului am folosit aceeasi idee ca la tremolo, contorul 'index2'. | ||
+ | <code C> | ||
+ | float flanger_delay = 0.04f; | ||
+ | float flanger_depth = 0.5f; | ||
+ | int index2 = 0; | ||
+ | float apply_flanger(float x) { | ||
+ | index2++; | ||
+ | float Fs = TIMER_1HZ; | ||
+ | float rate = 1.0; | ||
+ | float max_sample_delay = flanger_delay * MAX_OUTPUT_HISTORY; | ||
+ | float current_sin = fabs(sin(2 * M_PI * index2 * (rate / Fs))); | ||
+ | int current_delay = (int)ceil(current_sin * max_sample_delay); | ||
+ | |||
+ | float out_delayed = (float)output_history[(output_history_last + (MAX_OUTPUT_HISTORY - 1) - current_delay) % MAX_OUTPUT_HISTORY]; | ||
+ | out_delayed /= SGN_MAX; | ||
+ | |||
+ | return (1 - flanger_depth) * x + flanger_depth * out_delayed; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | In final, echo presupune memorarea semnalului si redarea lui cu un delay. | ||
+ | <code C> | ||
+ | int echo_delay = 350; | ||
+ | float echo_depth = 0.4f; | ||
+ | float apply_echo(float x) { | ||
+ | float out_delayed = (float)output_history[(output_history_last + (MAX_OUTPUT_HISTORY - 1) - echo_delay) % MAX_OUTPUT_HISTORY]; | ||
+ | out_delayed /= SGN_MAX; | ||
+ | |||
+ | return (1 - echo_depth) * x + echo_depth * out_delayed; | ||
+ | } | ||
+ | </code> | ||
===== Rezultate Obţinute ===== | ===== Rezultate Obţinute ===== | ||
{{:pm:prj2023:dene:poza_proiect_1.jpeg?350 |}} | {{:pm:prj2023:dene:poza_proiect_1.jpeg?350 |}} | ||
- | |||
{{:pm:prj2023:dene:poza_proiect_2.jpeg?350|}} | {{:pm:prj2023:dene:poza_proiect_2.jpeg?350|}} | ||
+ | {{:pm:prj2023:dene:poza_proiect_3.jpeg?350 |}} | ||
+ | {{:pm:prj2023:dene:remotelayout.png?350|}} | ||
- | {{:pm:prj2023:dene:poza_proiect_3.jpeg?350|}} | ||
- | {{:pm:prj2023:dene:remotelayout.png?350 |}} | ||
- | ===== Concluzii ===== | ||
- | ===== Download ===== | ||
+ | ===== Concluzii ===== | ||
+ | Am invatat destul de multe si despre arduino si despre procesarea audio real-time si sunt multumit de rezultat. | ||
+ | ===== Download ===== | ||
+ | {{:pm:prj2023:dene:proiectpm.zip|}} | ||