Cu cât bitrate-ul fluxului de date este mai mic, cu atât mai mult poate fi transmis. Dacă puteți comprima vocea la 1-2 kB / s, puteți comunica la o distanță de până la 25 km (utilizând transmițătorul CC1125). Să încercăm să vă dezvoltăm singur un codec vocal, fără a utiliza soluții gata făcute cum ar fi codec2.
Cum funcționează vocea? Există mai multe elemente în ea:
- sunete vocale
- consonanțe - zgomot - exploziv: n, k, t ...
- consonanțe - zgomot - fricatives / wheezing: s, w, w, f, în ...
- consonanți - sonori - tremurând: p
- consonanți - sonori - nazali: m, n
Sunetele vocale pot fi considerate ca sunete muzicale - este un ton pur + tonurile lui de amplitudine variabilă. Sunetele consonante sunt sunete de zgomot cu timbre diferite și sonor (ton + zgomot).
Vocile și consoanele diferă în informativitatea lor, compara:
Ironia este că sunetele vocale sunt foarte ușor de descris cu un set mic de parametri. Ei au frecvențe de frecvență pas nonmultiple, astfel încât toată descrierea se reduce la câteva valori: + armonici de frecvență pas amplitudine. Iar frecvența dominantă trebuie măsurată cu precizie (cu o precizie de 16 biți), dar amplitudinile armonicelor tolerate și decimare foarte puternic - prin urmare, fiecare amplitudine poate fi comprimat la 1 octet sau ciuguli.
Să începem cu vocalele, deoarece sunt atât de ușor de descris. Am dezvoltat un algoritm pe Python, pur și simplu pentru că este foarte rapid și ușor.
Citirea unui fișier de sunet
Am înregistrat sunetul "a" în propriul meu spectacol și în performanța fetei și l-am păstrat brut cu dicretizare de 8kHz, sub forma unui semnal întreg pe 16 biți cu Audacity. Să facem o funcție pentru citirea unui astfel de fișier:
Salvez doar 800 conte, adică 100 ms de sunet - pe un astfel de segment puteți primi încă un semnal staționar, neschimbat. Următoarele cadre vor fi apoi analizate de pasajele următoare ale algoritmului. Să construim oscilograma sunetului recepționat:
Spectrul de construcție
Calculăm transformarea Fourier pentru sunetul rezultat. Fourier returnează amplitudinea complexă din care poate fi calculată amplitudinea și faza. Urechea este practic insensibilă la fază, astfel încât putem salva jumătate din bitrate, complet eliminându-l - lăsând doar amplitudinea, calculându-l cu funcția abs.
Spectru frumos, nu? Să creștem fragmentul care ne interesează:
Tonul principal și tonurile lui sunt vizibile, spectrul are o structură periodică.
Poziția fiecărui vârf este determinată de relația: freq = samples / period. Abcesul vârfului este egal cu raportul dintre lungimea cadrului în eșantioane (în cazul nostru 800) și perioada de undă.
Cu toate acestea, există o problemă: dacă luați pur sinusoidală cu o frecvență care nu se încadrează într-o grilă de frecvență selectată, aceasta nu devine un impuls delta după transformare Fourier (un singur vârf), iar unele figura unse:
Pentru a reduce acest efect, este necesar să se aplice semnalului așa-numita "fereastră". Voi multiplica semnalul pe fereastra lui Hanning.
Linia roșie - spectrul semnalului sursă, spectrul verde al semnalului cu fereastra Hanning:
A devenit mult mai bine: vârfurile sunt mai proeminente, jumătatea lățimii lor este mai mică și în spectru există mai puțin zgomot.
Construirea unui cepstrum
Aici puteți vedea tot ce avem nevoie, dar cum să găsim programatic vârfurile și amplitudinile lor? Este nerecunoscător să trecem prin căutarea obișnuită a unui maxim local: vârfurile pot fi ușor schimbate, duplicate, astfel încât vom găsi doar întreaga parte a perioadei și poate fi fracționată. Cum determinăm apoi această perioadă? În același mod în care am definit perioadele din semnalul audio original, transformarea Fourier. Numai trebuie mai întâi să logaritmizăm spectrul nostru pentru a evidenția mai puternic vârfurile.
Și aplicați transformarea Fourier la aceasta:
Ceea ce am construit este numit cuvântul rece "Cepstrum" - din numele este clar că aceasta este ceva de genul inversării spectrului.
Găsirea frecvenței fundamentale
În ea avem nevoie doar de primul vârf, a cărui poziție va fi exact egală cu perioada tonului fundamental dorit. Vom găsi acest vârf prin căutarea obișnuită a maximului global, limitând căutarea la frecvențe de 80..270 Hz, deoarece în acest interval se află frecvențele de bază ale vocii adulților. În cazul nostru, acesta este intervalul perioadelor 30..100 (8000 / 270..8000 / 80).
În cazul meu, frecvența fundamentală era de 113 Hz, iar prietena mea - exact 200 Hz, care este bine corelată cu citatul din Wikipedia:
Înregistrarea se suprapune
Totul, acum puteți să vă întoarceți la spectru, să treceți prin toate armonicile frecvenței fundamentale găsite și să înregistrați amplitudinea lor. Extinde ușor benzile de frecvență ale suprasolicitării pentru a găsi suma vârfului (deoarece vârfurile sunt murdare din cauza neconcordanței rețelei de frecvență cu frecvența fundamentală).
Chiar și a noua armonică are o amplitudine comparabilă cu amplitudinea frecvenței fundamentale, deci trebuie să înregistrați o mulțime de duri, cel puțin 8-10. Pe de altă parte, este suficient să ne limităm la o bandă de 4 kHz, armonice mai mari nu mai sunt necesare pentru transmisia vocii.
Parametrul de ambalare
Pentru a descrie un cadru cu o voce (10ms în cazul nostru) este necesar:
- frecvența fundamentală - 2 octeți
- N * amplitudine de suprapunere - N / 2 octeți
De obicei, nu mai mult de 10 tonuri de ton, adică caracteristica va dura 2 + 5 = 7 octeți. Cadrul original a cântărit 1600 de octeți, adică raportul de compresie este
De 230 de ori. Dar trebuie să înțelegem că am doar squeeze sunete vocale, sunt încă consoane care, după cum spunea norocul, transmit mai multe informații.
Despachetarea sunetului și compararea
Decompresia sunetului ar putea fi făcută prin transformarea inversă Fourier, dar o vom face și mai ușor - generând sinusoide ale frecvențelor și amplitudinilor corecte și le-am pus pe toate împreună.
Deschideți fișierul sursă în Audacity și restaurați și comparați formele de undă:
Destul de similar. Pe de ascultare prea este similară, iar 10 armonici sună mult mai bine decât 8.