A következőkben egy olyan Pythonban készült parancssoros programkódot mutatok be, ami az előzőekben ismertetett mérési módok közül a hosszú szinusz sweep típust használja. Ezzel a módszerrel sokkal gyorsabban lemegy a mérés mint a lépcsőzetes szinusz esetében és hasonló, vagy jobb eredményt előállítva. Példaként lljon itt, hogy egy 5Hz-40kHz közötti 1/48 oktávos felbontású stepped sine mérés az Arta Limppel több, mint 11 percig fut, ellenben egy hasonló szintű (a korrekt összehasonlítás nem lehetséges) mérés ezzel a megoldással 45 mp (1/24 okt. simításnál), de szigurú szemmel is csak 1.5 perc (1/48 okt simítás)! (Fontos, hogy itt a simítás nem felbontás, ezért az 1/24-ed simítás partiban van az 1/48-ados diszkrét felbontással!) Ez a mérési idő nyilván továbbra is elmarad az FFT-s néhány másodperces mérési idejétől, de a mérés precizitása változatlanul hozza a szinuszos mérésre jellemző sokkal jobb szintet.
Előljáróban pár gondolat a lépcsőzetes szinusz módról
Amikor stepped-sine módban mérünk, akkor az történik, hogy generálunk egy szinuszjelet valamilyen frekvenciával, bekapcsoljuk, lemegy belőle pár periódus, és az utolsó periódus végén (szépen szinkronizálva a periódis végére) kikapcsoljuk. Majd következik egy kis üres rész, amiben a rendszer még kalimpál, azaz kikapcsolási tranzienssel nyugalmi állapotba kerül, és jöhet a következő frekvenciájú szinusz csomag. Fontos tudni, hogy a ki- és bekapcsolásoknál tranziensek keletkeznek, amiket apró pattogások formájában hallani is lehet. Ezeket a tranzienseket ki kell(ene) zárni a korrelációból, mivel itt torzul a jelforma, egyéb frekvenciák is létrejönnek egy rövid időre. Az első próbálkozásom alkalmával az egyszerűségre való törekvés érdekében még nem foglalkoztam ezzel (ld. az előző cikkben ismertetett kódot) és ennek ellenére egész jónak látszó eredményt kaptam. Később a fenti kód fejlesztésével megoldottam a hangkártya késleltetésének bemérését és szinkronizálását, így már tudtam pontosan időablakokat kijelölni. Először csak magát a burst csomagot tettem egy szűk ablakba, gondolva, hogy ezzel legalább a kikapcsolási tranzienst kizárom a feldolgozásból, de a bekapcsolási így még benne marad. Az eredmény egy rosszabb mérés lett. Ha azonban a burst jel elejéből is lecsíptem egy kicsit és mind a bekapcsolási, mind a kikapcsolási tranzienst kizártam a feldolgozásból, akkor újra jó mérést kaptam, sőt ez lenne a kívánatos, pl. az Arta Limp program is így működik. Érdekes tapasztalat azonban, hogy ha csak az egyik tranziest zárjuk ki, az rosszabb eredményt ad, mintha mindkettőt bennehagynánk; a bekapcs és kikapcs tranzies a feldolgozás alatt mintegy kioltani igyekezné egymás hatását! Ebből a megfontolásból a korábbi kódban is maradt az eredeti állapot, miszerint mind a bekapcs, mind a kikapcs tranzies bekerül a feldolgozási ablakba, helyette ott a jel fel- és lekeverésével csillapítottam a tranziensek kialakulását. Ide tartozik még, hogy próbálkoztam amolyan szünetmentes buströléssel is, ahol a szinusz csomagok között nincs megállás, 0 átmenetnél fázisugrás nélkül megy egyik rezegésből át a másikba. Ez is jó megoldásnak bizonyult, és jelentősen képes volt csökkenteni a mérési időt. (Ezeket a módokat a grafikus felületű programban próbálgattam, ami az előző cikkben a Youtube videóban látható.)
Állandó frekvenciájú szinusz korrelácó
Eddig nem esett szó a szinusz/koszinusz korreláció működéséről, így ezt most pár mondatban pótolni próbálom. Maga a működés abból áll, hogy a visszamért szinuszjelből veszünk egy akkora ablaknyi mintát, amire egész számú peridódus ráfér. Ezt a mintát megszorozzuk egy szinusz és egy koszinusz függvénnyel, ebből kapunk egy kétszeres frekvenciájú változó középértékű eredményt. Ennek kell átlagolással kiszámolni a középértékét, és megkapjuk a szinuszos és koszinuszos összetevőket, amikből vektoralgebrával kapjuk a mért nagyságot és fázist. Figyelembe kell venni azt is, hogy a szorzatfüggvények amplitúdója felére esik, ennek megfelelően kell majd számolni!
Egy szép animáció is készült, lehet vele játszani:
Amplitúdó: 50
Fázis: 0
Periódus: 2
Jelmagyarázat:
- aranysárga görbe: szinusz és koszinusz bázisfüggvények
- kék görbe: bemenő szinuszjel
- piros görbe: szinuszjel szorzata a bázisfüggvénnyel
- szaggatott piros görbe: szorzatfüggvény középértéke (korreláció eredménye, szinusz vagy koszinusz összetevő nagysága)
- piros vektor: polárkoordináta-rendszerben a szinusz/koszinusz összetevő vektorok
- ibolya vektor: polárkoordináta-rendszerben az eredmény nagysága és fázisa az összetevők alapján
Folytonosan változó szinusz-sweep korreláció
A vázolt gondolatmenettel odág jutottam, hogy lényegében lehetne korrelálni változó szinusz- és koszinusz jellel is folytonosan, miközben a frekvencia is folytonosan nővekszik, csupán az integráló szűrőt kell másképpen megoldani, mivel ilyenkor nincsenek szigorú frekvencia és periódus határok, egyetlen periódus végére is már megváltozott egy kicsit a frekvencia. A szinusz csomagoknál az előző részben sima átlagolást lehetett használni, ami egy skalár értéket adott vissza a szinus és koszinusz összetevők előjeles nagyságával. Itt viszont egy folytonos szűrőt kell alkalmazni, ami lényegében egy aluláteresztő szűrő, jelen esetben egy sin(x)/x kerenelű FIR szűrő lett. Ezzel így már nem skalárokat kapunk szinusz és koszinusz összetevőknek, hanem frekvenciában változó függvényeket.
Hogy érthetőbb legyen a dolog, nézzük meg mért jelekkel is! Kezdetben adott a sima rögzített (visszamért) szinusz jelünk:
Az első kép maga a rögzített hangminta szinusz sweep jellel, nevezetesen egy hangszóró rezonancia púpját mérjük itt éppen körbe. Alatta a szintén változó szinusszal és koszinusszal történő korrelációt látjuk. Vegyük észre, hogy a szorzatfüggvények középértéke itt hullámzik. A legalsó képen erre a jelre alkalmazott aluláteresztő FIR szűrő hatására már csak a középvonal látszik.
A teljes rögzített kétcsatornás (sztereo) jel így néz ki:
A jel elején egy rövid (100ms) 1kHz-es négyszögjel biztosítja a hangkártya késleltetésének mérését, ez ugyanis elengedhetetlen ehhez a fajta feldolgozáshoz. A jel elején a növekvő jelszint főleg a hangkártya csatolókondenzátorainak hatása, de az eredeti mérőjelben is van egy felkeverés és előrezegtetés, hogy a grafikon elején ne legyen tranziens hiba, ugyanígy a végén is van egy lekeverés, ami a FIR szűrő miatt kell, itt is a befejező frekvencia állandó, csupán az amplitúdója csökken le nullára. Valamint a bal csatorna (felső) a mérés sáv, ami egy 100 Ohmos soros ellenállásról egy hangszóróra leosztott jel, míg a jobb csatorna (alsó) a referencia sáv. (Ld, előző részben a kapcsolás) Annyi eltérés van a korábbiaktól, hogy itt nem használtam végfokot, passzív 100 Ohmos soros ellenállásos egyszerű kábelt használtam, ami végül egész jól bevált. (Korábban voltak kétségeim ezzel a mérőkábellel) A mérés egy módosított Behringer UCA222 hangkártyán készült, annak fülhallgató kimenetéről az RCA bemenet felé.
A fenti hangkártya igen jól bevált mérésre, azonban gyári állapotában sajnos nem problémamentes! Az egyik szinte már kizáró hibája, hogy az analóg referencia rail nem kisimpedanciás, így áthallás jön létre ezen a vonalon, egészen pontosan a kimenetei felöl a bemeneti műveleti erősítőkre. Ennek orvoslására a neten is több megoldás van, pl. hogy egy 2.5V-os sönt stabilizátorral fogják meg ezt a vonalat. Az én megoldásom az volt, hogy az áthallás okát szűntettem meg, ami a fülhallgató erősítő hangerő potijának hibás tervezése. A poti alsó pontjait nem GND-re, hanem erre a ref feszültségre kötötték, így megspóroltak összesen 4 csatolókondit. Én lekötöttem a potit és fixre kötöttem a füles erősítőjét. További gond volt még, hogy a füles OPA nem reel to reel, így nagyon hamar beklippel, ráadásul asszimetrikusan. Mintkét hibát orvosolni lehetett, egyrészt az IC cseréje, másrészt a szintén elbaltázott visszacsatolás, ahol újfent spóroltak egy csatolókondit. Hátrányként jegyezném még meg, hogy eredetileg a Behringer ezekbe a 48kHz/16bit kártyáiba a PCM290x Audio Codec IC-ket használta, de chip hiány meg drága is, így lecsérlték egy kínai klónra (CoolAudio V2902), ami nem olyan jó és tartós, mint a Texas/BB féle eredeti, ráadásul ebben is van a bemeneti ADC-jében a két csatorna között egy mintányi elcsúszás, ami miatt 24kHz felé befordul a fázis 180 fokkal. Megjegyezném még, hogy az Arta Limp bár eddig nálam minden hangkártyával jól teljesített, de ez nem a barátja, 12kHz felett összeomlik a mérés! (Mondjuk én amúgy se szeretem az utolsó oktávban mérésre használni a kártyákat, ezért jobb legalább 96 vagy méginkább 192kHz-es 24 bit felbontású eszközöket nézni inkább!) Windowszal is egy fontos tapasztalat, hogy 10/11-es kiadások audio kezelése soha nem látott mélységekbe esett, 600ms feletti késések a stream-ben, orrba szájba belenyúl a formátumba, 192kHz-re állítható a 48kHz-es kártya, kéretlen digitális szűrők alkalmazása, szintezgetés stb. Sajnos Win alatt egyre inkább fontos, hogy ASIO kártyát használjunk, amivel megkerülhető a Windows hangszerver! (Linux esetében szerencsére ASIO nélkül is megkerülhető a hangszerver és kiosztható egy kártya dedikáltan egy folyamatnak!)
A folytonos szinusz sweep-el működő Python programkód ismertetése
Ennyi előjáték után térjünk is rá a kódra! Ismét megjegyezném, hogy a kód elsősorban a tanulást, az ismeretszerzést célozta meg, de ettől függetlenül jól működik, használható mindennapi mérési munkához is! (Sőt már-már megérné grafikus interface-el ellátva ilyen kiadásra fejleszteni) Számos új funkció épült be korábbi pythonos verzióhoz képest, mint pl.:
- Több üzemmód: impedancia-menet mérése, relatív frekvenciaátvitel mérése, kalibrálási módok
- Több szálas Python kód, stream módban használt audio, de van hagyományos felvételi módja is, ha kompatibilitási problémák merülnének fel
- Bár karakteres interface-t használunk, a mérés során dob egy GUI ablakot az audio jelszintekkel és egy folymatjelzővel
- „Három pontos” kalibráció: open/short/referencia
- LCR mérő grafikonok soros és párhuzamos modelben, alkalmas kapacitás és induktivitás mérésére is
Beállítás/változók magyarázata
|
MODE = None |
Üzemmódok, beleértve a kalibrációt is. Ha None értéket adunk meg, akkor a program futás közben fogja megkérdezni. Futás alatt alapértelmzetett mód a Z (impedancia), ha nem írunk be semmit, ez lesz kiválasztva. A ?-jellel rövid súgót ír ki. |
|
USING_CALIBRATE = None |
Ha korábban az adott beállításra kalibráltunk, akkor azt használjuk-e a méréshez, vagy ne. True/False/None értékekre hallgat, None esetén futásidőben kérdez rá. |
|
FREQ_START = 5 |
Kezdő frekvencia Hz-ben |
|
FREQ_END = 20000 |
Vég frekvencia Hz-ben |
|
SWEEP_TIME = 0 |
Teljes sweep löket hossza másodpercben. Csak akkor releváns, ha a FR_RES_PER_OCT érték None |
|
FR_RES_PER_OCT = 24 |
Elvárt simítás (frekvencia felbontás). Ha értéket kap, akkor a program kiszámolja a sweep jel hosszát, amivel az integráló szűrő simítása teljesíti a fenti felbontású szűrést. Fontos megjegyezni, hogy ez nem a kapott frekvencia függvény felbontása, az olyan magas érték, hogy csak a hangkártya mintavételezési frekvenciája szab határt neki. Pl. 48kHz mintavételezés esetén egy 1 perces jel 48000*60 = 2.88 millió minta, ennyi a nyersen keletkezett frekifüggvény elemszáma! Az integráló szűrő viszont elsimítja, miközben a korreláció után kiátlagolja a dupla frekis szinuszt, és ennek a simításnak a mértéke legyen pl. 1/24-ed oktáv. |
|
FSTART_TIME = 1.0 |
A kezdőfrekvencián előrezegtet ennyi ideig (másodperc), a bekapcsolási tranziens távoltartása érdekében. |
|
FEND_TIME = 0.2 |
A végfrekvencián utórezegtet ennyi ideig (másodperc), a kikapcsolási tranziens távoltartása érdekében. |
|
FADING = True |
Elő- és utórezegtetés amplitúdó fel/le keveréssel. |
|
SAMPLE_RATE = 48*1000 |
Hangkártya illetve a streamelés mintavételi frekvenciája (Javasolt a hangkártya natív értékét használni. Egyes studio kártyáknak több, akár az összes értéke lehet natív, ha átkapcsolható óragenerátora van!) |
|
BLOCKSIZE = 2*1024 |
Streamelés buffermérete (kilóminta) |
|
LR_DELAY = 0 |
Bal és jobb csatorna eltolása mintában. Pl. az UCA222-nél ha V2902 chip van benne, akkor 1-re kell állítani, alapértelmezésben 0. Ha nem adunk neki értéket az se feltétlen baj, a kalibráció átviteli fázishibaként behúzza lineárba. |
|
OUTPUT_LEVEL = 1 |
Stream kimeneti digitális jelszint. A módosított UCA222-nél gond nélkül mehet 1 értéken (ez a 100%), de ha klippelést látunk a szinuszjelen, akkor lejjebb kell venni. |
|
OUTPUT_LEVEL_LEFT = 1 |
A bal és a jobb csatorna jelszintjei külön-külön kiballanszolva. Célszerűen itt a bal 1 a jobb pedig -1, ami áthallás csökkentő hatású lehet, mert ha monóra lekeveredik, akkor kioltja magát. A bal csatorna szinte mindig lehet 1, a jobb csatornára adhatunk 1 (ugyanolyan fázisú), 0 (nincs jel a jobb csatornában), vagy -1 (ellenfázisú) értékek valamelyikét. |
|
INPUT_CH_MEAS = 0 |
Azt állítjuk be, hogy melyik bemeneti csatorna a mérésé és melyik a referencia sáv. 0 a bal, 1 a jobb csatorna. Ebben a beállításban a ballal mérünk, és a jobb lesz a referencia jel. |
|
R_SENSE = 100 |
Soros mérőellenállás értéke. (Ohm) |
|
R_INPUT = None |
Hangkártya bemeneti impedanciája, vagy ohmos ellenállsa egy csatolókondi után. Ha nincs 3 pontos kalib, akkor javít a pontosságon. Ha alkalmazunk 3 pontos kalibrációt, akkor szükségtelen, mert az kikompenzálja a hangkártya bemeneti komplex impedanciát. (None = nem használjuk, egyébként Ohm-ban mérjük) |
|
CS_INPUT = None |
Hangkártya bemeneti csatolókondi értéke (Farad egységben, pl. 10uF-ot így írjuk 10E-6) Ha nem None, akkor egy ilyen értékű kondinak és az R_INPUT ellenállásnak megfelelően számol bele a körbe egy bemeneti impedanciát. Alacsony frekin pontosít, de 3 pontos kalib esetén legyen nyugodtan kikapcsolva! (None) |
|
R_CAL = 1000 |
Hárompontos kalibráció esetén az utolsó kalibrálási kör a külső referencia ellenállással töreténő kalibráció. Tapasztalat alapján jó érték a mérőellenállás 10-szerese, ami egy 100Ohmos mérőellenállás esetén 1kOhm lesz. használjunk 0.1% tűrésű preciziós rétegellenállást! (Nem utolsó sorban érdemes ilyet használni a soros ellenállás pozícióban is, ha megtehetjünk!) |
|
MARGIN_TIME = 1.0 |
Margó (üres szakasz) a jel elején és végén. Sajnos a nagy stream késések miatt indokolt lehet az 1 másodperc. |
|
SYNC_POS_TIME = 0.25 |
A bal margóban ebben a pozícióba kerül a stream késést mérő 100ms hosszú szinkronjel. Másodperben adjuk meg. |
|
INT_FILTER_CUTOFF |
Integráló szűrő törésponti frekvenciája Hz-ben. Ezt az induló freki alapján számoljuk
ki, figyelembe véve, hogy a legkisebb freki, amit már hatékonyan kell szűrni, az
ennek a kétszerese. Három értéket ajánl fel a programkód: |
|
CSV_NUMBER_OF_ROWS |
Frd és zma kimeneti fileok tulajdonságai. Az első a sorok (értékek) száma. Az 1000 akkor jó, ha a fogadó másik program nagy adatmennyiséggel nem tud mit kezdeni. Saját kézi feldolgozásra beállíthatjuk 100-200 ezerre is, akkor nagyon finoman lehet pl. f0,f1,f2 pontokat leolvasni, nem kell interpolálni! Második a szeparátorjel (oszlopok elválaszója) a harmadik pedig a nyomtatási formátum |
|
USING_TIME_GRAPHS = True |
A program által Matplotlibbel rajzolt grafikonok tulajdonságai. Az első a time grafikon. Nagyon nagy adatmennyiség, több millió értékkel. Ha nem bírja a gép, akkor ki kell kapcsolni. Ha bírja, akkor hasznos, mert látszik, ha gond van a méréssel (pl. klippel, vagy kihagy, recseg) A második a frekvcia és a többi grafikon felbontása |
|
DISABLE_STREAMING = False |
A két utolsó flag debug célokra való. Az első akkor jó, ha a szálkezeléssel megvalósított streamelés nem működne jól, de én nem tapasztaltam ilyet (Python 3.11 alatt legalábbis) se Win-en, se Linuxon. A második egy érdekes feature, azt csinálja, hogy a folyamat végén debug célból record.wav filba lementett felvételt tölti be és dolgozza fel új streamelés helyett. Ez gyorsabbá teszi a hibajavítást, mert nem kell megvárni egy esetlegesen 1 perc körüli audio streamelés végét. Ha bogarászod a kódot, próbálgatod, akkor hasznos lesz! |
A program működése képekben
Először egy kis Grundug (Braun) gyártmányú 13 cm átmérőjű hangszórón mérünk impedancia menetet. Indítás után a módot kell megadni egy betűben:
Itt látunk pár adatot a mérésről, pl. hogy ez a sweep összesen (szinkronjellel, margóval, fel- és lerezegtetéssel) 43.99 másodperc hosszú lesz. Ez igen jó idő egy 5Hz-ről induló és 1/24-es oktávos simítású méréstől! Ezután ha korábban készült kalibráció az adott beállításhoz és a USING_CALIBRATE = None beállítás van érvényben, akkor a program megkérdezi, hogy szeretnénk-e használni a kalibrációs értékeket:
A következőkben a hangkártyát kell kiválasztani. Itt most Windows 10 rendszeren fut a program, ezen és a Win 11-en célszerű a WDM-KS szerveren belül választani, ha nincs ASIO támogatásunk. (Ha van, akkor értelemszerűen azt válasszuk.) Valamiért mostanában a Windowsban külön vannak szedve a ki és bemenetei eszközök, akkor is, ha azok valójában egy hangkártyán sőt egy IC-ben helyezkednek el. Ha már történt kivákasztás, azt megjegyzi a program egy dev.txt file segítségévell, ilyenkor csak Enterrel tovább is léphetünk, de én most beírtam, hogy lássuk hogyan kell megadni. A beállított hangkártya a Begringer UCA222, amit USB Audio CODEC néven látunk az eszközök között. A bemenetnél a mikrofon ne zavarjon meg, a Windows így érzékeli, de valójában ez vonal bemenet! Sőt, annyira komolyan hiszi a Winfos, hogy ez miki, hogy le is monósítja, ezért a hangbeállításoknál nekünk kell beállítani a 2 csatorna, 16 bit, 48000 Hz (DVD-minőség) módot! Javasolt még amúgy, hogy miután beállítottuk, tiltsuk le a hangkártyák között, hogy a Windows a továbbiaknak ne csörömpöljön rajta.
Ha ezt megadjuk, akkor el is indul a mérés. A program nem kérdez, csinálja a dolgát, tehát a hangszórónak vagy bárminek amit mérünk, csatlakoztatva kell lennie! Grafikus folyamat- és jelszint kijezést élvezhetünk:
A mérés végén megjelenik az első eredménygrafikon, a bal és jobb sáv felvett jeleivel, valamint az ebből mért impedanciamenet:
Az ábra alatti szöveges sorban megjelenik a választott hangkártya és hangszerver, a mintavételi frekvencia, a kalibráció módja (Kal=), aminél ha megjelenik az O akkor történt open kalibráció, ha benne van az S akkor történt short kalibráció és ha benne van az R akkor történt referencia ellenállásos kalibráció is. Látjuk még a sweep löket hosszát sec-ban és az integráló szűrő simító hatását 1/oktávban. Utóbbi azért nem kerek, mert az optimalizációkor a program a lökethosszt számolja s-ban egészre és felfelé kerekítve, hogy a választott simítás megfelelő legyen, így az ilyenkor meglesz, vagy kicsit jobb lesz.
Bezárás után kapunk egy Nyquist diagrammot (helygörbét), bár nem mintha sok hasznát vennénk, legfeljebb ha nem szabályos kör a rezonancia szakasz, akkor az informálhat minket, hogy valami gond lehet a felfüggesztőelemek viselkedésével:
Utolsó grafikon pedig egy LCR. Ennek a felső sora a soros, az alsó a párhuzamos módnak megfelelő számítás. Az oszlopok pedig az L a C és az R értékek:
Hangszóró mérésekor ebből legfeljebb a cséveinduktivitást (soros módban) olvashatjuk ki, ha ránagyítunk az 1k feletti részekre.
Végül a program befejeződik, csinál pár mentést, mint pl. impedancia.zma és egy record.wav-ot. Eredetileg ezek kérdések után hajtódtak vagy nem hajtódtak végre, de Windows 11-en itt már nem működött jól a billentyűzetről bevitel, ezért ezt ideiglenesen megszűntettem.
2uF-os fólia kondenzátor mérése
Következő példa egy 2uF-os Remix C213 PP fóliakondi lesz. Az impedanciamenet logaritmikus skálázatán gyakorlatilag tankönyvi görbéket látunk, még 5Hz-en is stabil a mérés, pedig itt 10 kOhm fölötti Xc értékkel számolhatunk! A fázis görbe is végig -90 fokban fut!
De ami még ennél is izgalmasabb, az az LCR grafikon. Mivel ez csak egy kondi, így elvileg nem számít, hogy soros, vagy párhuzamos módban számolunk-e, pláne, hogy ez egy igen jó fóliakondi, és a mérőrendszer vezetékezésének impedanciája is kompenzálva lett a kalibrációban. Szinte a teljes sávszélességben hozza a 2uF értéket. A kondenzátor magas tartományú pici esése valószínűleg megfelel a valóságnak:
2uF-os fólia kondenzátor és 100 Ohmos ellenállás párhuzamos kapcsolásának mérése
Ebben a példában párhuzamos kötöttem a kondival egy 100 Ohmos ellenállást is:
Természetesen itt is az LCR grafikon az izgalmasabb, az 5. és a 6. képen a párhuzamos modell szerinti mérés eredményét látjuk. Nyilván összetett kapcsolásban nem mérhető teljes sávban egy rendszer, de azért szépen visszaadja mindkét alkatrész értékét! Ugyanilyen jól teljesít egyébként soros RC, RL stb kapcsolásoknál is, amíg az eredő impedancia a jól mérhető tartományokon belül van és egyik alkatrész sem dominálja le túlságosan a másikat (pl a fenti esetben magas tartományban már annyira söntöl a kondi, hogy lehetetlen pontosan mérni a párhuzamos R-t) addig a mérés jól teljesít.
A forráskód:
Függőségek
Ha az első fejezetben felsorolt csomagokat telepítetted a Pythonhoz, akkor nem lesz probléma a működéssel (scipy, matplotlib, sounddevice, si-prefix). Python verzióból 3.11-en lett fejlesztve, de kicsit régebbieken se volt vele gond.
Fileok, könyvtárszerkezet
|
hmer_swp_4.1_4wf10_thr_stream_ref.py |
Ezzel a csodás névvel illettem magát a python kódot. A hmer-ben a h jelzi, hogy átvitelt (h) is mér, nem csak impedanciát, az swp jelzi, hogy ez sweep jellel operál, 4.1_4 verziószám, bár egy ideje nem léptetem wf10 jelzi benne hogy Windows-10 (winfos) kompatibilis, a thr, hogy thread azaz szálkezeléses, a stream jelöli, hogy streameléssel működik, nem az sd.playrec metódussal, és a ref jelzi, hogy ebbe már a külső referencia ellenállásos kalibráció (3.-ik kalibrációs pont) is belekerült. |
|
cal |
Ez egy könyvtár, amibe a kalibrációs fileokat teszi. A program létrehozza, ha nincs. |
|
dev.txt |
Az utoljára választott Audio device sorszámát ebben tárolja, hogy ne kelljen mindig beírkálni. Azért figyelni kell, hogy nem-e változik a sorban az adott eszköz! |
|
impedancia.zma |
Ezekbe kerül a mérés eredménye csv szerű táblázatos szöveges fileként. |
|
record.wav |
Felvett audio mentése (elemzésre, debug-ra) |
Kalibráció menete
A kalibráció 3 pontos, de nem kötelező mind a 3 pontot teljesíteni. Az viszont fontos, hogy ebben a sorrendben haladjuk vele, ugyanis egymásra épülnek! További fontos infó, hogy beállításonként új kalibráció kell, mivel itt a kalibráció szigorúan ugyanolyan mérési metódussal lesz felvéve, mint maga a mérés. Viszont mivel a kalibrációkat fileba menti, így minden általunk használt beállításhoz (beleértve a hangkártyát is) készíthetünk egyet.
1. pont: Open kalibráció
Ezt az üzemmódot C (mint calibrate) betűvel érjük el a program elején. Fontos, hogy legalább ez a kalibráció legyen meg, mert enélkül nagyon valószínű, hogy félre fog mérni a készülék, még akkor is, ha amúgy pontosan írjuk be a soros ellenállás értékét! Ez a kalibráció amúgy kalibrálja a hangkártya bemeneti együttfutás hibáit, és lényegében beállítja a végtelen értékre a mérést. Fontos, hogy ennél a készüléknél ne zárjuk rövidre a soros mérőellenállást, vagy ne kapcsoljuk át a jelet a mérőellenállás elé. Része kell, hogy legyen a kalibrációnak! Ha ezután nyitott kapcsokkal mérünk, akkor kb 1MOhm feletti értékeket látunk, még akkor is, ha a hangkártya bemeneti impedanciája mondjuk 10-20 kOhm körüli. Thevelin tétellel bizonyítható, hogy ilyenkor a bemeneti impedancia nem eltűnik, hanem virtuálisan átkerül a mérőellenállással párhuzamosan. (Ennek levezetését most elhagynám...) A program fel fog minket szólítani, hogy a kalibrációhoz legyenek a mérőkapcsok nyitottak!
2. pont: Short kalibráció
Ezt az üzemmódot az S (mint short) gombbal érhetjük el a program elején. Értelemszerűen itt össze kell zárni a mérőkapcsokat, és a program a mérővezetéket fogja lemérni, amivel a későbbiekben offsetelni fog. (Az itt mért impedanciát ki fogja vonni a későbbiekben Z módban mért impedanciából) A kis impedancia érékeken pontosít, nem kötelező, de ajánlott.
3. pont: Referencia kalibráció
Ez a pont elég sokáig váratott magára, ugyanis nagyon nehéz volt matematikailag levezetni egy ehhez szükséges két változós két ismeretlenes egyenletrendszert. Ebben a módban az R betűt kell választani induláskor és egy 1000 Ohmos nagy pontosságú precíziós ellenállást kell bekötni a kapcsok közé. De mire is jó, és miért is kell? Azt gondolhatnánk, hogy az open behúzza a végtelenre a rendszert, a short behúzza a 0-ba, a soros mérőellenállásunk pontos, preciziós, nem spóroltunk vele, az is 0.1%-os, akkor mit kell még kalibrálni? Nos, ahogy az előbb mondtam, a hangkártya bemeneti impedanciája virtuálisan átkerül a soros ellenállásra párhuzamosan. Ezért szükséges, hogy egy külső referencia ellenállással a soros ellenállásunkra is mérjünk egy impedancia-menetet, és igen, nem skalár ellenállást, hanem frekvenciafüggvényt (ahogy a shortnál se skalárral dolgozunk, mint egy-két program!) Azonban van ezzel egy kis gond; ki kell ebből is vonni a short kalibbal bemért kábel impedanciát, amit viszont pont azzal a soros ellenállással mértük ki, amit éppen most akarunk bekalibrálni! Van tehát egy egymásra mutogatás két elem között. Persze mondhatnánk, hogy ugyan, ez minimális mérési hibát okozna, ha valóságos elemekkel dolgozunk, azaz a kábel 100-200 mOhm, a soros ellenállás 100 Ohm, a kártya vonalbemenetének impedanciája meg 10 kOhm feletti. Csakhogy ez így nem profi! Itt bizony két dolgot, két ismeretlent kell egyszerre megmérni, azaz nem csak a soros mérőellenállás impedanciáját, de a vezetékezés impedanciát is újra kell számolni. Ez a két ismeretlen, a két változó pedig az, hogy ez két átviteli függvényből származik. Mivel sokat kopott már a matek a fejemben, így erős fejtörő lett ebből a kis pitiáner feladatból... Ez a mérés tehét frissíteni fogja a short kalibot, és letesz egy újat is, ami a soros ellenállás impedanciamenete lesz. Megjegyezném amúgy, hogy amennyiben nagy bemeneti ellenállása van a hangkártyának, akkor nem szükséges ez a pont, pl. sok studio hangkártya egyik vagy mintkét bemenete kapcsolható HiZ bemenetre, ami ilyenkor legalább olyan 300 kOhm, de inkább 1 MOhm bemeneti impedanciával működik. (Eredetileg gitár és egyéb pick-up-ös hangszerekhez lett ez kitalálva.)
Jelszintek kérdése
Ez a kis program nem rendelkezik jelszint beállító ablakkal, azt használatkor már tudni kell, pl. más program segítségével, vagy korábbi mérések alapján. Mérés alatt viszont látjuk a két bemenet kivezérlését, ami segít korrigálni a következő mérésre. (Megjegyzem, hogy gondolkodtam egy automata szintbeállítón is, amit a szinkronjel visszamérésekor alkalmazhatna a program) Ellenben van pár tapasztalás a jelszintekkel kapcsolatban, amit megosztanék. Egyszerűbb (pl. az UCA222) hangkártyákon a teljes kivezésrlési tartományban jó linearitás tapasztalható, nagyon tág határok között pontos mérést kapunk. Studio kártyáknál viszont azt vettem észre, hogy már -3dBFS szintnél kigyullad a clip jelzés. Ha ezeknél a kártyáknál ebben a tartományban is mérünk, (tehát a -3...0 dB sávban) akkor elszáll a linearitás, pontatlan lesz a mérés. Az a gyanúm, hogy ezekbe az eszközökbe kerülhetett valamilyen soft-clip megoldás, ami lekomprimálja a túl magas jeleket, hogy ne durva reccsenésbe menjen át. Ez érthető is, ha az eredeti stúdiós, zenélgetős funkciót nézzük. Én ilyen kártyáknál a biztonság kedvéért sosem engedem a jelszintet -6dBFS azaz 50% fölé a bemeneteken, és akkor egész pontosak lesznek, de sose lesznek olyan precízek, mint a meztelen egyszerűbb kártyák. Összességében azt mondanám, hogy majdnem mindig érdemes biztonságos szinten tartani a bemeneti jelet, nem szükséges plafonig kihasználni a mérési tartományt, az 50% (-6dB) teljesen jó érték mindig! Figyeljünk arra is, hogy a 100 Ohmos füles kimenetről hajtott mérőkörnél a füleskiment is olyan 50 Ohm külöri kimenő impedanciával rendelkezik, így üresjáratban, és terhelten a referencia jel is kicsit ingadozik. Ez a mérés pontosságát nem befolyásolja, csak könnyen klipp közeli helyzetbe kerülhetünk így. Open kalibrációkór látjuk leginkább, hogy milyen üresjárati szinteket kapunk.
Végül egy összehasonlítás az ARTA Limppel:
Itt Behringer UMC404HD volt a mérővas, annak is Insert csatlakozóit használtam vonalszintű bemenetnek, hogy a preamp ne zavarjon bele a mérésbe. Mind a két mérés kalibrálatlan állapotban készült, hogy az eltérő kalibrációk ne zavarjanak bele az összehasonlításba, itt csak a szoftveres mérőalgoritmust szerettem volna bevonni a vizsgálatba. Amint azt látjuk, a két mérés olyannyira együttfut, hogy a zöld Limpes mérés teljesen kitakarja a sárga importált Pythonos mérés görbéjét! Szerintem ennél több nem is kell, ez bizony valid! A Limppel a mérés csak 40kHz-ig ment, mivel nem lehet magasabb értékre állítani, a Pythonos mérést 80kHz-ig küldtem fel. A Python mérésben az integráló szűrő simítása 1/48 oktávra volt állítva, a mérőjel teljes hossza 1 perc 26 mp lett.
Ismert hibák
1. Matplotlib összeomlás
Sajnos a Matplotlib grafikonrajzoló néha hajlamos elszállni, és magával rántja az egész programot ilyenkor. Try-olni se lehet, akkor is elszáll, próbáltam szálba tenni, mondván, hogy akkor csak a szálat kaszálja el, de ez a kiegészítő csak a főszánon hajlandó futni. Neten se nagyon találtam megoldást, csak annyit, hogy más is járt már hasonlóan. Ez a hiba Windows-on csak ritkán jelentkezik, inkább a Lixuon jellemző. Ha gyakran előjön, érdemes kikapcsolni a time diagrammokat, mivel azok nagyon sok memóriát esznek, illetve jelenleg próbálgatok egy olyan verziót, ahol a program az eredményeket kiírja fileokba és külön programként futattaja a rajzolást, ez eddig elég jónak látszik, bár kissé igénytelen megoldás.
Kép a hibáról2. Stream botlás
Már kezdetek óta jelen van ez a hiba, vélhetően az oprendszer hangszerverének hibázása okozza. (Pl. Windows alatt ASIO esetén eddig nem jelentkezett, és ott mint tudjuk, megkerüljük a Windows Audiot!) Most egy ilyen elcsípett hibát elemeztem ki képernyőképekkel együtt. Annyit veszünk csak észre, hogy a grafikon eleje még jó, de egy ponton túl zagyvaságokat rajzol. Ennek az az oka, hogy egy buffernyi mintával valamelyik irányban megcsúszunk; pl. eldob a rendszer egy buffernyi adatot, vagy keletkezik egy buffernyi fals adat (itt most ez utóbbi történt). Szerencsére igen ritkán fordul elő, nem okoz nagy gondot, csak meg kell ismételni a mérést. Figyelni kell, hogy ha kalibráció esetén tapasztaljuk, akkor ismételjük meg a kalibrációt! Ami ebben az esetben történt, azt a következő screenshotokon mutatom be a record.wav mentett stream segítségével. Három mentett streamelést hoztam be, a felső kettő két jó (direkt kettőt, így ezek egymás kontrolljai) az alsó pedig a hibás streamelés. link A következő képen a felvétel elejére nagyítva már látni, hogy a feldolgozáshoz szükséges szinkronjelek sem esnek egyvonalba, ez az első kettőnél sincs így, hiszen mint azt korábbi cikkekben is mondtam, minden streamnél kicsit más késés lesz, ezért minden felvételnél új szinkront kell mérni. Azonban az alsó ábránál azt látjuk, hogy a szinkronjel nagyon nincs a többi jellel egyvonalban! A jel indításánál is látunk egy anomáliát, itt keletketett egy 8kS-nyi fals bemenet (nem tudni honnan, a Windows ingyen adta nekünk) Ha egyvonalba rendezzük a szinkronjeleket, akkor látjuk majd, hogy milyen időzítési hibákat kapunk, pl. hogy a streamelés vége nem esik egyvonalba, a rossz streamelés 8k-val hosszabb lett, de ha belenézünk a jelekbe, akkor is látjuk, hogy már alacsonyabb frekvenciákon is hamis fáziseltolódást okoz, magas frekiken pedig nem az a freki lesz adott pozícióban, mint amivel korrelálunk, ezért egy frekvencián túl teljesen szétesik a feldolgozás.
Letöltés
A programnak csináltam egy Google Drive tárhelyet is, ide időnként teszek fel frissített verziókat. Letöltés után ellenőrizzétek a program elején a paramétereket is, pl. az RLDELAY-t is, mert ezt néhány (pl UCA222) hangkártyánál 1-re kell állítani, némelyiknél 0-ra!