Soluții

“Murdarire” audio cu amprenta microfonului

Am creat acest script pentru a rezolva o problemă fundamentală: modelul AI era antrenat pe sunete curate, înregistrate profesional, dar pe dispozitiv primea sunete „murdărite” de caracteristicile microfonului intern al ESP32. Microfonul acesta nu este unul de studio — are o răspuns în frecvență limitat, introduce un zgomot de fond propriu și colorează sunetul într-un mod specific. Din cauza asta, aceeași împușcătură sau sirenă suna diferit în datele de antrenare față de ce auzea dispozitivul în realitate, iar modelul nu le mai recunoștea corect.

Soluția: am „murdărit” datele de antrenare ca să semene cu ce aude microfonul

1. Am calculat amprenta acustică a microfonului

Am redat un semnal de test cunoscut (un sweep de frecvențe) prin difuzor și l-am înregistrat cu microfonul ESP32. Comparând semnalul original curat cu cel înregistrat, am extras prin deconvoluție ceea ce se numește „răspuns la impuls” — practic amprenta acustică a microfonului, care descrie exact cum modifică el sunetul (ce frecvențe le atenuează, ce frecvențe le amplifică, ce distorsiuni introduce).

2. Am aplicat această amprentă peste toate datele de antrenare

Am luat fiecare fișier audio din setul de date și l-am trecut prin convoluție cu acest răspuns la impuls. Efectul este ca și cum acel sunet ar fi fost înregistrat direct cu microfonul ESP32, chiar dacă inițial era un fișier curat descărcat de pe internet.

3. Am limitat banda de frecvențe

Microfonul ESP32 nu captează fidel frecvențe foarte joase sau foarte înalte. Am aplicat un filtru care păstrează doar frecvențele între 100 Hz și 7000 Hz, simulând limitările reale ale hardware-ului.

4. Am aplicat compresie

Microfonul și circuitul analogic al dispozitivului introduc o ușoară compresie naturală — sunetele foarte puternice nu cresc proporțional, ci se „saturează” ușor. Am simulat acest efect printr-o funcție matematică de compresie.

5. Am adăugat zgomot de fond real

Am înregistrat liniștea cu ESP32 — chiar și când nu e niciun sunet, microfonul produce un zgomot de fond slab, caracteristic. Am amestecat acest zgomot peste fiecare fișier audio de antrenare, la intensități variate, pentru ca modelul să învețe să ignore acest zgomot de fond și să se concentreze pe sunetele importante.

6. Am variat volumul

În realitate, sunetele ajung la microfon la volume diferite în funcție de distanță și mediu. Am aplicat o amplificare aleatorie pentru fiecare fișier, astfel încât modelul să nu depindă de un anumit nivel de volum.

De ce este nevoie de acest pas

Fără el, modelul ar fi fost antrenat într-o „lume ideală” a sunetelor curate, dar ar fi funcționat pe un dispozitiv care aude lumea printr-un microfon imperfect. Este ca și cum ai antrena pe cineva să recunoască mașini uitându-se la fotografii profesionale, dar apoi îi ceri să le recunoască printr-o cameră de supraveghere neclară și cu zgomot.

Prin aplicarea acestor transformări, am adus datele de antrenare cât mai aproape de condițiile reale, iar modelul a învățat să recunoască sunete exact așa cum le aude dispozitivul — cu toate imperfecțiunile incluse. Acest lucru a îmbunătățit semnificativ acuratețea clasificării pe dispozitiv.

[mai mult...]

Echivalenta matematica Python-Arduino

Am asigurat echivalența matematică dintre calculul spectrogramei mel din Python și cel de pe microcontroler prin mai multe strategii concrete:

1. Parametri identici

Am pornit de la aceiași parametri exacti în ambele medii: rată de eșantionare de 16kHz, FFT de 512 puncte, fereastră de 30ms (480 eșantioane), hop de 10ms (160 eșantioane) și 40 de benzi mel.

2. Filterbank-ul mel — exportat direct din Python

În loc să reimplementez manual formulele de calcul al benzilor mel pe microcontroler (unde orice diferență mică de rotunjire ar fi alterat rezultatele), am generat filterbank-ul direct în Python folosind librosa, cu setările sale implicite. Rezultatul — o matrice de 40×257 valori — l-am salvat cu 8 zecimale de precizie într-un format pe care microcontrolerul îl poate citi direct. Astfel, dispozitivul folosește exact aceiași coeficienți numerici ca Python, fără nicio aproximare.

3. Fereastra Hann — aceeași formulă

Am replicat pe microcontroler aceeași formulă matematică de fereastră Hann simetrică pe care o folosește librosa, cu același divisor, producând valori identice.

4. FFT și spectrul de putere — aceeași secvență de operații

Pe microcontroler, pentru fiecare cadru: aplic fereastra Hann, completez cu zerouri, rulez transformata Fourier, apoi calculez spectrul de putere ca suma pătratelor părților reale și imaginare. În Python, am configurat librosa să facă exact același lucru, inclusiv dezactivarea padding-ului simetric la capetele semnalului — un detaliu critic, pentru că altfel Python ar fi generat cadre decalate și un număr diferit de frame-uri.

5. Conversia în decibeli și normalizarea — aceeași formulă, aceleași praguri

Atât pe microcontroler cât și în Python, aplic aceeași secvență: convertesc puterea în decibeli cu același epsilon mic pentru a preveni logaritmul din zero, limitez valorile la intervalul de la -80 la 0 decibeli, apoi normalizez totul în intervalul 0–1 prin aceeași formulă liniară.

6. Verificare pas cu pas

Am scris un script Python care reproduce pas cu pas exact ce face microcontrolerul: încarcă audio, convertește la virgulă mobilă, calculează volumul, aplică filtrul de liniște, calculează spectrograma cadru cu cadru prin aceeași buclă manuală. Fiecare pas intermediar este afișat în același format ca pe dispozitiv, astfel încât pot compara linie cu linie valorile și identifica orice divergență.

7. Antrenarea modelului pe date procesate identic

Ca să mă asigur că modelul AI a fost antrenat pe aceleași tipuri de spectrograme pe care le va primi pe dispozitiv, am preprocesat toate datele de antrenare în Python cu exact aceiași parametri și aceeași formulă de conversie și normalizare. Astfel, modelul a „văzut” în antrenare exact același tip de reprezentare pe care o primește și pe dispozitiv.

Pe scurt: nu am reimplementat independent matematica pe microcontroler, ci am exportat componentele critice direct din Python, am replicat doar operațiile aritmetice simple cu aceleași formule și constante, și am construit un sistem de verificare care compară valoare cu valoare rezultatele intermediare dintre cele două medii.

[mai mult...]