Hlavní navigace

Zvukový čip POKEY

19. 3. 2009
Doba čtení: 13 minut

Sdílet

V dnešní části našeho pravidelného seriálu o architekturách počítačů si podrobněji popíšeme schopnosti zvukového čipu POKEY (přesný kód obvodu je C012294). Tento čip byl použit prakticky ve všech osmibitových počítačích Atari, také v herních konzolích této firmy a v mnoha herních automatech.

Obsah

1. Zvukové možnosti osmibitových počítačů Atari
2. Zvuková syntéza pomocí obvodu POKEY
3. Poly čítače
4. Sampling
5. Programové řízení obvodu POKEY
6. Ukázky zvuků a hudby generované čipem POKEY
7. Odkazy na Internetu
8. Obsah další části seriálu

1. Zvukové možnosti osmibitových počítačů Atari

Typickým zástupcem osmibitových domácích počítačů, které využívaly pro syntézu zvuku i hudby speciální integrovaný obvod, jsou všechny osmibitové počítače firmy Atari (jednalo se například o modely Atari 400, Atari 800, Atari 600XL/800XL/1200XL, Atari 800XE a Atari 130XE). Pro syntézu zvuku (a také několik dalších důležitých operací popsaných na konci této kapitoly) byl firmou Atari vyvinut integrovaný obvod nazvaný POKEY, jehož jméno je odvozeno od sousloví POtentiometer and KEYboard. Tento čip nebyl použitý pouze v domácích počítačích, ale také v některých herních konzolách firmy Atari a taktéž herních automatech (ostatně pro firmu Atari představovala výroba herních konzolí i automatů v jednu chvíli převážnou část zisků). V případě POKEY se jedná o hybridní integrovaný obvod, který obsahuje jak digitální část (právě ta je použita i pro zvukovou syntézu), tak i část analogovou – obvod je vybaven mj. i funkcí pro převod analogového signálu na osmibitové vzorky, čehož firma Atari využívala pro připojení ovladačů typu paddle ke svým počítačům i herním konzolím (na tyto ovladače můžeme pohlížet jako na konstrukčně jednodušší předchůdce analogových joysticků).

pc5301

Obrázek 1: Osmibitový domácí počítač Atari 800XL. V horním konektoru je zasunuta cartridge obsahující paměť typu EPROM s aplikací (zde hrou) a několik podpůrných součástek. Podobné cartridge, i když bez křiklavě barevných obalů, se vyráběly i u nás – obsahovaly například assemblery, „turba“ pro kazetové magnetofony, kopírovací programy apod.

Kromě zvukové syntézy se integrovaný obvod POKEY používal i pro dat čtení klávesnice (přímá podpora pro maximálně 64 kláves + 3 speciálně zpracovávané klávesy Control, Shift a Break), komunikaci se zařízeními připojenými přes sériový port (jedná se o známé rozhraní SIO – Serial Input/Output), jako generátor pseudonáhodných čísel i ve funkci časovače (tři zvukové kanály bylo možné přepnout do funkce časovače, čehož se využívalo při práci s kazetovým magnetofonem). Právě sloučení mnoha různých funkcí do jednoho čtyřicetipinového integrovaného obvodu umožnilo snížit celkový počet obvodů ve všech osmibitových počítačích Atari, což samozřejmě – v mnohem větší míře než dnes – souvisí i s celkovou relativně nízkou výrobní cenou počítače či konzole, jeho nižší poruchovostí apod. (pro upřesnění: v osmibitových Atari se nacházely čtyři „velké“ obvody se čtyřiceti piny – mikroprocesor MOS 6502, grafický koprocesor ANTIC, grafický čip GTIA a taktéž dnes popisovaný multifunkční obvod POKEY).

pc5302

Obrázek 2: Originální ovladače typu paddle vyráběné firmou Atari. Tyto ovladače bylo možné připojit jak k herním konzolím Atari 2600 a Atari 5200, tak i k osmibitovým domácím počítačům Atari 400, 800, 800XL, 130XE atd.

2. Zvuková syntéza pomocí obvodu POKEY

V předchozí kapitole jsme si řekli, že integrovaný obvod POKEY slouží mj. i ke zvukové syntéze. Zvuk je možné generovat pomocí čtyř zvukových kanálů (lze tedy vytvářet až čtyřhlasou polyfonii), přičemž vždy dva kanály lze v případě potřeby spojit do kanálu jednoho, u něhož je možné přesněji řídit frekvenci zvuku (v podstatě to znamená, že se dva osmibitové čítače/děliče spojí do jednoho čítače šestnáctibitového a změní se zdroj vstupních hodinových signálů – viz další text). Každý zvukový kanál produkuje obdélníkový signál s amplitudou, kterou je možné nastavit do jedné ze šestnácti úrovní (pro specifikaci amplitudy každého kanálu jsou vyhrazeny v ovládacích registrech pouze čtyři bity). Nulová logická hodnota obdélníkového signálu na vstupu vždy vede k nulovému napětí na výstupu zvukového kanálu; logická jednička je převedena na jednu ze šestnácti úrovní napětí. Závislost mezi zvolenou úrovní a napětím není přesně lineární; taktéž generovaný signál není (například po připojení na osciloskop) zcela obdélníkový, čehož se v pozdější době využívalo při tvorbě trojúhelníkových průběhů (ovšem nutno říci, že za značné pomoci mikroprocesoru a přesného časování).

pc5303

Obrázek 3: Označení pinů obvodu POKEY.

Frekvence zvuku v každém zvukovém kanálu je řízena děličem 1:N, který je interně implementovaný jako čítač (ostatně právě na základě čítačů obvod POKEY detekuje stlačené klávesy, generuje pseudonáhodná čísla, provádí A/D převod z ovladačů paddle a komunikuje se SIO). Pokud nejsou zvukové kanály spojeny do dvojic, je vstupní frekvence dělena hodnotou 2×+1, kde x je číslo v rozsahu 0–255 zapsané do řídicího registru obvodu POKEY. Vždy dva zvukové kanály je možné spojit, čímž se sice sníží počet současně přehrávaných zvuků, ale zvýší se přesnost čítače, protože vstupní frekvence může být dělena hodnotou 1 až 2×216+1=131073 (v tomto případě se však volí vyšší frekvence hodinových signálů na vstupu obvodu – z cca 16 kHz na 64 kHz, jinak by po vydělení příliš velkou hodnotou byl na výstupu zvukových kanálů infrazvuk, který se v případě obdélníkového průběhu projevuje pouze „lupáním“ membrány reproduktoru při skokové změně amplitudy). Změnou obsahu řídicího registru obvodu POKEY je možné nakonfigurovat jednu ze tří kombinací zvukových kanálů:

  • Čtyři zvukové kanály, frekvence každého z nich je vytvořena pomocí osmibitového děliče. Tato konfigurace čipu POKEY je použita při práci se zvukem z Atari BASICu (známý příkaz SOUND a,b,c,d). V tomto režimu lze generovat tóny v rozsahu zhruba čtyř oktáv.
  • Dva zvukové kanály, frekvence každého z nich je vytvořena pomocí šestnáctibitového děliče, který vznikl spojením dvou děličů osmibitových. Tónový rozsah z obou stran v tomto případě přesahuje limity lidského sluchu (infrazvuk, ultrazvuk).
  • Jeden zvukový kanál řízený šestnáctibitovým děličem a dva kanály řízené děličem osmibitovým (tuto konfiguraci využívalo mnoho hudebníků, kteří přesněji řízený kanál použili pro basový hudební nástroj a další dva kanály pro perkusní nástroj – někdy samplovaný – a hlavní melodii hranou většinou na vyšších frekvencích).
pc5304

Obrázek 4: Počítač Atari 800 XL s poněkud odlišným designem klávesnice – funkce ovládané klávesou CONTROL zde nejsou popsány inverzně, ale jsou pouze orámovány.

3. Poly čítače

Obdélníkový signál na výstupu každého zvukového kanálu může být buď periodický (a tedy pravidelný), nebo může být řízen takzvaným poly čítačem, který produkuje pseudonáhodné binární hodnoty. Obvod POKEY obsahuje celkem tři poly čítače (čtyřbitový, pětibitový, sedmnáctibitový), jejichž výstup může řídit vybraný zvukový kanál (zvukové kanály se dělí o stejné poly čítače, ovšem každý zvukový kanál může mít nastavenou jinou frekvenci, tj. i výsledný zvuk bude odlišný). U sedmnáctibitového poly čítače (viz další odstavce) je vzdálenost mezi stejnými vzorky (perioda) tak velká, že ho lze považovat za generátor náhodných impulsů, který vytváří bílý šum. Princip řízení zvukového kanálu poly čítačem je velmi jednoduchý – řízení je prováděno obyčejným logickým hradlem a klopným obvodem typu D. Poly čítače sice mění hodnotu na svém výstupu velmi rychle (jsou řízeny přímo hodinovým signálem mikroprocesoru, tj. cca 1,79 MHz pro počítače pracující v normě NTSC a 1,77 MHz pro počítače s televizní normou PAL), ale maximální frekvence na výstupu zvukového kanálu je kvůli zapojenému logickému hradlu omezena frekvencí získanou pomocí děliče 1:N.

pc5305

Obrázek 5: Theta Music Composer, jeden z nejlepších editorů hudby na osmibitová Atari.

Samotný poly čítač, tj. generátor pseudonáhodného šumu, je tvořen posuvným registrem řízeným externím hodinovým signálem. S každým taktem hodin dojde k posunu obsahu registru (tj. čtyř, pěti, sedmnácti a ve speciálním případě devíti bitů) o jednu pozici. Na vstup posuvného registru je zpětnovazební smyčkou přivedena binární hodnota získaná pomocí hradla typu XOR připojeného svými vstupy na třetí a poslední bit posuvného registru – hodnota, na výstupu hradla je tedy zapsána do první pozice. Pokud vezmeme do úvahy logickou funkci, kterou hradlo typu XOR reprezentuje, dojdeme k závěru, že po inicializaci čipu POKEY může mít posuvný registr prakticky jakoukoli nenulovou hodnotu, protože i za této situace rychle dojde k jeho naplnění pseudonáhodnými daty, které se poté periodicky opakují s periodou, jejíž délka závisí na bitové délce samotného posuvného registru. Pokud má registr délku n bitů, je perioda rovna 2n-1 taktům, protože jeden zbývající stav – samé nulové bity – tvoří samostatný (nezajímavý) cyklus. Poslední bit posuvného registru představuje i jeho finální výstup, tj. sekvenci pseudonáhodných binárních hodnot, kterou po zpracování obvodem POKEY (zejména po nastavení amplitudy) slyšíme.

Zatímco čtyřbitové a pětibitové poly čítače produkují poměrně rychle se opakující pseudonáhodné sekvence (lze s nimi napodobit například zvuk leteckých motorů), sedmnáctibitový poly čítač již má délku sekvence tak dlouhou, že s ním lze generovat náhodný zvuk. Tento čítač lze také překonfigurovat tak, že se jeho délka sníží na devět bitů.

Funkci polyčítače si můžeme odsimulovat pomocí jednoduchého céčkového programu, který po svém spuštění vypíše na obrazovku všech n stavů polyčítače o zadané délce (viz symbolická konstanta POLYCOUNTER_LEN­GTH). Pomocí konstant BIT_A_INDEX a BIT_B_INDEX lze určit pozice bitů, které vstupují do hradla XOR, jehož výstup tvoří zpětnovazebnou smyčku:

// vypis stavu polycitace
#include <stdio.h>
#include <stdlib.h>

#define POLYCOUNTER_LENGTH 5
#define BIT_A_INDEX 3
#define BIT_B_INDEX 5

// vypis vsech bitu polycitace
void printPoly( int polycounter )
{
    int i;
    // pro vsechny bity posuvneho registru
    for ( i=0; i<POLYCOUNTER_LENGTH; i++ )
    {
        // vypis binarni hodnoty jednoho bitu
        putchar('0'+ (polycounter & 1) );
        // posun na dalsi bit
        polycounter = polycounter >> 1;
    }
    putchar('\n');
}

int main(void)
{
    // pocatecni hodnota polycitace
    int polycounter = 1;
    int i;
    for ( i=0; i < (1<<POLYCOUNTER_LENGTH); i++ )
    {
        // vypis hodnoty pocitadla i hexadecimalni hodnoty polycitace
        // hodnota polycitace musi byt maskovana na svou max. bitovou delku
        printf("%02d\t%02x\t", i+1, polycounter & ((1<<POLYCOUNTER_LENGTH)-1));
        // vypis vsech bitu polycitace
        printPoly(polycounter);

        // ziskani hodnoty prvniho bitu, ktery jde do zpetnovazebni smycky
        int bitA = (polycounter >> (BIT_A_INDEX-1) ) & 1;

        // ziskani hodnoty druheho bitu, ktery jde do zpetnovazebni smycky
        int bitB = (polycounter >> (BIT_B_INDEX-1) ) & 1;

        // simulace funkce hradla typu XOR
        int inputBit = bitA ^ bitB;

        // posun o jeden bit doleva a nastaveni
        // nove hodnoty prvniho bitu (LSB)
        polycounter = (polycounter << 1) | inputBit;
    }
    return 0;
} 

Výstup z programu pro pětibitový polyčítač (všech 31 nenulových stavů čítače):

01   01      10000
02      02      01000
03      04      00100
04      09      10010
05      12      01001
06      05      10100
07      0b      11010
08      16      01101
09      0c      00110
10      19      10011
11      13      11001
12      07      11100
13      0f      11110
14      1f      11111
15      1e      01111
16      1c      00111
17      18      00011
18      11      10001
19      03      11000
20      06      01100
21      0d      10110
22      1b      11011
23      17      11101
24      0e      01110
25      1d      10111
26      1a      01011
27      15      10101
28      0a      01010
29      14      00101
30      08      00010
31      10      00001
32      01      10000 

Druhý program vypisuje hodnoty posledního bitu polyčítače, který se v čipu POKEY používá pro generování pseudonáhodných zvuků. Aby bylo patrné, že se bitová sekvence na výstupu několikrát opakuje, je vypsáno několik period, každá na zvláštním řádku:

// simulace funkce polycitace (polycounteru)
#include <stdio.h>
#include <stdlib.h>

#define POLYCOUNTER_LENGTH 5
#define BIT_A_INDEX 3
#define BIT_B_INDEX 5

int main(void)
{
    // pocatecni hodnota polycitace
    int polycounter = 1;
    int i,j;
    // projdeme pres nekolik period, aby bylo patrne, ze se hodnoty opakuji
    for ( j=0; j < 10; j++ )
    {
        // vypis cele jedne periody polycitace
        for ( i=0; i < (1<<POLYCOUNTER_LENGTH)-1; i++ )
        {
            // ziskani hodnoty prvniho bitu, ktery jde do zpetnovazebni smycky
            int bitA = (polycounter >> (BIT_A_INDEX-1) ) & 1;

            // ziskani hodnoty druheho bitu, ktery jde do zpetnovazebni smycky
            int bitB = (polycounter >> (BIT_B_INDEX-1) ) & 1;

            // nejvyssi bit polycitace tvori i jeho vystup
            int outputBit = (polycounter >> (POLYCOUNTER_LENGTH-1) ) & 1;

            // vypis vystupni hodnoty
            putchar('0' + outputBit);

            // simulace funkce hradla typu XOR
            int inputBit = bitA ^ bitB;

            // posun o jeden bit doleva a nastaveni
            // nove hodnoty prvniho bitu (LSB)
            polycounter = (polycounter << 1) | inputBit;
        }
        putchar('\n');
    }
    return 0;
} 

Výstup po spuštění druhého programu:

0000100101100111110001101110101
0000100101100111110001101110101
0000100101100111110001101110101
0000100101100111110001101110101
0000100101100111110001101110101
0000100101100111110001101110101
0000100101100111110001101110101
0000100101100111110001101110101
0000100101100111110001101110101
0000100101100111110001101110101 

4. Sampling

V případě potřeby (a také dostatečného výkonu mikroprocesoru) je možné generování obdélníkového signálu zcela vypnout a řídit pouze amplitudu na výstupu každého zvukového kanálu – tímto způsobem lze přehrávat i nasamplované zvuky, ovšem kvůli výše uvedeným vlastnostem čipu POKEY je možné použít pouze šestnáct úrovní hlasitosti, tj. jedná se o čtyřbitový sampling s dynamickým rozsahem pouze 24 dB (naproti tomu CD-Audio využívá šestnáctibitový sampling s dynamickým rozsahem 96 dB a zvuková karta Sound Blaster 1 používá osmibitový sampling s dynamickým rozsahem cca 48 dB, což zhruba odpovídá magnetofonovému záznamu). V případě potřeby je však možné digitalizovaný zvuk přehrávat současně na všech čtyřech zvukových kanálech, čímž se počet úrovní – a tím i dynamický rozsah – nepatrně zvyšuje (součet intenzit není lineární ale logaritmický). Nasamplovaná řeč byla na osmibitových počítačích Atari použita například ve hrách Ghostbusters (krátká ukázka) či Berzerk (tři větičky z této legendární hry, ve které se vyskytuje známý Evil Otto, si můžete poslechnout po výběru tohoto odkazu).

pc5306

Obrázek 6: RMT demo – ukázkový program, přehrávající dvě známé skladby, jejichž Atari verze byly vytvořeny pomocí cross-platform hudebního editoru Raster Music Tracker

5. Programové řízení obvodu POKEY

Pro řízení zvukových kanálů obsahuje integrovaný obvod POKEY devět osmibitových registrů, které jsou na počítačích Atari mapovány na adresy 53760–53768 (zde stojí za připomenutí fakt, že příště popsaný zvukový čip SID obsahuje řídicích registrů mnohem více, protože je možné měnit více vlastností zvukové syntézy, například obálky, tvary signálů aj.). Těchto devět registrů je možné rozdělit do tří skupin. V první skupině se nachází celkem čtyři registry obsahující osmibitové hodnoty frekvenčního děliče. Pro každý zvukový kanál (kterých je, jak již víme z předchozího textu, celkem čtyři), je určen jeden z těchto registrů. To znamená, že každý kanál může používat odlišnou frekvenci výstupního zvuku a tím i výstupní tón. V některých případech může být pouhých 256 různých frekvencí poměrně hrubé, proto je možné vždy dva zvukové kanály spojit a využít šestnáctibitového děliče. Ve druhé skupině se nachází taktéž čtyři registry, každý registr je určený pro jeden ze zvukových kanálů. Čtyři bity každého registru určují hlasitost zvuku, jedním bitem se zapíná či vypíná pulsní režim a třemi posledními bity se určuje zkreslení, přesněji řečeno způsob zapojení výše popsaných poly čítačů do celého řetězce generujícího zvuk. Kromě toho lze určit, že první ze dvou kanálů vytvoří frekvenční filtr typu horní propust (resp. jeho velmi hrubou obdobu založenou na logické operaci a ne na skutečném frekvenčním filtru).

pc5307

Obrázek 7: Filtr tvořený jedním zvukovým kanálem, který je aplikovaný na druhý zvukový kanál.

6. Ukázky zvuků a hudby generované čipem POKEY

Zvuky a melodie, jejichž ukázky si můžete stáhnout ve formátu MP3 z tabulky zobrazení níže, byly získány především z archivu ASMA – Atari SAP music archive (http://asma.a­tari.org/), ve kterém jsou dostupné ve formátu SAP (v současnosti je v archivu uloženo cca 2500 ukázek). Formát SAP je velmi úsporný, protože v souborech jsou ukládány pouze hodnoty řídicích registrů čipu POKEY, nikoli celé samply. Z toho důvodu například hudba původně uložená v souboru typu SAP na pouhých čtyřech kilobajtech zabere po transformaci do „úsporného“ formátu MP3 i několik megabajtů (v následující části tohoto seriálu budou uvedeny ukázky melodií pro čip SID, u nichž je použitý principiálně stejný formát založený na ukládání hodnot řídicích registrů tohoto čipu). Existuje několik přehrávačů pro formát SAP; pravděpodobně nejpoužívanějším způsobem přehrávání těchto souborů je však použití pluginů pro universální přehravač Winamp či (na Linuxu) XMMS.

7. Odkazy na Internetu

  1. Atari.org
    http://www.ata­ri.org/
  2. Atari POKEY
    http://www.ab­soluteastrono­my.com/topics/A­tari_POKEY
  3. Chiptune
    http://www.ab­soluteastrono­my.com/topics/Chip­tune
  4. ASAP – Another Slight Atari Player
    http://asap.sou­rceforge.net/
  5. Atari SAP music archive
    http://asma.a­tari.org/
  6. RASTER Music Tracker (RMT)
    http://raster­.infos.cz/ata­ri/rmt/rmt.htm
  7. ATARI + ATARI = STEREO ???
    http://anonym­.mouse.sweb.cz/ste­reo.htm
  8. Otázky o Atárku
    http://raster­.infos.cz/ata­ri/afaq/afaq.htm

skoleni

8. Obsah další části seriálu

Původně jsem měl v úmyslu v dnešním článku popsat kromě čipu POKEY i slavný zvukový čip SID firmy Commodore, nicméně se ukázalo, že kvůli velkému množství informací bude vhodnější článek rozdělit na dva samostatné díly. Proto se budeme dodnes stále používanému SIDu věnovat až v následujícím pokračování tohoto seriálu (nehledě na to, že porovnávat v jednom textu POKEY a SID by i dnes bylo pro autora poměrně nebezpečné :-).

pc5308

Obrázek 8: Osmibitový domácí počítač Commodore C64 (vybavený prakticky stejným mikroprocesorem jako konkurenční osmibitová Atari), jehož světový úspěch do značné míry závisel (kromě dumpingových cen) i na schopnostech čipů SID (zvuky) a VIC (grafika).

Autor článku

Pavel Tišnovský vystudoval VUT FIT a v současné době pracuje ve společnosti Red Hat, kde vyvíjí nástroje pro OpenShift.io.