LabWindows/CVI · Limbaj C · Analiza in Domeniul Timp si Frecventa
Autor: Bliah Stefan Matei
Facultatea de Automatica si Calculatoare, specializarea CTI — Anul III
Aplicatie desktop dezvoltata in LabWindows/CVI (National Instruments) folosind limbajul C, destinata incarcarii, procesarii si vizualizarii semnalelor audio din fisiere .WAV. Aplicatia realizeaza analiza semnalului atat in domeniul timp (operatii spatiale asupra amplitudinii), cat si in domeniul frecventa, printr-o interfata grafica interactiva cu redare si salvare in timp real.
Fisierul de intrare (01.wav) este un semnal audio cu 4 canale, 16-bit PCM. Se extrage exclusiv Canalul 1, prin indexare modulo (cnt % 4 == 0), cu durata limitata configurabil (DURATA_MAX = 10s, INTERVAL_MAX = 6).
Radacina proiect
├── Bliah_Stefan_1309A_APD-P.c # Logica principala si callback-urile UI
├── Bliah_Stefan_1309A_APD-P.h # Definitii resurse UI (generat automat de CVI)
├── Bliah_Stefan_1309A_APD-P.cws # Fisier Workspace LabWindows/CVI
├── Bliah_Stefan_1309A_APD-P.prj # Fisier Project LabWindows/CVI
├── Bliah_Stefan_1309A_APD-P.uir # Layout GUI (panouri, grafice, controale)
├── 01.wav # Fisier audio de intrare (4 canale, 16-bit PCM)
├── waveData.txt # Esantioane Canal 1 — generat de main.py
├── DOC_APD_P_BLIAH-1.pdf # Documentatia completa a proiectului
├── main.py # Python: extrage datele WAV in waveData.txt (SciPy)
├── count_channels.py # Python: verifica numarul de canale din fisierul WAV
├── Image\ # Capturi .jpg domeniu timp (creat automat la rulare)
└── Fourier_<timestamp>\ # Export grafice domeniu frecventa (creat automat la rulare)
Toti parametrii sunt calculati in cadrul unui singur parcurs al semnalului in functia ExtractData(), minimizand overhead-ul de memorie. Semnalul este stocat intr-un buffer double* alocat dinamic.
Reprezinta componenta de curent continuu (DC) a semnalului. Acumulata inline in timpul citirii, normalizata dupa incheierea buclei.
medie += number;
// dupa bucla:
medie = medie / (i - 1);Rezultat: -0.37 — offset DC neglijabil; semnalul oscileaza simetric in jurul valorii zero.
Urmarite intr-un singur parcurs, cu inregistrarea indexului pentru localizarea exacta in semnal.
if (minim > number) { minim = number; idxMin = i - 1; }
if (maxim < number) { maxim = number; idxMax = i - 1; }Rezultate: Min = -11268.00 la esantionul #12415 · Max = 11845.00 la esantionul #11505.
Intervalul de variatie semnificativ sugereaza prezenta unor componente tonice ascutite.
Media patratelor deviatiilor fata de medie. Calculata intr-un al doilea parcurs dupa ExtractData().
for (int j = 0; j < i; j++)
dispersie += (buff[j] - medie) * (buff[j] - medie);
dispersie /= i;Rezultat: 797748.27 — variatie larga a amplitudinii, consistenta cu un zgomot alb.
Buffer-ul este copiat (non-distructiv), sortat cu qsort — O(n log n) — dupa care este indexat elementul din mijloc.
memcpy(tmp, buff, n * sizeof(int));
qsort(tmp, n, sizeof(int), compare);
return (n % 2 != 0) ? tmp[n/2] : (tmp[n/2-1] + tmp[n/2]) / 2.0;Rezultat: 0.00 — distributie simetrica, componenta DC neglijabila.
Detectate prin verificarea semnului produsului a doua esantioane consecutive.
n2 = n1;
n1 = number;
if (n1 * n2 < 0) zero++;Rezultat: 47.325 de treceri — continut bogat de frecvente inalte, comportament specific zgomotului alb.
Masoara asimetria distributiei de probabilitate in jurul mediei. Calculat prin momentele statistice de ordinul 2 si 3, folosind functia Moment() din biblioteca NI analysis.h.
Skewness = moment_ordin_3 / pow(moment_ordin_2, 1.5);Rezultat: 0.14 — asimetrie pozitiva usoara; cateva valori de amplitudine mare intind coada distributiei spre dreapta.
Masoara ascutimea varfului distributiei si ponderea cozilor fata de o distributie normala. Calculat prin momentele de ordinul 2 si 4.
Kurtosis = moment_ordin_4 / pow(moment_ordin_2, 2);Rezultat: 3.48 — distributie leptocurtica (varf mai ascutit decat normalul); valorile sunt concentrate in jurul mediei cu prezenta unor varfuri semnificative.
Medie glisanta cauzala. La capetele bufferului sunt incluse doar esantioanele disponibile, evitand depasirea de index.
for (int k = i - range + 1; k <= i; k++) {
if (k >= 0) { s += data[k]; count++; }
}
filtered[i] = s / count;- Fereastra de 16 elemente: reducere moderata a zgomotului, pastreaza forma generala a semnalului.
- Fereastra de 32 de elemente: netezire mai puternica, atenuare mai mare a extremelor de inalta frecventa.
Filtru recursiv trece-jos cu parametrul alpha reglabil din interfata, aplicat prin callback-ul OnApplyAlpha.
filt[i] = (1 - alpha) * filt[i-1] + alpha * signal[i];| alpha | Efect |
|---|---|
| aproape 0 | Netezire puternica |
| 0.25 | Filtru trece-jos accentuat |
| 0.50 | Netezire moderata |
| 0.75 | Netezire usoara |
| 1.0 | Identitate — semnal original |
Traseaza contururile superior si inferior ale amplitudinii semnalului, captand variatiile lente fara oscilatiile rapide. Etapele de implementare:
- Detectarea maximelor si minimelor locale
- Filtrare prin prag pentru eliminarea varfurilor nesemnificative
- Interpolarea liniara intre extremele retinute pentru formarea curbelor superioara si inferioara
Rezultat: Anvelopele sunt aproape stationare — confirma structura uniforma a zgomotului.
Estimeaza rata instantanee de variatie a amplitudinii folosind formula derivatei centrate.
derivata[i] = (data[i + 1] - data[i - 1]) / (2.0 * dt);
// dt = 1.0 / sampleRateRezultat: Valori ale derivatei extrem de mari — variatii rapide ale amplitudinii, continut dominant de frecvente inalte, specific unui semnal cu zgomot.
Reprezinta distributia valorilor de amplitudine ale semnalului pe intervalul [minim, maxim]. Histograma obtinuta are forma de clopot, centrata in jurul valorii zero — confirma caracteristicile unui zgomot alb, cu un numar redus de valori extreme la capete.
Aplicata semnalului inainte de FFT pentru reducerea scurgerilor spectrale cauzate de discontinuitatile la marginile ferestrei. Dimensiunea ferestrei este selectabila ca putere a lui 2, de la 1024 pana la lungimea integrala a semnalului, printr-un control de tip inel in interfata.
Versiune modificata a ferestrei Hanning — continua la capete, reduce semnificativ scurgerile spectrale. Recomandata pentru semnale audio si de vorbire.
windowed[i] = sig[i] * (0.54 - 0.46 * cos((2 * M_PI * i) / (n - 1)));Fereastra cosinus cu 5 termeni — cea mai buna acuratete a amplitudinii dintre toate tipurile de ferestre. Preferata pentru masuratori precise ale amplitudinii unui ton unic; selectivitate redusa in frecventa.
windowed[i] = sig[i] * (0.21557895
- 0.41663158 * cos( wp*i / (n-1))
+ 0.277263158 * cos(2*wp*i / (n-1))
- 0.083578947 * cos(3*wp*i / (n-1))
+ 0.006947368 * cos(4*wp*i / (n-1)));Calculat cu functia AutoPowerSpectrum() din LabWindows, aplicata semnalului ferestruit. Axa de frecventa este reconstruita cu delta_f = 1 / (N x dt). Valorile frequencyPeak si powerPeak sunt extrase si afisate in timp real in controalele de tip string din interfata.
AutoPowerSpectrum(sig, total_samples, dt, autopwrSpectrum, &df);
PowerFrequencyEstimate(autopwrSpectrum, autoPwrSize, -1.0,
winConst, df, 7, &frequencyPeak, &powerPeak);Rezultate:
- Puterea distribuita pe o plaja larga de frecvente — confirma prezenta zgomotului
- Grupare dominanta in jurul frecventei ~5000 Hz — componenta tonica ascutita in semnal
- Power Peak:
4801.94la121.16 Hz— componenta de joasa frecventa persistenta
Ambele filtre sunt trece-sus, aplicate jumatatea superioara a spectrului (frecventa de taiere fc = sampleRate / 4.0). Selectia filtrului se face printr-un control de tip inel in panoul de frecventa.
Intarziere de grup maxim plata (raspuns de faza aproape liniar) — pastreaza forma semnalului in banda de trecere. Utilizat frecvent in crossovere audio unde fidelitatea formei de unda este esentiala.
Bssl_HPF(sig, nSamples, sampleRate, fc, order, filtrat);
// order = 4, fc = sampleRate / 4.0Cadere mai abrupta in afara benzii de trecere fata de Bessel, cu costul unor ondulatii de 0.5 dB in banda de trecere. Selectivitate superioara in frecventa; minimizeaza eroarea dintre caracteristica ideala si cea reala.
Ch_HPF(sig, nSamples, sampleRate, fc, ripple, order, filtrat);
// order = 6, ripple = 0.5 dB, fc = sampleRate / 4.0Panoul de frecventa suporta redare automata bazata pe timer — fereastra de analiza gliseaza prin semnal un cadru la fiecare tact al timerului. La fiecare tact (callback OnTimer):
winOffset += realWindowSize;
if (winOffset >= total_samples) winOffset = 0;Fiecare tact randeaza si salveaza automat 4 grafice intr-un folder cu timestamp prin SaveFourier():
| Graf | Continut |
|---|---|
| GRAPHP2 | Segment semnal brut |
| GRAPHP2_2 | Semnal brut + filtru aplicat |
| GRAPHP2_4 | Spectrul de putere (nefiltrat) |
| GRAPHP2_3 | Spectrul de putere (filtrat) |
Format denumire folder:
Fourier_YYYY_MM_DD___HH-MM-SS__ESANTIOANE_<start>_to_<stop>/
Navigarea manuala prin butoanele Prev/Next este disponibila si ea. Comutarea la modul manual dezactiveaza automat timerul.
| Parametru | Valoare | Interpretare |
|---|---|---|
| Media | -0.37 | Offset DC neglijabil |
| Minim | -11268.00 la esantionul #12415 | Amplitudine minima |
| Maxim | 11845.00 la esantionul #11505 | Amplitudine maxima |
| Dispersia | 797748.27 | Variatie larga de amplitudine |
| Mediana | 0.00 | Distributie simetrica |
| Treceri prin zero | 47.325 | Continut bogat de frecvente inalte |
| Skewness | 0.14 | Asimetrie pozitiva usoara |
| Kurtosis | 3.48 | Distributie leptocurtica |
| Power Peak | 4801.94 la 121.16 Hz | Componenta dominanta de joasa frecventa |
| Regiune spectrala dominanta | ~5000 Hz | Componenta tonica ascutita |
| Instrument | Rol |
|---|---|
| LabWindows/CVI (NI) | IDE, framework GUI, mediu de executie |
| C (ANSI C) | Limbaj principal de implementare |
| analysis.h / advanlys.h | FFT, filtre IIR, momente statistice, ferestruire (biblioteca NI) |
| Python + SciPy | Extractia datelor WAV in waveData.txt |
| Python + wave | Verificarea numarului de canale din fisierul WAV |
- Deschide
Bliah_Stefan_1309A_APD-P.cwsin LabWindows/CVI - Compileaza proiectul (
F7) - Plaseaza
01.wavin directorul radacina al proiectului - Ruleaza
main.pyo singura data pentru a generawaveData.txt - Porneste aplicatia si apasa butonul Load
Folderele Image\ si Fourier_* sunt create automat la rulare — nu este necesara nicio configurare manuala.
Documentatia completa a proiectului, cu grafice, capturi ale semnalului, fundament teoretic si rezultate detaliate:
DOC_APD_P_BLIAH-1.pdf