Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2014:synchro-wav

Synchronní přehrávač zvukového souboru

autor: Richard Vacula, 115 303, xvacul18(at)stud.feec.vutbr.cz


Úvod

Synchronní přehrávání zvukových stop se řeší od dob, kdy započalo spojování různorodých médií, schopných uchovat určitou kontinuitu času. Dlouho si vědci a techniční pracovníci lámali hlavu nad tím, jak synchronizovat zvuk s filmovým vyprávěním. Zkoušela se spojení hřídele motoru filmového projektoru s pohonem gramofonu na šelakové desky, dlouhou dobu bylo právě mechanické spojení pohonů tou jedinou možnou cestou maximální synchronizace.

Filmoví amatéři kdysi zasahovali do konstrukcí kotoučových magnetofonů, čítali rychlost posuvu filmu ve svém projektoru a převáděli ji na ss napětí, kterým ovlivňovali tovární nastavení chodu pardubického kotoučáku.

S nástupem digitální technologie se jednoduché fyzické ovlivňování rychlosti čtení media ztratilo někde v propasti dějin (dnešní děti už si zřejmě nepustí z legrace gramofonovou pohádku místo na 45 ot./min s rychlostí 33,3 ot./min., aby proměnili ráskosníčka na mužného štamgasta páté cenové). Avšak stále existuje početná komunita, která se o výdobytky analogového světa nechce nechat připravit, ba naopak, chtějí si staré technologie vyzkoušet. Proto se, především v Praze, uskutečňuje řada analogových projekcí nezávislých filmařů z celého světa - a všichni řeší stále stejný problém - jak přehrát externí zvuk synchronně, i se zkreslením, které zavádí nestálý chod starého projektoru. Tato práce nastiňuje cestu, kterou lze právě starý kotoučový magnetofon simulovat. Digitální technika se ubírá směrem maximální přesnosti plnění daných norem. Dostupné DA převodníky k těmto nápadům a potřebám uměleckého světa nejsou zrovna přívětivé. Vyzkoušel jsem si to sám při lámání své hlavy nad tím, jak převodník CS43L22 donutit k nesynchronicitě a jiné, než tabulkové rychlosi DA převodu.

O zavrženíhodném DAC CS43L22

Pro pochopení možností i omezení tohoto převodníku je vhodné prolistovat dokumentaci: http://www.cirrus.com/en/pubs/proDatasheet/CS43L22_F2.pdf

Veškerá možná nastavení DA převodu nalezneme na straně 29. Konfiguraci je možno načíst i zapsat po sběrnici I2C do registrů 05h a 06h. Rychlost DA převodu lze standardně, bohužel, jak je vidno na str. 29, přepínat pouze po velkých skocích. Můžeme tedy přepnout převodník do modu SLAVE, kdy má přejímat referenční masterclock po sběrnici I2S (MCLK), od MCLK jsou generovaný BCLK, i LRCLK, takže by v rozladění frekvence převodu problém být neměl. Cesta řešení úlohy změnou hodin DAC se však při hlubším ponoření do tématu ukázala jako slepá. Parametry lze totiž měnit pouze při vypnutém PLL.

Stál jsem před rozhodnutím, zda to nějak obejít programově a vytvořil hybrid, který stejně nedosáhne tíženého výsledku, nebo se poohlížet po jiném převodníku. Nejčistším řešením by bylo užití obyčejného průmyslového převodníku, který je natvrdo řízen externí frekvencí - jak rychle posíláme data, tak rychle je dalším kontrolním vstupem odpalujeme v napěťové úrovni ven. Mně se však čas krátil a musel jsem vařit z toho, co se v mém bydlišti nabízelo. Přes studium zvukové tvorby na FAMU stále formálně pracuji pro opavskou Tipu, v tamní sekci vývoje jsem posbíral (i vypájel), co dům dal a hlavně uloupil obvod VS1053, připravený pro vývoj nové stavebnice MP3 playeru. Díky CNC vrtačce, kterou vývojové odd. disponuje, bylo možné okamžitě nafrézovat plošný spoj a vrhnout se s rukama nezasviněnýma od chloridu do práce.

Jelikož se zde pracuje především s ARM procesory od NXP a já sám jsem už měl za sebou projekt na řízení galvo systému skrze moduly lpcxpresso, tedy vývojové prostředí od NXP je mi bližší, napsal jsem kód nakonec v prostředí Code Red 4 a použil procesor LPC1769.

O kodeku VS1053 s interním DAC

Datasheet: http://www.vlsi.fi/fileadmin/datasheets/vs1053.pdf

Pokud bychom použili jednoduchý průmyslový převodník, museli bychom řešit změnu rychlosti posílaných dat k dekódování. Kodek VS1053 však obsahuje 32B buffer, jehož vyprázdnění (schopnost pojmout alespoň 32B) je indikováno na pinu DREQ hodnotou log. 1. DREQ je přepnut do log. 0, pokud je buffer dostatečně zaplněn.

Data se tak do kodeku posílají na vyžádání, vyšší rychlostí, než jakou probíhá samotné dekódování. Díky tomu neřešíme přesné dávkování dat o frekvenci, která by byla řízena vnější zdrojem referenční frekvence. Kodek navíc podporuje i spoustu jiných formátů, je možné tak synchronní přehrávač rozvinout do podoby, kdy akceptuje jakýkoli formát tímto kodekem zpracovatelný. Podle hlavičky přehrávaného souboru kodek rozpozná parametry i typ záznamu, který přijímá na svém datovém vstupu.

Komunikace mezi procesorem a kodekem probíhá po rozhraní SPI, rychlost dekódování pak můžeme ovlivnit pomocí registru SCI_CLOCKF. Užití externího zdroje frekvence namísto krystalu se v dokumentaci obvodu výslovně zakazuje.

Prostředníkem v předávání dat z připojené SD karty do kodeku je procesor LPC1769, založený na architektuře ARM.

Schéma zapojení

Na tomto obrázku je patrné vzájemné propojení komponent potřebných pro realizaci pokusu/ověření kódu. Vzhledem k množství periferií obvodu VS1053 bylo nutné pro audiokodek navrhnout celou DPS. LPCXpresso bohužel neměl k dispozici knihovnu pro SW eagle, byl jsem tak nucen si ji vytvořit jako kompletní komponentu (pro případ potřeby vytvoření homogenní základové desky pro všechny komponenty).

Mimo audiokodek a modul LPCxpresso na schémetu nalezneme připojení SD karty s nahraným souborem WAV, startovací tlačítko a zapojený pin IN pro přivedení externí řídicí frekvence. Nejdříve byla jako referenční frekvence uvažováno 25 Hz (počet snímků/s). Jistější je však čtení frekvence přímo na rotační závěrce projektoru. Pro snížení vjemu blikání však dochází k zaclonění světelného toku filmem 50x za sekundu (tedy na každé filmové pole připadá dvojité zaclonění). Proto jsem se uchýlil k určení referenčního kmitočtu 50 Hz. Není zapotřebí stavět žádný složitý systém optické závory. Stačí umístit fotodiodu mezi rotační clonu a projekční lampu, jež rovnou slouží jako přerušovaný zdroj světla, určující pravou rychlost posuvu filmu.

Popis funkce

Čítač/časovač

Pro synchronní přehrávání obsahu WAV potřebujeme měřit externí referenční frekvenci. K tomu slouží čítač LPC_TIM0, spouštěný sestupnou hranou na PINu P1.26, s rozlišením časování po 1us, s nastavenou děličkou 100. Výsledkem je tedy údaj X ve stovkách us, udávající délku periody externě přiváděného signálu.

Při rovných 50 Hz bude výsledkem číslo 200, tedy 20 000 us = 20 ms. Provádíme tedy měření periody s přesností v desetinách milisekund, což je v okolí 50Hz ve frekvenční oblasti přenost na čtvrtiny Hz, tedy polovinu tzv. čtvrtsnímku filmového pásu. Lidské oko je schopno zaznamenat asychnronnost obrazu vůči zvuku až při posuvu o půl snímek (cvičený filmový zvukař), běžný divák rozlišuje asynchronnosti až u jednotek snímků.

Ukázka kódu čítače/časovače:

	 /* Nastavení vstupu P1.26 jako captureCAP0.0 */
	 PinCfg.Funcnum = PINSEL_FUNC_3;
	 PinCfg.OpenDrain = 0;
	 PinCfg.Pinmode = 0;
	 PinCfg.Portnum = PINSEL_PORT_1;
	 PinCfg.Pinnum = PINSEL_PIN_26;
	 PINSEL_ConfigPin(&PinCfg);
 
 
	 /* Nastavení TIM0 na čítání po 1us */
	 TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
	 TIM_ConfigStruct.PrescaleValue   = 1;
 
	 /* Kanál 0, CAPn.0 */
	 TIM_CaptureConfigStruct.CaptureChannel = 0;
	 /* Povolen capture na CAPn.0 vzestupnou hranu */
	 TIM_CaptureConfigStruct.RisingEdge = ENABLE;
 
	 TIM_CaptureConfigStruct.IntOnCaption = ENABLE;
 
	 /* Nastavení módů */
	 TIM_Init(LPC_TIM0, TIM_TIMER_MODE,&TIM_ConfigStruct);
	 TIM_ConfigCapture(LPC_TIM0, &TIM_CaptureConfigStruct);
 
 
	 LPC_TIM0->MR0=100; /* čítání po 100uS */
	 LPC_TIM0->MCR=3; /* int na match a reset po match */
 
	 TIM_ResetCounter(LPC_TIM0);
 
	 /* Nastavení nejvyšší priority přerušení */
	 NVIC_SetPriority(TIMER0_IRQn, ((0x01<<3)|0x01));
	 /* Povolit přerušení čítače */
	 NVIC_EnableIRQ(TIMER0_IRQn);
	 /* Start čítače */
	 TIM_Cmd(LPC_TIM0,ENABLE);

Komunikace s VS1053

Pro obsluhu VS1053 byly užity již existující knihovny, toulající se datovým etherem. Za předpokladu, že bylo stisknuto startovací tlačítko, započne zasílání dat do kodeku po 32B blocích. Je nutné ošetřit kapacitní dispozice bufferu kodeku a také hlídat konec souboru WAV, abychom neodesílali nesmyslná data (doplňující 32B „packet“). Názorná ukázka v následujícím kódu:

while (VS_DREQ_READ() == 1) /* Pokud buffer obvodu VS1053 požaduje nejméně 32bytů dat */
			{
			if (DataRestSize>=32) ToRead=32; /* Pokud zbývá více než 32bajtů, čteme 32 bajtů */
			else
				{
				ToRead=DataRestSize; /* Pokud méně, čteme přesný zbytek bajtů - ošetření konce WAV souboru */
				PLAY_STATUS=DONE;
				}
			f_err_code = f_read(&fil_obj,Buffer,ToRead,&NoOfReadBytes); /* Načtení potřebného množsví dat ze souboru */
			DataRestSize-=NoOfReadBytes; /* Odečteme počet vyčtených bajtů ze souboru */
			WriteSdi(ukazatel,32); /* zapsat data z bufferu do VS1053 */
			}

Ve chvíli, kdy zrovna neodesíláme 32B digitálního zvuku do kodeku (za předpokladu naplněného bufferu), dochází k ověření rychlosti posuvu filmu, resp. ke čtení aktuální délky periody ext. ref. signálu. Dle délky periody je aktualizován obsah registru SCI_CLOCKF audio kodeku. Jako referenční je brán posuv filmu 25fps, tedy 50Hz = 20ms, v případě našeho kódu se jedná o hodnotu 200. Odchylky od této délky periody jsou vyjádřeny poměrově mezi periodou očekávanou a naměřenou. Tento poměr je převeden do procentuální míry zrychlení či zpomalení (např +5,23% nebo naopak -4,34%). Z datasheetu kodeku na str. 42 najdeme vzorce, jak dopočítat konstantu (obsah registru SCI_CLOCKF) pro daný užitý krystal tak, aby dekódování probíhalo v reálném čase. U krystalu 12,288MHz se dopočteme hodnoty 1072. Pokud však tuto hodnotu snížíme, dojde k nesprávně dosazené konstantě a obvod předpokládá osazení krystalu o jiné hodnotě (akceptuje skoky 4kHz, tedy minimální zrychlení či zpomalení o 0,03%, tj. odchylka o cca 1/100 snímku vůči obrazu). Toto „ošálení“ obvodu o tom, že má osazen krystal jiné hodnoty, jej vede k situaci, kdy již neintepretuje zvukový záznam v reálném čase.

Dosazením do vzorců bylo zjištěno, že pro 1% zrychlení je zapotřebí k hodnotě 1072 přičíst hodnotu 30,72. (Při připočtení čísla 100 dojde k cca 3,5% nárůstu tempa přehrávání). Pro zpomalení je postup opačný, je nutno číslo 1072 snižovat. Vzhledem k určení soustažnosti procento zrychlení versus míra úpravy dané konstanty potřebujeme také z referenční externí frekvence získávat pouze informaci o procentuální odchylce. Tato procentuální odchylka (tedy nikoli 102% či 98%, ale +2% či -2%) je tedy násobena dopočteným koeficientem 30,72, čímž získáme rovnou hodnotu přičítanou k hodnotě pro přehrávání v reálném čase (1072). Následuje opět ukázka kódu, která snad postup dostatečně objasní:

if (CounterTime>125 && CounterTime<500) /* 12,5 až 50ms tj 20 až 80Hz */
		{
			float Percent;
			if (CounterTime>200) Percent = (((float)CounterTime/200)-1)*100;
			else if (CounterTime<200) Percent = -1*(((float)200/CounterTime)-1)*100;
			else if (CounterTime==200) Percent = 0;
 
			WriteSci(SCI_CLOCKF, (1072 + (uint32_t)(30.72*Percent)) | SC_MULT_53_35X | SC_ADD_53_10X); /* Změna rychlosti přehrávání VS1053 */
		}
		else
		{
			PLAY_STATUS=ERROR;
			/* pokud je mimo rozsah - lze libovolně ošetřit.  */
		}

A jestli se Vám to vše teď zdá jako jednoduché cvičení, přikládám jeden z papírů tvůrčího procesu, jak vůbec získat vztah mezi vstupní frekvencí a potřebnou hotnotou zapisovanou do registru kodeku:

Závěr

Byť s jinou platformou a jiným DAC (v tomto případě včetně kodeku), se podařil realizovat synchronní přehrávač zvuku. Možnost jeho rozladění ve skocích o 0,03% umožňuje velmi jemnou synchronizaci, byť, pochopitelně, stále nespojitou, digitální. Při uvažování přesnosti měření lidského elementu, kdy rozpoznáme nesrovnalosti v synchronnosti mezi zvukem a obrazem teprve v jednotkách snímků (jeden snímek je 1/25 sec, tedy nesynchronnost 4%), je přenost zařízení dostatečná. Možná by bylo záhodno tolik nedělit výstup čítače TIM0, jelikož další výpočty a převody snižují přesnost dalších výpočtů a chyba může při dlouhém záznamu narůst i do jednotek snímků. Pro účely pokusů je však výstup dostačující.

Přílohy

Veškeré kódy, fotografie, dokumenty EAGLE jsou ke stažení na http://xxx.postreh.com/mpoa.zip

Následuje ještě obrazec DPS audiokodeku:

A omluva za špatnou kvalitu fotografií. Vlastním pouze analogový fotoaparát a jsem teď bez prostředků i bez potřebné vyvolávací chemie. Nový telefon moc zářné výsledky nepřinesl.

2014/synchro-wav.txt · Poslední úprava: 2015/01/18 18:14 autor: Richard Vacula