In [1]:
%pylab inline
import scipy.io.wavfile
from scipy.optimize import curve_fit
Populating the interactive namespace from numpy and matplotlib

Hangfeldolgozás 2

*Figyelem:* *,,A hangfeldolgozás 2.''* idén lett hadrendbe állítva, ezért a konstruktív hallgatói visszajelzések sokat segítenének a feladatok finomításában és véglegesítésében.

A hangminták rögzítésére az audacity programot használhatjuk. A felvett hangminta fájlokat ne felejtse a jegyzőkönyvhöz csatolni, a fájl feltöltésével.

Győződjön meg arról, hogy a külső hangkártya be van kapcsolva és a mikrofonokra fel van kapcsolva az úgy nevezett 48 V-os fantom táp. Az audacity-ben válassza ki a megfelelő bemeneti eszközt AudioBox 1818 VSL: USB Audio (hw 1,0): Line: 0.

1. feladat: A jel-zaj arány vizsgálata

1.1. Koordinátarendszer rögzítése

A laborvezető segítségével helyezze el a mikrofonokat. Jelöljön ki egy arra alkalmas viszonyítási rendszert, és rögzítse hogy abban a mikrofonoknak mi a helye.

A választott koordinátarendszer leírása:

  • Az origo helye: Az asztal hozzám képesti bal elülső sarka,
  • Az $x$-tengely: Az asztal hosszabbik oldalával párhuzamosan (az ablak felé),
  • Az $y$-tengely: Az asztal rövidebbik oldalával párhuzamosan (a másik terem felé),
  • A $z$-tengely: Függőlegesen felfelé.
Mikrofon száma $x$ [cm] $y$ [cm] $z$ [cm]
1. 55 10 0,5
2. 23 23 0,5
3. 152 50 56
4. 4 47 55
5. 8 66 1
6. 140 58 1
7. 140 10 1

A mikrofonok mérete, és a mérés pontatlansága miatt a mikrofonok koordinátáinak van kb. 1 cm bizonytalansága az $x-y$ irányba. $z$ irányban, mivel a mikrofonok az asztalon fekszenek, ezért csak a méretük okoz bizonytalanságot.

In [2]:
tavolsag = [56, 33, 170, 72, 66, 152, 140]

1.2. Háttér felvétele

Vizsgáljuk meg, hogy a teremben milyen teljesítménye van az alapzajnak. Az audacity felvételi monitorának segítségével állítsa be a hangkártya előerősítő fokozatait úgy, hogy ne legyen túlvezérelve a jel. Ebben segíthet, hogy az asztalra koppintva se tapasztaljon torzuló jelalakot. Mivel csak az 1-es és 2-es csatorna jelét mutatja a monitor, hogyan állítaná be a maradék csatorna előerősítését?

Válaszom: Elindítottam a felvételt és ekkor mutatta mind a hét csatornának a jelét a főablakban. Ezt így már utólag is meg tudom vizsgálni, hogy torzult-e a jel.

Rögzítsen alkalmasan hosszú jelalakot az összes mikrofont egyszerre felhasználva!

Az idősorok alapján határozza meg, az egyes csatornákat jellemző átlagos jelteljesítményt!

Az adatsort rövidebb szakaszokra bontva is számolja ki a teljesítményt, és nézze meg ennek időbeli változását! Készítsen erről ábrát és elemezze! Mit vár és mit tapasztal?

In [3]:
# Hangfájlok betöltése
jel_alap = [ scipy.io.wavfile.read("alapzaj/Audio Track-" + str(i) + "-2.wav")[1] for i in range(1, 8) ]

# A teljesítmény az amplitúdó abszolútérték négyzetének időbeli átlaga:
teljesitmeny_alap = [ (abs(jel_alap[i])**2).mean() for i in range(7) ]

for i in range(7):
    print("A " + str(i + 1) + ". csatorna átlagos teljesítménye:", teljesitmeny_alap[i])
A 1. csatorna átlagos teljesítménye: 2.8641222e-07
A 2. csatorna átlagos teljesítménye: 3.2722122e-07
A 3. csatorna átlagos teljesítménye: 2.773002e-07
A 4. csatorna átlagos teljesítménye: 5.2608135e-07
A 5. csatorna átlagos teljesítménye: 1.0934724e-06
A 6. csatorna átlagos teljesítménye: 1.996058e-06
A 7. csatorna átlagos teljesítménye: 1.0475975e-06
/opt/conda/lib/python3.6/site-packages/scipy/io/wavfile.py:273: WavFileWarning: Chunk (non-data) not understood, skipping it.
  WavFileWarning)
In [4]:
# Az mérés időtartamát felosztjuk 1000 időintervallumra
t = linspace(0, jel_alap[0].shape[0], 201).astype(int)

# Majd kiszámítjuk ezekben a rövidebb intervallumokban a teljesítményt
idofugges_alap = list()
for ch in range(7):
    idofugges_alap += [ list() ]
    for i in range(len(t) - 1):
        idofugges_alap[ch] += [ (abs(jel_alap[ch][t[i]:t[i+1]])**2).mean() ]
idofugges_alap = array(idofugges_alap)
In [5]:
figsize(12, 8)
for i in range(7):
    plot(0.5 * (t[1:] + t[:-1]), idofugges_alap[i, :], label=str(i+1) + '. csatorna')

xlabel("idő", size=15)
ylabel("teljesítmény", size=15)
title("Teljesítmény az idő függvényében", size=21, y=1.03)
legend(fontsize="large")
Out[5]:
<matplotlib.legend.Legend at 0x7fda006839b0>

Azt vártam, hogy a háttérzaj egy nagyjából egyenletesen ingadozó, gyenge teljesítményt fog adni. A kapott ábrán jól kivehető ez a ez az ingadozás, ám látszanak benne bizonyos zavarok. 3 olyan nagyobb zavar van, amely minden csatornán megjelenik, valószínűleg ilyenkor történt valami a szobában (lesett valami, megszólalt valaki, stb...).

Érdekes megfigyelni a 6. csatorna jelében a szabályos periodicitással rendelkező jelet. Ez annak köszönhető, hogy a 6. mikrofon közvetlenül a számítőgép szellőzője mellett van, és a ventillátor forgásának változása jellegzetesen felismerhető.

A másik érdekesség a 7. csatornán lévő felfutás az utolsó részben, ami máshol nem nagyon látszik. Mivel a 7. mikrofon az egér mellett volt, valószínűleg érzékelte, amikor egy kattintással leállítottam a mérést, és ez jelenik itt meg.

1.3. Kopogtató jele

A munkaterületek egy mechanikus hangforrást talál az asztalhoz rögzítve. (Ez egy forrasztóón elszívó pumpa.)

Rögzítse a hangforrás jelét, többször megismételve a rugó megfeszítését, majd a kioldást.

A rögzített mintában keresse meg a kopogtató jelét és számolja ki a jel teljesítményét!

Térjen ki a következő kérdések megválaszolására:

  • Tud egy koppanáshoz tartozó jelen érdekes szakaszokat elkülöníteni? Ha igen, mi lehet ennek a hátterében meghízódó folyamat?
  • Mennyire ingadozik egy-egy csatornán belül a koppanáshoz tartozó jelteljesítmény érték?
  • Milyen jel-zaj viszonyt tud becsülni az egyes csatornákra?
  • Vizsgálja meg a jel/zaj viszony távolság függését!
In [6]:
jel_kopog = [ scipy.io.wavfile.read("kopogas/Audio Track-" + str(i) + ".wav")[1] for i in range(1, 8) ]
/opt/conda/lib/python3.6/site-packages/scipy/io/wavfile.py:273: WavFileWarning: Chunk (non-data) not understood, skipping it.
  WavFileWarning)

A koppanáshoz tartozó jel az 1. csatornán az alábbi:

In [7]:
figsize(8, 6)
plot(linspace(422000, 442000, 20000), jel_kopog[0][422000:442000])
xlabel("Idő", size=13)
ylabel("Amplitudó", size=13)
title("A koppanás jele", size=17, y=1.02)
Out[7]:
Text(0.5,1.02,'A koppanás jele')

Jól látható, hogy az elején még kisebb a jel (de még itt is nagyobb, mint a zaj), ez annak az időnek felel meg, amíg a szerkezet nyomógombja csúszik visszafelé a csőben. Ezután egy éles csúcs látható a jelen, a nyomógomb ekkor ütközik hozzá a cső végéhez, és nagy zajt kelt, majd az utolsó szakaszban ez a jel, amit az ütközés keltett exponenciálisan lecseng. Én a jelből egy 20000 mérési pontból álló részt választottam ki, erre számolom ki a teljesítményt:

In [8]:
teljesitmeny_kopog = [ (abs(jel_kopog[i][422000:442000])**2).mean() for i in range(7) ]

for i in range(7):
    print("A " + str(i + 1) + ". csatornában a koppanás átlagos teljesítménye:", teljesitmeny_kopog[i])
    print("\tÍgy a jel-zaj arány:", teljesitmeny_kopog[i] / teljesitmeny_alap[i])
    print()
A 1. csatornában a koppanás átlagos teljesítménye: 0.00041925727
	Így a jel-zaj arány: 1463.8247

A 2. csatornában a koppanás átlagos teljesítménye: 0.001177691
	Így a jel-zaj arány: 3599.067

A 3. csatornában a koppanás átlagos teljesítménye: 7.515373e-05
	Így a jel-zaj arány: 271.0194

A 4. csatornában a koppanás átlagos teljesítménye: 0.00028537327
	Így a jel-zaj arány: 542.45087

A 5. csatornában a koppanás átlagos teljesítménye: 0.00042189483
	Így a jel-zaj arány: 385.83035

A 6. csatornában a koppanás átlagos teljesítménye: 0.00026874922
	Így a jel-zaj arány: 134.63998

A 7. csatornában a koppanás átlagos teljesítménye: 0.0003820373
	Így a jel-zaj arány: 364.67947

A kapott jel-zaj arányokat a mikrofon távolságának a függvényében az alábbi ábrán ábrázoltam. Mivel azt várnánk, hogy a teljesítmény a forrástól $r^{-2}$-nel arányos módon cseng le, ábrázoltam mellette egy ilyen kitevőjű hatványfüggvényt is. Látszik, hogy bár a pontoknak elég nagy a szórása (egyéb zajforrások miatt, mint a gép, egér, beszéd stb...), de a csökkenés nagyjából követi a görbe lefutását.

In [9]:
plot(tavolsag, [ teljesitmeny_kopog[i] / teljesitmeny_alap[i] for i in range(7) ] , "ro", label="mért pontok")
plot(linspace(30, 160, 100), 10**6.67*linspace(30, 160, 100)**-2, "-", color="#99D9EA", label="Egy -2 kitevőjű hatványfüggvény")
loglog()
xlabel("Távolság [cm]", size=13)
ylabel("jel-zaj arány", size=13)
title("A jel-zaj arány távolságfüggése", size=17, y=1.02)
legend()
Out[9]:
<matplotlib.legend.Legend at 0x7fda00595160>

2. feladat: A terem hőmérsékletének becslése

A méréshez két mikrofonra lesz szükség. Igyekezzen a mikrofonokat és a kopogtatót egy vonalban elhelyezni. A mikrofonok távolságát változtatva rögzítse a kopogtató hangját. Keresse meg a jel felfutását minden csatornán például minta indexben mérve. Alkalmas ábrán vegye fel ezek különbségét a távolságkülönbség függvényében és illesszen modellt!

A hibák becsléséről se feledkezzen meg!

Mérés n $\langle\Delta s\rangle$ $\sigma(s)$ $\Delta l$ [cm] $\sigma(l)$
1. 1 57 . 20 .
2. 1 90 . 30 .
3. 1 122 . 40 .
4. 1 149 . 50 .
5. 1 176 . 60 .
6. 1 202 . 70 .
7. 1 230 . 80 .
8. 1 258 . 90 .
9. 1 283 . 100 .
10. 1 311 . 110 .

Az illesztéshez választott modell: $\langle\Delta s\rangle = \frac{1}{c} \cdot \Delta l + s_0$, ami alapján a becsült hangsebesség: c = (345 $\pm$ 4) m/s.

A hangsebesség többek között függ a levegő hőmérsékletétől, ez alapján milyen hőmérsékletet becsül?

Az adatokra illesztett egyenes meredekségének reciprokából megkaphatjuk a hangsebességet. Ennek mértékegysége először $\frac{cm}{mintavétel}$, de ez könnyen átszámolható $\frac{m}{s}$-má, ha figyelembe vesszük, hogy 1 másodperc alatt 96000-szer mintavételeztünk. Az eredmény, hogy a hangsebesség: $c = \left( 345 \pm 4 \right)\,\frac{m}{s}$.

A négyjegyű függvénytábla szerint a hangsebesség hőmérsékletfüggése: $c = c_0 \sqrt{\frac{T}{273\,K}}$, ahol $c_0 = 331,8\,\frac{m}{s}$. A kapott hangsebesség alapján a labor levegőjének hőmérséklete: $T = 295\,K \pm 7\,K = 22^{\circ}C \pm 7^{\circ}C$

In [10]:
def linear(x, a0, a1):
    return x*a1 + a0

tav = linspace(20, 110, 10)
ds = [57, 90, 122, 149, 176, 202, 230, 258, 283, 311]
eh, hiba = curve_fit(linear, tav, ds)

figsize(12, 8)
plot(tav, ds, "ro", label="mért adatok")
x = linspace(tav[0], tav[-1], 100)
plot(x, eh[0] + eh[1] * x, label="illesztett egyenes")
xlabel("tavolsag [cm]", size=15)
ylabel("mintaszám különbség", size=15)
title("Mintaszám különbség a mikrofonok távolságának függvényében", size=21, y=1.03)
legend()

print("Illesztés együtthatói:", eh)
print("Hibamátrix:", hiba)
Illesztés együtthatói: [7.13939394 2.77939394]
Hibamátrix: [[ 5.21044883e+00 -6.70651811e-02]
 [-6.70651811e-02  1.03177203e-03]]

3. feladat: Helymeghatározás síkon

Haladó feladat a kiváló jegyért!

A leírásban szereplő likelihood becslés segítségével építsen sík-lokátort.

Az asztal síkjában keltsen a kopogtatóval jelet és vesse egybe a számolt pozíciót a jelforrás aktuális pozíciójával. Milyen pontosságot tud elérni.

A méréssel kapcsolatos észrevételek

Kitölteni nem kötelező:

  • Itt kérjük feltűntetni, hogy mennyi idő volt szükséges a feladatok elvégzéséhez.
  • Itt lehet javaslatot tenni a méréssel kapcsolatban.
  • A méréssel kapcsolatban felmerült további ötletek.

Mivel nincs hozzá rendes leírás, ezért sok mindent nehéz megérteni elsőre, hogy pontosan mire is van szükség, mit kell csinálni. Egy leírás elolvasásával szerintem legalább 30-40 percet lehetne spórolni, amivel kényelmesen befejezhető lenne a mérés (kis rákészüléssel, és sietve még a 3. feladat is). Így csak sietve lehetne csak befejezni az 1-2 feladatokat, és ez nagyban a lényeg megértésének rovására megy.

Esetemben ráadásul sok idő ki is esett, így nem is tudtam mindent teljesen jól lemérni, és a kiértékelést is csak a labor után, otthon tudtam befejezni.