MOD-player

   Jedná se o přehrávač hudebních souborů MOD. Jde o podobný formát jako MID, což jsou soubory, ve kterých jsou uloženy jen noty, podle kterých SW přehrává vzorky uložené v ovladačích nebo přímo ve zvukové kartě. Soubory MOD obsahují také noty, ale navíc v sobě nesou až 31 vzorků vlastních nástrojů. S příchodem hudebního formátu MID a hlavně MP3 byly odsunuty do pozadí. I přes to jsem se rozhodl postavit přehrávač těchto souborů, protože mě zajímalo, zda je 8-bitový MCU řady AVR dostatečně rychlý, aby je mohl přehrávat. První verze fungovala překvapivě docela dobře (překvapilo mě, že vůbec nějak :-), takže jsem ji pořád rozšiřoval a upravoval a prozatimní výsledek můžete posoudit sami.


Základní parametry

Vzorkování: 22321.42 Hz
Počet kanálů: 4 (mix do 2)
Nástrojů (vzorků): 15 nebo 31
Způsob převzorkování: lineární interpolace

Popis zapojení

   Pro konstrukci jsem zvolil největší MCU řady ATmega, který se vyrábí v pouzdře DIL, abych nemusel vyrábět redukci do kontaktního pole - ATmega32. Má celkem 32 I/O pinů, taktovací kmitočet 16MHz, dostatek RAM (2kB) a všechny periferie, co jsou potřeba. V první verzi jsem soubory četl přímo z 1MB EPROM, což bylo docela pomalé, takže jsem na stejnou sběrbici připojil ještě 512kB SRAM (největší, co jsem sehnal (u GME)), do které se skladba před přehráváním kopíruje. Adresy jsou díky nedostatku vývodů řízeny jen portem PORTA s pomocnými D-buffery 74HC547. Trochu to zpomaluje práci, ale je to jen 8 cyklů na jedno čtení navíc. Na PORTA jsou připojeny ještě tlačítka ovládání. Data jsou na portu PORTC, zároveň s daty LCD displeje 2x 20 znaků s řadičem HD44780 nebo kompatibilním. Zbylé porty PORTB a PORTD ovládají jednotlivé piny bufferů, pamětí, ...
   DA převodník jsem původně měl 8-mi bitový z odporové sítě R-2R, ale při nižších hlasitostech se objevoval nepříjemný šum. Digitální regulací hlasitsti (jeden z efektů MODu) se původních 8 bitů stejně rozšírí na 16, takže jsem zapojení nakonec předělal pro 16-bitový převodník. Vytváření větší odporové sítě jsem zavrhl, takže jsem se nakonec rozhodl pro stereo 16-bitový převodník TDA1543 (nebo TDA1545, který se ale asi přestal vyrábět a sehnat se dá jen ojedinělě nebo občas bývá ve starších CD mechanikach). Zapojení jsem tedy mimo 16 bitů rozšířil i na stereo. Nevýhodou těchto převodníků je, že mají poměrně nešikovnou sériovou sběrnici I2S. Data a hodiny sbernice I2S jsou generovány přes SPI rozhraní, signál pro pin WS (časový multiplex) je genrován pomocí instrukcí behěm vlastního vysílní přes ISP (odeslání vzorků pro levý a pravý kanál trvá asi 70 cyklů). Každý z převodníků se zapojuje jinak, takže je třeba ze schématu vybrat správnou variantu. TDA1543 má dost vysoký odběr (asi 50mA) narozdíl od TDA1545, který bere jen asi 7mA. Napájení operačních zesilovačů (převodník proud/napětí) za každým kanálem DA není zakresleno a může to být klidně jen 0 a +5V. Čtveřice odporů na výstupu tvoří častečný mix kanálů.



   Na portu PORTD je ještě sériový kanál USART pomocí kterého lze nahrát jednu skladbu do RAM. Převoník na RS232 je tvořen klasicky obvodem MAX232. RAM je zálohována malým 3V lithiovým článkem, takže po vypnutí napájení uchová nahraná data. Odběr samotné paměti v úsporném režimu jsem při 3V baterii změřil na nějakých 100nA, což je vynikající, jenže dalších 300nA teče přes schottkyho diodu D10 do napájení :-(. I tak ale 100mAh baterie vydrží asi 15let. Těch pár, většinou pasivních, součástek připojených mezi vývodem CE u RAM a MCU je ochranný obvod, který zajistí, že po zapnutí napájení nebo při sériovém programování MCU nedojde k poškození dat. Při vypnutí napájení tranzistor rozepne a RAM přejde do úsporného režimu.
   Všude do napájení (hlavně kolem DA převodníku) je vhodné vložit kondenzátory (keramiku i tantaly), jinak je ve zvuku slyšet šum a bzučení digitální části. Důležité je také vedení zemí, což mě ovšem na kontaktním poli moc bolet nemusí :-). MCU je taktován krystalovým oscilátorem na 20MHz. Je to sice trochu víc něž udávaná maximální hodnota, ale pracuje mi bezchybně až do 32MHz. U většiny skladeb sice stačí takt 16MHz, ale v některých případech ne. S krystalem 20MHz sice oscilátor normálně kmital a všechno fungovalo, ale pořád jsem se divil, přoč při sériovém přenosu přes USART dochází k chybám. Po několika dnech nadávání a předělávání, jsem zjistil, že chyba není v SW nebo nastavení USARTu, ale že díky nešťastnéu umístění pinu RX hned vedle pinu XTAL1 dochází k rušení oscilátoru. Proto raději používám externí oscilátor 20MHz.
   Celému zapojení stačí jen jedno napájení 5V a odběr s DAC TDA1545 je asi 100mA.

Ovládání

   K tomu skoro není co dodat. Po zapnutí napájení se automaticky čte poslední skladba z RAM a po jejím přerátí se opakuje. Na LCD je po zapnutí zobrazeno "Nacitam data ...". Nápis je zobrazen asi po dobu 2s - běží timeout časovač. Během této doby je přehrávač připraven přijímat data po USARTu ve formátu 115200bd, 8 datových bitů, 1 stop bit, bez parity. Po skončení přenosu a uplynutí 2s se začne přehrávat. Data je možno přijímat nejen po zapnutí, ale také po stisku tlačítka COM. Pokud nedojde k příjmu dat, přehrává se původní skladba. Pokud dojde k příjmu s chybou, tak se může stát, že přehrávač "vytuhne" nebo neustále píše "Nacitam data ...". Z tohoto stavu se lze dostat stiskem skladba +/-. Těmito tlačítky se načítají data z externí paměti (v mém případě EPROM). Tlačítka list +/- ručne mění číslo přehrávaného listu v MODu. Poslední tlačítko je PAUSE a jeho funkci doufám není třeba vysvětlovat.
   Během přehrávání je na horním řádku LCD název skladby, na dolním "řádek listu/list/počet listů", následně 4 bargrafy pro každý ze 4 kanálů a nakonec další 2 bargrafy pro mix levého a pravého kanálu (holt pouťové efekty na takovém LCD musí být :-).

Program pro jednočip

   Program je napsán kompletně v assembleru a zatím má něco přes 3000 řádků, po přeložení skoro 6kB. Původní verze měla přímý výstup vypočtených dat, ale zvuk byl poněkud chraplavý, protože načtení řádku not trvá docela dlouho a tok dat byl nerovnoměrný. Navíc po přidání některých efektů (hlavně portamento) přibylo asi 300 cyklů dlouhé dělění a hned 2x za sebou a v nejhorším případě pro všechny 4 kanály, což delá spolu s dalšími výpočty asi 150us dlouhý blok operací asi 30x za sekundu. Proto jsem se rozhodl přidat FIFO registr. Zbylo mi asi 1300B RAM, takže jsem jeho velikost nastavil na 1200B (lze ji měnit), což je při použitém vzorkování asi 10ms zvuku.
   Nyní je tedy program členěn do několika hlavních částí. Vždy před začátkem přehrávání je přečtena hlavička souboru, detekován typ souboru a potřebná často pužívaná data, jako jsou třeba adresy vzorků v souboru, jsou uloženy do interní RAM. Další částí programu je vlastní smyčka, ve které se vypočítávají zvuková data. Nejprve se zjišťuje, jestli je ve FIFO místo. Když ano, spustí se výpočet a uloží se spočítaný vzorek pro pravý a levý kanál. V určitém místě této smyčky se obsluhují data z tlačítek, která jsou čteny nezávisle pomocí přerušení od vlastního časovače. Jednou za přesně definovaný počet průchodů smyčkou (záleží na rychlosti udané skladbou) se přečte další řádek not, kde se nastaví registry, které během výpočtu zvukových dat udávají, co se vlastně má dělat.
   Poslední důležitá část je pravidelné čtení z FIFO registru, které je spouštěno dalším časovačem. Zde se přečte jeden vzorek pro každý kanál z FIFO registru a pošle DA převodníku. Tato část spolu s vlastním výpočtem zvuku je klíčová a musí být co nejrychlejší. Z tohoto důvodu je kód ještě nepřehlednější než obvyklý ASM, protože jsou zde různé "fígle" pro zrychlení.
   Každý nástroj lze přehrávat různou rychlostí, takže je nezbytně nutné, aby došlo k převzorkování na jinou frekvenci. To jsem nejdříve řešil metodou přehrávání nejbližšího vzorku, původního signálu (tato metoda bývá označována "no resampling"). Zvuk byl logicky chraplavý, protože vznikaly skokové změny. Později jsem se rozhodl pro tzv. linární interpolaci, kterou lze dopočítat hodnotu vzorku, který leží na pomyslné spojnici okolních 2 vzorků původního signálu. Zvuk je nyní perfektní (v rámci možností :-) a zabralo to jen asi 25 cyklů navíc.
   V obsluze výstupu FIFO registru (někde na začátku hned za definicí proměnných) se musí vybrat kus kódu buď pro TDA1543 nebo TDA1545. Jsou tam popisky, takže by to neměl být problém.    Další věcí, kterou je třeba nastavit ve zdrojáku jsou adresy začátků skladeb v externí paměti a jejich celkový počet. Tabulka adres je hned pod obsluhou výstupu FIFO registru.
Zdrojový kód a překlad do HEX (pro TDA1545) v zipu.

Podporované efekty a formáty

   Dokáže přehrát nekomprimované 4 kanálové MODy s 31 nebo 15 nástroji do velikosti 524288B (omezeno RAM). 4-kanálové MODy s 31 nástroji mají od bytu 1080 text "M.K." nebo "FLT4" (jiné jsou vyhodnoceny jako 15 nástrojů a pokud to tak není, budou se přehrávat nesmysly).


Podporované efekty
0 Arpeggio plně funkční
1 Portamento up většinou plně funkční
2 Portamento down většinou plně funkční
3 Tone-portamento plně funkční
4 Vibrato zatím není
5 Tone-portamneto + Volume slide plně funkční
6 Vibrato + Volume slide Vibrato není, Volume slide plně funkční
7 Tremolo zatím není
8 Panning (stereováha) není a nebude, použitý algoritmus neumožňuje
9 Nastevení ofsetu vzorku plně funkční
A Volume slide plně funkční
B Skok na jiný list záměrně není - používá se pro cyklení skladeb
C Nastav hlasitost plně funkční
D Skok v listu funkční, ale jen zalomí list, neskáče v listu
E0 Nastav filtr nevím co to je - v MPtrackeru to nic nedělá
E1 Portamento up jemně funguje, ale ne přesně
E2 Portamento down jemně funguje, ale ne přesně
E3 Glissandro není a nebude, nepoužívá se
E4 Vibrato waveform zatím není
E5 Fine-tune zatím není
E6 Pattern loop zatím není
E7 Tremolo waveform zatím není
E9 Retrig note není a nebude - nevím co to je
EA Volume slide up jemně plně funkční
EB Volume slide down jemně plně funkční
EC Cut note není a nebude, nevím jak přesně to funguje
ED Note delay není a nebude, nevím jak přesně to funguje
EE Pattern delay zatím není
EF Invert loop není a nebude
F Set speed/tempo plně funkční

Několik nahrávek z MOD-playeru

   V ZIPech je vždy nahrávka ve formátu MP3 a originální skladba. Soubory mají každý asi 700kB a jsou 1 minutu dlouhé.
dragonsfunk.zip
severalkbytes.zip
tarsnareslider.zip
mrazikv2.zip


(c) 2005, Stanislav Mašláň - využití programu ke komerčním účelům bez souhlasu autora není dovoleno.

Poslední aktualizace: 11.6.2005