Artykuły

    Zniekształcenie C w generatorze dźwiękowym POKEY

    Wstęp

    Motywacją do stworzenia tego artykułu była moja chęć a właściwie nawet konieczność użycia tzw. basów C generatora POKEY w ścieżce dźwiękowej do jednej z tworzonych gier. Basy C to jedna z kilku metod wytwarzania dźwieków basowych w generatorze POKEY, polegająca na użyciu tzw. zniekształcenia C. Powszechnie wiadomo, że basy C mają ładniejsze brzmienie niż basy uzyskiwane innymi metodami ale niestety są niestabilne, co w praktyce ogranicza ich użycie. Nie było dla mnie jasne co w tym przypadku oznacza niestabilność. Po zrealizowaniu wspomnianej ścieżki dźwiękowej zauważyłem, że niestabilność dotyczy zarówno barwy jak i częstotliwości dźwięku wytwarzanego przy użyciu zniekształcenia C. Powstało więc pytanie, czy i jak można ustabilizować basy C. Na forach internetowych odnalazłem kilka wątków dotyczących tego problemu. Remedium miała być synchronizacja liczników POKEY-a poprzez programowy "reset". Obejmowała ona m. in. tzw. liczniki wielomianowe odpowiedzialne za wytwarzanie zniekształceń. Okazało się jednak, że użycie procedury synchronizującej liczniki wcale nie rozwiązało problemu niestabilności. Dlaczego? Przede wszystkim dlatego, że sam problem nie był dobrze określony. Nie było wiadomo kiedy dokładnie synchronizacja jest potrzebna. Kiedy ją tracimy i kiedy musimy ją ponowić. Czy i jak długo mamy kontrolę nad stanem synchronizacji liczników. Dokładne zdefiniowanie problemu oraz odpowiedzi na pytania postawione powyżej stanowią przedmiot tego artykułu.

    Dźwięki basowe wytwarzane przez POKEY

    Układ POKEY pozwala wytwarzać dźwięki o niskiej częstotliwości, czyli basy, na kilka sposobów. W zależności od sposobu basy różnią się brzmieniem oraz dostępnym zakresem częstotliwości. Z nomenklatury trackera RMT wywodzą się umowne nazwy trzech sposobów generacji powszechnie rozumianych jako trzy rodzaje basów. Są to tzw. basy C, basy E oraz basy 16-bit. Wszystkie trzy wykorzystują zniekształcenie C POKEY-a (AUDCx = $Cv). Istnieją też techniki wytwarzania basów oparte na zniekształceniu A ale nie są one przedmiotem tego artykułu. Brzmienia basów C i E różnią się dość znacznie. Basy C mają ładną, miękką barwę, co jest ich zaletą. Basy E brzmią bardziej ostro i nieco industrialnie. Zarówno basy C jak i E uzyskuje się przy użyciu pojedynczego kanału POKEY-a (8-bitowy podzielnik częstotliwości). Jedne i drugie uzyskuje się przy pomocy tego samego zniekształcenia C, co oznacza, że konkretne wartości podzielnika częstotliwości decydują, którego typu basy zostaną wygenerowane.

    Brzmienia o takich samych charakterystykach jak basów C i E można też uzyskać używając 16-bitowych podzielników częstotliwości (łącząc dwa kanały POKEY-a). Basy nazywane wg nomenklatury RMT basami 16-bit to basy o takim samym brzmieniu jak basy E.

    Zaletą basów C i E jest to, że wymagają tylko jednego kanału POKEY-a. W przypadku basów 16-bit wymaganie dwóch kanałów należy uznać za wadę. Z kolei zaletą basów 16-bit jest znacznie większa "gęstość" występowania podzielników właściwych dla danego brzmienia w całej palecie dostępnych podzielników (64k) co oznacza szerszy zakres dostępnych tonów jak również większą precyzję dobranych częstotliwości, co skutkuje lepszym zestrojeniem z czystymi tonami uzyskiwanymi przy zniekształceniu A.

    Basy C mają poważną wadę polegającą na niestabilności brzmienia. Wady tej nie mają basy E i basy 16-bit (te o brzmieniu takim jak basy E). Dokładniej mówiąc, basy C mają trzy różne brzmienia a to, które z nich jest użyte, zależy od wybranej częstotliwości i momentu, w którym nastąpiła zmiana częstotliwości.

    Zależność brzmienia basów C od momentu zmiany częstotliwości przekłada się na niestabilne brzmienie muzyki, która może brzmieć inaczej w kolejnych cyklach odtwarzania. Ponadto zależność brzmienia od momentu zmiany oraz od samej częstotliwości powoduje, że każda z kolejnych nut linii basu może przybierać losowo jedno z trzech brzmień.

    Niestabilność brzmienia basów C nie wynika z błędnej konstrukcji ani uszkodzenia układu POKEY, lecz z czystej matematyki. Jest konsekwencją przyjętych przez konstruktorów wartości stałych podzielników częstotliwości głównego zegara taktującego stosowanych do pozostałych zegarów POKEY-a.

    Problem niestabilmości niektórych częstotliwości zniekształcenia C był zapewne znany konstruktorom układu POKEY. Nigdy jednak nie udokumentowano sposobu na ustabilizowanie tego typu dźwięków. W dalszej części artykułu zawarty jest dokładny opis sposobu generowania dźwięków przez układ POKEY przy użyciu zniekształcenia C oraz opis sposobów stabilizacji brzmienia takich dzwięków w przypadku użycia częstotliwości, dla których taka niestabilność występuje.

    Wytwarzanie dźwięku przez POKEY

    Wyjaśnienie zasad wytwarzania dźwięku o zniekształceniu C wymaga najpierw wyjaśnienia kilku podstawowych pojęć związanych z wytwarzaniem dźwięku przez POKEY w ogóle.

    POKEY generuje sygnały binarne czyli sekwencje składające się z próbek o wartości 0 lub 1. Wartość próbki jest ostatecznie mnożona przez głośność ustawioną dla danego kanału na czterech mniej znaczących bitach rejestru AUDCx. Sama głośność nie ma jednak znaczenia dla dalszego opisu.

    Kolejne próbki danego kanału pojawiają się na wyjściu audio z pewną częstotliwością, którą nazwiemy częstotliwością generacji próbek (ang. sample generation rate). Częstotliwość ta jest odpowiednikiem częstotliwości odtwarzania próbek (ang. sample playback rate) w generatorach dźwięku korzystających z pamięci próbek.

    Częstotliwość generacji próbek nie jest częstotliwością generowanego dźwięku ale obie są od siebie zależne. Fala dźwiękowa o zniekształceniu A, czyli czysty ton, składa się z na przemian pojawiających się próbek o wartościach 0 i 1. Okres generowanej fali składa się więc z dwóch próbek a częstotliwość tej fali jest dwa razy mniejsza od częstotliwości generacji próbek. W przypadku zniekształcenia C zależność obu częstotliwości nie jest taka prosta, o czym później.

    Częstotliwość generacji próbek wynika z wybranego dla danego kanału sygnału zegara taktującego oraz podzielnika częstotliwości tego zegara ustawionego w rejestrze AUDFx.

    Dostępne są trzy sygnały zegarowe:

    Zegar

    Częstotliwość

    phi2

    fphi2 = 1.77 MHz (PAL) / 1.79 Mhz (NTSC)

    div28

    fdiv28 = 64 kHz = fphi2/28

    div114

    fdiv114 = 15.6 kHz = fphi2/114

    Zegar phi2 to główny zegar taktujący. Jest on dostarczony do układu POKEY z zewnątrz. Ten sam sygnał taktuje też CPU i inne układy wewnątrz małego Atari. Częstotliwości zegarów div28 i div114 wynikają z podzielenia częstotliwości zegara phi2 przez stałe podzielniki odpowiednio 28 i 114.

    Dla wszystkich czterech kanałów POKEY-a można wybrać wspólny sygnał zegarowy którym może być tylko div28 lub div114. Dodatkowo dla kanałów 1 i 3 można ustawić taktowanie zegarem phi2 niezależnie od wybranego zegara wspólnego. Nie jest możliwe aby jeden kanał taktować zegarem div28 a inny w tym samym czasie zegarem div114.

    Zniekształcenie C

    Fala dźwiękowa o zniekształceniu C powstaje w wyniku próbkowania (samplowania) powtarzającej się cyklicznie sekwencji binarnej generowanej przez 4-bitowy licznik wielomianowy nazywany dalej poly4. Choć licznik jest 4-bitowy to sekwencja pochodzi z jednego tylko bitu – tego o najmniejszym znaczeniu. Próbkowanie odbywa się z częstotliwością wynikającą z wybranego podzielnika w AUDFx oraz wybranego zegara taktującego dany kanał. Częstotliwość próbkowania wyjścia licznika poly4 jest tożsama z częstotliwością generacji próbek na wyjściu audio POKEY-a. Zależność między częstotliwością generacji próbek a częstotliwością generowanego dźwięku nie jest tak oczywista jak w przypadku zniekształcenia A. Częstotliwość generowanego dźwięku dla zniekształcenia C zależy od ilości próbek z poly4 przypadających na pojedynczy okres generowanej fali.

    Sama sekwencja licznika poly4 składa się z 15 elementów (bitów) i generowana jest z częstotliwością głównego zegara taktującego phi2. Sekwencja ta pokazana jest na rysunku poniżej.

    Rys. 1. Sekwencja binarna wytwarzana cyklicznie przez licznik poly4

    Kolejne elementy (bity) sekwencji oznaczone są odpowiednio E0 – E14. Powtarzającą się cyklicznie sekwencję licznika poly4 nazwijmy sygnałem poly4.

    Wynikowy kształt fali zniekształcenia C to sekwencja bitów powstała przez próbkowanie powtarzającej się sekwencji licznika poly4.

    Zależność brzmienia zniekształcenia C od podzielnika częstotliwości. Próbkowanie.
    Częstotliwość próbkowania sygnału poly4 jest zależna od podzielnika w AUDFx oraz wybranego zegara a sam licznik poly4 taktowany jest zawsze zegarem phi2. Aby dobrze zrozumieć zależność między częstotliwościami taktowania i próbkowania licznika poly4 konieczne jest wprowadzenia pojęcia bezwzględnego podzielnika częstotliwości zegara phi2 (ang. absolute phi2 divider) określającego częstotliwość próbkowania sygnału poly4. Podzielnik ten jest jednocześnie długością okresu próbkowania sygnału poly4 wyrażoną w liczbie cykli zegara phi2 i będzie dalej oznaczany literą p.

    Długość okresu próbkowania sygnału poly4 (bezwzględny podzielnik częstotliwości zegara phi2) to iloczyn względnego podzielnika częstotliwości wynikającego z wartości w AUDFx oraz stałego podzielnika używanego do uzyskania wybranego zegara przez podział częstotliwości głównego zegara phi2. Względny podzielnik będzie oznaczany przez div. Stały podzielnik ma wartość odpowiednio 28 w przypadku zegara div28 (64kHz), 114 w przypadku zegara div114 (15,6kHz) oraz 1 w przypadku użycia zegara phi2.

    Oto wzory na względny i bezwzględny podzielnik częstotliwości w zależności od wybranego zegara taktującego i wartości nastaw w rejestrach AUDFx:

    Zegar bazowy

    Długość słowa nastawy

    Podzielnik względny

    Podzielnik bezwzględny (okres próbkow.)

    div28

    8 bitów

    div = AUDFx + 1

    p = div * 28

    div28

    16 bitów (dwa kanały)

    div = AUDFxy + 1

    div114

    8 bitów

    div = AUDFx + 1

    p = div * 114

    div114

    16 bitów (dwa kanały)

    div = AUDFxy + 1

    phi2

    8 bitów

    div = AUDFx + 4

    p = div

    phi2

    16 bitów (dwa kanały)

    div = AUDFxy + 7

    Tab. 2. Wzory na względny i bezwzględny podzielnik częstotliwości (okres próbkowania) w zależności od nastaw

    Długość sekwencji poly4 czyli liczba 15 ma (oprócz samej siebie i 1) dwa podzielniki – 3 i 5, które są jednocześnie liczbami pierwszymi. Konsekwencją tego faktu jest istnienie różnych kategorii brzmień uzyskiwanych z próbkowania tej sekwencji. Związek pomiędzy liczbami 3 i 5 a kategoriami brzmienia wyjaśni się w dalszej części tego rozdziału.

    Istnieją cztery kategorie brzmienia (kształtu fali) zniekształcenia C zależne od wybranego podzielnika częstotliwości:

    Kategoria

    Charakterystyka brzmienia

    C1

    brzmienie stabilne – jedna barwa (basy E i 16bit)

    C2

    brzmienie niestabilne – trzy barwy (basy C)

    C3

    brzmienie niestabilne – jedna barwa lub cisza

    C4

    cisza

    Tab. 3. Cztery kategorie brzmienia zniekształcenia C

    Choć najbardziej interesująca jest zależność brzmienia od ustawienia AUDFx określającego podzielnik częstotliwości, to znacznie prościej jest zrozumieć zależność od bezwzględnego podzielnika częstotliwości zegara phi2 czyli inaczej mówiąc od okresu próbkowania sekwencji poly4.

    Zbiór wszystkich możliwych do uzyskania bezwzględnych podzielników częstotliwości zegara phi2 to innymi słowy zbiór wszystkich nastaw częstotliwości dostępnych w układzie POKEY. Ponieważ mamy do dyspozycji trzy zegary bazowe i dla każdego możemy użyć jednej z 65536 wartości podzielnika to liczność zbioru nastaw to 3 * 65536 czyli około 196000. W praktyce jest ona mniejsza bo część nastaw dla różnych zegarów pokrywa się dając efektywnie taki sam podzielnik.

    Zbiór wszystkich możliwych do uzyskania okresów próbkowania sekwencji poly4 (~ 196k wartości) dzieli się na cztery rozłączne podzbiory odpowiadające wspomnianym wyżej czterem kategoriom brzmienia:

    Kategoria

    Zbiór okresów (podzielników)

    Charakterystyka okresów próbkowania

    C1

    P1

    okres próbkowania nie jest wielokrotnością 3 ani 5

    C2

    P2

    okres próbkowania jest wielokrotnością 3 i nie jest wielokrotnością 5

    C3

    P3

    okres próbkowania jest wielokrotnością 5 i nie jest wielokrotnością 3

    C4

    P4

    okres próbkowania jest wielokrotnością 3 i 5 a przez to również 15

    Tab. 4. Cztery zbiory okresów próbkowania odpowiadające czterem kategoriom brzmienia zniekształcenia C

    Najprostszą sytuację mamy w przypadku kategorii C4. Wiemy, że próbkowana sekwencja ma okres składający się z 15 elementów. Próbkowanie z okresem będącym wielokrotnością 15 oznacza, że próbkowany jest ciągle ten sam element sekwencji poly4. Niezależnie, czy ma on wartość 0 czy 1, na wyjściu otrzymujemy sygnał stały czyli ciszę.

    Aby łatwiej zrozumieć mechanizmy rządzące próbkowaniem w pozostałych kategoriach należy najpierw zredukować przestrzeń problemu czyli dziedzinę obejmującą wszystkie możliwe okresy próbkowania (~ 196k wartości). Należy zauważyć, że interesująca jest tylko ta część okresu próbkowania, która zostaje po odjęciu największej możliwej wielokrotności liczby 15, czyli inaczej reszta z dzielenia okresu próbkowania przez 15. Największa możliwa wielokrotność liczby 15, jaka mieści się w okresie próbkowania, może zostać pominięta, ponieważ nie ma znaczenia ile razy przesuniemy się o całą sekwencję poly4. Nadal będziemy próbkować ten sam element sekwencji. Znaczenie ma tylko reszta z dzielenia przez 15, ponieważ to ona oznacza, o ile elementów sekwencji przesuniemy się względem elementu z poprzedniej próbki.

    Jeżeli okres próbkowania oznaczymy przez p a resztę z dzielenia przez R to R obliczamy z następującego wzoru:

    R = p MOD 15

    R przyjmuje wartości z zakresu od 0 do 14.

    Reguły podane w tabeli poniżej dzielą zbiór okresów próbkowania (podzielników bezwzględnych) na cztery podzbiory odpowiadające czterem kategoriom brzmienia oraz zgodnie z powyższym wzorem przypisują im odpowiednie podzbiory wartości R.

    Kategoria

    Reguła mapowania dziedzin zgodnie z wzorem R = p MOD 15

    C1

    jeżeli p nie jest wielokrotnością 3 ani 5 (p ∊ P1) to R nie jest wielokrotnością 3 ani 5 oraz R != 0

    (R ∊ {1, 2, 4, 7, 8, 11, 13, 14})

    C2

    jeżeli p jest wielokrotn. 3 i nie jest wielokrotn. 5 (p ∊ P2) to R jest wielokrotnością 3 oraz R != 0

    (R ∊ {3, 6, 9, 12})

    C3

    jeżeli p jest wielokrotn. 5 i nie jest wielokrotn. 3 (p ∊ P3) to R jest wielokrotnością 5 oraz R != 0

    (R ∊ {5, 10})

    C4

    jeżeli p jest wielokrotnością 15 (p ∊ P4) to R = 0

    Tab. 5. Reguły dzielące zbiór okresów próbkowania oraz zbiór R na odpowiadające sobie podzbiory

    Tak więc dziedzinę wszystkich możliwych do ustawienia okresów próbkowania sekwencji poly4 (lub inaczej dziedzinę podzielników bezwzględnych) można zastąpić przez 15-sto wartościową dziedzinę R czyli reszt z dzielenia okresów próbkowania przez 15, redukując tym samym przestrzeń problemu do rozmiaru dającego się w łatwy sposób analizować. Reguły mapowania dziedzin w zwięzłej formie są przedstawione jeszcze raz w tabeli poniżej.

    Kategoria

    Zbiór okresów próbkowania

    Reguła mapowania dziedzin

    C1

    P1

    p ∊ P1 ↔ R ∊ {1, 2, 4, 7, 8, 11, 13, 14}

    C2

    P2

    p ∊ P2 ↔ R ∊ {3, 6, 9, 12}

    C3

    P3

    p ∊ P3 ↔ R ∊ {5, 10}

    C4

    P4

    p ∊ P4 ↔ R = 0

    Tab. 6. Mapowanie dziedziny okresów próbkowania na dziedzinę R - reszt z dzielenia przez 15

    Kolejna tabela pokazuje wprost przynależność poszczególnych wartości R do czterech kategorii brzmień (po pozbyciu się zbiorów okresów próbkowania).

    Kategoria

    R

    C1

    1, 2, 4, 6, 7, 8, 11, 13, 14

    C2

    3, 6, 9 ,12

    C3

    5, 10

    C4

    0

    Tab. 7. Przynależność wartości R (reszt z dzielenia okresu próbkowania przez 15) do kategorii brzmień

    Wartość reszty z dzielenia R określa interwał czasowy próbkowania, czyli ilość elementów sekwencji poly4 o jaką przeskakujemy przy kolejnych próbkowaniach.
    W tym miejscu trzeba zaznaczyć, że zamieniając dziedzinę okresów próbkowania na dziedzinę interwałów R należy trochę zmienić sposób myślenia. Można zwyczajnie zapomnieć o rzeczywistych okresach i traktować wartości R właśnie jako okresy próbkowania.

    Używając różnych wartości R jako interwału czy też skoku przy wybieraniu kolejnych próbek z powtarzającej się sekwencji poly4 można bardzo łatwo przekonać się jak wyglądają generowane sekwencje wyjściowe dla tych R. Można je też zobaczyć w podsumowującej tabeli 8 na końcu tego rozdziału.

    Poniższy rysunek przedstawia przebieg próbkowania dla przykładowej wartości R = 4.

    Rys. 2. Przebieg próbkowania dla R = 4 (skok 4)

    W przypadku kategorii C4 skok ma długość 0 co oznacza, że dla dowolnej częstotliwości należącej do tej kategorii w kolejnych momentach próbkowany jest zawsze ten sam element sekwencji poly4 skutkując sygnałem stałym czyli ciszą na wyjściu.

    Dla wartości R należących do kategorii C1 wygenerowana sekwencja zawsze zawiera 15 elementów w okresie i jest dokładnie taka jak sekwencja poly4 bądź zawiera elementy sekwencji poly4 w odwróconej kolejności. Zauważmy, że sekwencja odwrócona pojawia się dla R równego 7, 11, 13 lub 14. Te wartości można traktować jako skoki o wartości ujemnej. Wtedy długość skoku to R – 15 czyli odpowiednio -8, -4, -2 i -1. Zawartość sekwencji wyjściowej nie zależy od tego, od którego elementu sekwencji poly4 rozpoczęło się próbkowanie. Zależy od tego tylko faza sekwencji wyjściowej ale nie ma to większego znaczenia. To, czy sekwencja wyjściowa zawiera elementy w kolejności zgodnej z sekwencją poly4 czy w odwróconej, nie wpływa na brzmienie (ten sam zbiór harmonicznych). Fala dźwiękowa generowana dla R należących do kategorii C1 jest więc stabilna. Do kategorii C1 należą tzw. basy E oraz basy 16-bit. Ponieważ na okres generowanej fali składa się 15 próbek, to częstotliwość głównej harmonicznej jest 15 razy niższa od zadanej częstotliwości generacji próbek.
    W przypadku wartości R należących do kategorii C3 (czyli 5 i 10) wygenerowana sekwencja zawsze zawiera 3 elementy w okresie. W czterech na pięć przypadków okres zawiera jedną próbkę o wartości 1 i dwie próbki o wartości 0. Jest to więc fala prostokątna o wypełnieniu 33%. W piątym przypadku okres zawiera trzy próbki o wartości 1 co daje sygnał stały czyli ciszę. To, z którym przypadkiem mamy do czynienia, zależy od momentu w którym rozpoczęło się próbkowanie. Wartość R równą 10 można traktować jako skok ujemny o długości -5. Nie ma jednak znaczenia, czy próbkujemy ze skokiem 5 czy -5. Sekwencja wyjściowa nie zależy od znaku wartości skoku ze względu na symetrię ułożenia zawartych w niej elementów.

    Dla wartości R należących do kategorii C2 (czyli 3, 6, 9 i 12) wygenerowana sekwencja zawiera zawsze 5 elementów w okresie. Możliwe są do uzyskania trzy różne sekwencje wyjściowe dające trzy różne brzmienia (ang. timbre). Oznaczyłem je przez T0, T1 i T2. Są one przedstawione na rysunku poniżej.

    Rys. 3. Trzy sekwencje wyjściowe (brzmienia) możliwe do uzyskania w kategorii C2

    Pierwsza sekwencja daje falę prostokątną o wypełnieniu 60%, druga – o wypełnieniu 20%. O trzeciej sekwencji można powiedzieć, że jako fala dźwiękowa zawiera znaczącą harmoniczną o częstotliwości dwukrotnie większej od podstawowej. Ponieważ na okres generowanej fali składa się 5 próbek, to częstotliwość podstawowej harmonicznej jest 5 razy niższa od zadanej częstotliwości generacji próbek. Dla porównania, częstotliwość sygnału o zniekształceniu A (czysty ton, fala prostokątna o wypełnieniu 50%) jest dwukrotnie mniejsza od zadanej częstotliwości generacji próbek. To oznacza, że częstotliwość sygnału w kategorii C2 jest 2,5 raza niższa od częstotliwości czystych tonów przy takim samym zegarze bazowym oraz takich samych wartościach podzielników w rejestrach AUDFx. Dwukrotna różnica częstotliwości oznacza różnicę o jedną oktawę na skali muzycznej.

    Dostępność trzech różnych brzmień w kategorii C2 oznacza właśnie niestabilność brzmienia. Do kategorii tej należą tzw. basy C. To, które z trzech brzmień jest generowane, zależy zarówno od R jak i od momentu w którym rozpoczęło się próbkowanie. Zależność ta będzie szczegółowo omówniona w dalszej części artykułu.
    Warto jeszcze zwrócić uwagę, że wartość R równą 9 i 12 można traktować jako skok ujemny o długości odpowiednio -6 i -3. W kategorii C2 podobnie jak w C3 nie ma naczenia, czy próbkujemy ze skokiem dodatnim czy ujemnym. Dla każdego z trzech brzmień sekwencja wyjściowa jest niezależna od znaku wartości skoku co wynika z symetrii ułożenia zawartych w niej elementów.

    Rys. 4. Sygnał o brzmieniu T0 w pięciu zgrubnych przesunięciach (opóźnieniach) fazowych

    Podsumowanie informacji o kategoriach brzmień przedstawione jest w tabeli ponizej.

    Kat.

    Skok

    Wyjście/brzmienie

    I, # ścieżek próbkow.

    # próbek w okresie

    Brzmienie stabilne

    C1

    R∊{1, 2, 4, 8}

    dodatni

    (1, 2, 4, 8)

    1

    15

    Tak
    (basy E, basy 16bit)

    R∊{7, 11, 13, 14}

    ujemny

    (-8, -4, -2, -1)

    C2

    R∊{3, 6}

    dodatni
    (3, 6)

    T0:

    T1:

    T2:

    3

    5

    Nie. Zależy od ścieżki i R. (basy C)

    R∊{9, 12}

    ujemny

    (-6, -3)

    C3

    R = 5

    dodatni (5)

    (4 ścieżki)

    lub cisza (1 ścieżka)

    5

    3

    Nie. Zależy od ścieżki.

    R = 10

    ujemny (-5)

    C4

    R = 0

    brak (0)

    cisza

    15

    1

    Tak

    Tab. 8. Zestawienie cech czterech kategorii brzmień zniekształcenia C

    Powyższa tabela zawiera dodatkowo informację o parametrze I tożsamym z liczbą tzw. ścieżek próbkowania. Terminy te będą wyjaśnione w dalszej części artykułu.
    Z uwagi na znaczne różnice między sygnałami generowanymi w poszczególnych kategoriach zniekształcenia C uzasadnione wydaje się posługiwanie terminem "zniekształcenie" w odniesieniu do konkretnej kategorii czyli mówienie np. o "zniekształceniu C1" zamiast o "kategorii C1 zniekształcenia C".

    Ostatnia tabela w tej części przedstawia wzory, które pozwalają wyznaczyć R na podstawie wartości nastaw w rejestrach AUDFx i wybranego zegara taktującego. Jest ona złożeniem tabel 2 i 6 oraz wzoru R = p MOD 15.

    Zegar bazowy

    Długość słowa nastawy

    Wzór na R

    div28

    8 bitów

    R = (AUDFx + 1) * 28 MOD 15

    div28

    16 bitów (dwa kanały)

    R = (AUDFxy + 1) * 28 MOD 15

    div114

    8 bitów

    R = (AUDFx + 1) * 114 MOD 15

    div114

    16 bitów (dwa kanały)

    R = (AUDFxy + 1) * 114 MOD 15

    phi2

    8 bitów

    R = (AUDFx + 4)  MOD 15

    phi2

    16 bitów (dwa kanały)

    R = (AUDFxy + 7)  MOD 15

    Tab. 9. Zależność R od zegara i wartości nastaw w rejestrach AUDFx.

    Zależność brzmienia zniekształcenia C od momentu rozpoczęcia próbkowania

    Moment rozpoczęcia próbkowania to dokładniej mówiąc moment rozpoczęcia próbkowania z nową częstotliwością czyli moment przeładowania licznika podzielnika częstotliwości (timera) danego kanału nową wartością z odpowiadającego rejestru AUDFx i jednocześnie moment pobrania pierwszej próbki w procesie próbkowania odbywającym się z nową częstotliwością. Może to być również moment pierwszego próbkowania po zmianie częstotliwości zegara bazowego. Moment rozpoczęcia próbkowania można wyrazić jako numer elementu sekwencji poly4 (E0 – E14), od którego zaczęło się próbkowanie z daną częstotliwością. W ten sposób redukujemy całą nieskończoną dziedzinę czasu do piętnastu wirtualnych momentów ale jest to redukcja jak najbardziej uprawniona. Kształt sygnału powstały w wyniku próbkowania rozpoczętego od konkretnego elementu poly4 jest zawsze taki sam niezależnie od tego w którym punkcie rzeczywistej osi czasu ten element się pojawił. Umiejscowienie na rzeczywistej osi czasu ma oczywiście wpływ na przesunięcie (opóźnienie) fazowe sygnału ale to przesunięcie możemy teraz zaniedbać. Rozważmy więc 15 możliwości związanych z możliwymi punktami rozpoczęcia próbkowania we wszystkich czterech kategoriach brzmień.

    W przypadku kategorii C1 sygnał wyjściowy może znaleźć się w jednym z piętnastu możliwych przesunięć fazowych. Chodzi tu o przesunięcia zgrubne tzn. o cały element. Jak pamiętamy, sygnał wyjściowy ma 15 elementów w okresie.

    W przypadku kategorii C4 jeden z piętnastu elementów sekwencji poly4 będzie stale podawany na wyjście.

    W przypadku kategorii C2 sygnał wyjściowy ma tylko pięć elementów w okresie więc możliwych jest tylko pięć zgrubnych przesunięć fazowych. W tej kategorii próbkowanie może odbywać się po trzech różnych ścieżkach (torach). Pojęcie ścieżki próbkowania zostanie wyjaśnione poniżej. Trzy ścieżki próbkowania razy pięć przesunięć fazowych daje piętnaście kombinacji.

    W przypadku kategorii C3 próbkowanie może odbywać się po pięciu różnych ścieżkach (torach) a sygnał wyjściowy ma trzy elementy w okresie przez co możliwe są trzy zgrubne przesunięcia fazowe. Pięć ścieżek próbkowania razy trzy przesunięcia fazowe daje piętnaście kombinacji.

    Rys. 5. Trzy ścieżki próbkowania w kategorii C2

    Ścieżki próbkowania stanowią rozłączne podzbiory elementów sekwencji poly4. Definicja ścieżki próbkowania jest następująca:

    Ścieżka próbkowania (ang. sampling track) jest podzbiorem elementów sekwencji próbkowanej (poly4), które są osiągalne w procesie próbkowania dla zadanej częstotliwości próbkowania lub inaczej dla zadanej wartości R.

    W sygnale wyjściowym znajdują się tylko takie elementy sekwencji poly4, które należą do bieżącej ścieżki próbkowania. W przypadku kategorii C1 mamy jedną ścieżkę 15-elementową, w kategorii C2 – 3 ścieżki 5-elementowe, w C3 – 5 ścieżek 3-elementowych i w C4 – 15 ścieżek jednoelementowych.

    W przypadku kategorii C2 i C3 moment rozpoczęcia próbkowania decyduje o tym, po której ścieżce będzie przebiegał process próbkowania oraz o fazie zgrubnej sygnału. W przypadku C1 moment ten decyduje tylko o fazie sygnału (15 przesunięć) a w przypadku C4 tylko o ścieżce próbkowania (15 ścieżek).

    Faza sygnału nie ma znaczenia o ile rozpatrujemy pojedynczy kanał dźwiękowy ale oczywiście inaczej jest w przypadku, gdy interesuje nas sumaryczny sygnał z dwóch lub więcej kanałów grających z tą samą częstotliwością.

    W poniższych tabelach przedstawiona jest przynależność elementów sekwencji poly4 do poszczególnych ścieżek próbkowania w kategoriach C2 i C3. Jednocześnie jest to zależność ścieżki od momentu rozpoczęcia próbkowania.

    Numer ścieżki próbkowania

    Nazwa

    Przynależne elementy sekwencji poly4

    0

    ST0

    E0, E3, E6, E9, E12

    1

    ST1

    E1, E4, E7, E10, E13

    2

    ST2

    E2, E5, E8, E11, E14

    Tab. 10. Zestawienie ścieżek próbkowania w kategorii C2

    Numer ścieżki próbkowania

    Przynależne elementy sekwencji poly4

    Wyjście

    0

    E0, E5, E10

    1

    E1, E6, E11

    2

    E2, E7, E12

    3

    E3, E8, E13

    4

    E4, E9, E14

    Tab. 11. Zestawienie ścieżek próbkowania w kategorii C3

    Tabela 11 zawiera kolumnę opisującą kształt sygnału dźwiękowego wytwarzanego na wyjściu w kategorii C3. Dla pierwszych czterech ścieżek jest to sygnał o wypełnieniu 33%. W przypadku piątej ścieżki jest to cisza. W tabeli 10 nie ma kolumny opisującej kształt sygnału wyjściowego ponieważ w kategorii C2 kształt zależy nie tylko od ścieżki próbkowania ale również od R. Ścieżki próbkowania istniejące w kategorii C2 oznaczyłem przez ST0, ST1 i ST2. Ich nazwy będą wykorzystywane w kolejnych tabelach. Trzy brzmienia T0, T1 i T2 dostępne w kategorii C2 były już przedstawione wcześniej. Zależność brzmienia w kategorii C2 od R i wybranej ścieżki próbkowania przedstawia poniższa tabela.

    R

    Skok

    ST0

    ST1

    ST2

    3

    3

    T0

    T1

    T2

    6

    6

    T2

    T1

    T0

    9

    -6

    T2

    T1

    T0

    12

    -3

    T0

    T1

    T2

    Tab. 12. Zależność brzmienia kategorii C2 od R i ścieżki próbkowania

    Ścieżka ST1 jako jedyna zawsze daje takie samo brzmienie, niezależnie od częstotliwości. Jest to więc ścieżka szczególna. Nazwałem ją "złotą". Pomiędzy pozostałymi dwoma ścieżkami jest zauważalna symetria. Na obu występują brzmienia T0 i T2 a ich zależności od R są dokładnie odwrotne.

    Następna tabela przedstawia zależność sekwencji wyjściowej w kategorii C2 od R i momentu rozpoczęcia próbkowania. Uwzględnia wszystkie kształty sygnału wyjściowego oraz wszystkie możliwe zgrubne przesunięcia fazowe. Moment rozpoczęcia próbkowania wyrażony jest oznaczeniem pierwszego próbkowanego elementu sekwencji poly4 (E0 - E14). W komórkach tabeli zawarte są wzorce bitowe generowanych sekwencji, oznaczenia barwy brzmienia T0-T2 oraz zgrubne przesunięcia (opóźnienia) fazowe D0-D4. Przesunięcie D0 należy rozumieć jako brak przesunięcia. Kolumna "Ścieżka" przypisuje ścieżkę próbkowania do momentu rozpoczęcia próbkowania.

    Początek próbkow.

    R = 3

    R = 6

    R = 9

    R = 12

    Ścieżka

    E0

    00111 / T0 / D0

    01101 / T2 / D0

    01011 / T2 / D2

    01110 / T0 / D4

    ST0

    E1

    01000 / T1 / D0

    00010 / T1 / D2

    00100 / T1 / D1

    00001 / T1 / D3

    ST1

    E2

    01101 / T2 / D0

    01110 / T0 / D4

    00111 / T0 / D0

    01011 / T2 / D2

    ST2

    E3

    01110 / T0 / D4

    01011 / T2 / D2

    01101 / T2 / D0

    00111 / T0 / D0

    ST0

    E4

    10000 / T1 / D4

    10000 / T1 / D4

    10000 / T1 / D4

    10000 / T1 / D4

    ST1

    E5

    11010 / T2 / D4

    10011 / T0 / D1

    11100 / T0 / D3

    10101 / T2 / D3

    ST2

    E6

    11100 / T0 / D3

    11010 / T2 / D4

    10101 / T2 / D3

    10011 / T0 / D1

    ST0

    E7

    01111 / T1 / D3

    00100 / T1 / D1

    00010 / T1 / D2

    01000 / T1 / D0

    ST1

    E8

    10101 / T2 / D3

    11100 / T0 / D3

    10011 / T0 / D1

    11010 / T2 / D4

    ST2

    E9

    11001 / T0 / D2

    10110 / T2 / D1

    10110 / T2 / D1

    11001 / T0 / D2

    ST0

    E10

    00010 / T1 / D2

    00001 / T1 / D3

    01000 / T1 / D0

    00100 / T1 / D1

    ST1

    E11

    01011 / T2 / D2

    00111 / T0 / D0

    01110 / T0 / D4

    01101 / T2 / D0

    ST2

    E12

    10011 / T0 / D1

    10101 / T2 / D3

    11010 / T2 / D4

    11100 / T0 / D3

    ST0

    E13

    00100 / T1 / D1

    01000 / T1 / D0

    00001 / T1 / D3

    00010 / T1 / D2

    ST1

    E14

    10110 / T2 / D1

    11001 / T0 / D2

    11001 / T0 / D2

    10110 / T2 / D1

    ST2

    Tab. 13. Zależność sekwencji wyjściowej w kategorii C2 od R i momentu rozpoczęcia próbkowania

    Zależność brzmienia zniekształcenia C od zegara

    Opisane dotąd informacje dotyczące zależności brzmienia zniekształcenia C dotyczą sytuacji, gdy używany jest zegar bazowy phi2 (1.77 MHz) lub div28 (64 kHz). W przypadku użycia zegara div114 (15.6 kHz) dochodzą dwa ograniczenia. Są one wprost związane z faktem, że liczba 114 jest podzielna przez 3 czyli jest wielokrotnością liczby 3. Z tego wynika, że każdy bezwzględny podzielnik częstotliwości, który w tym wypadku jest iloczynem 114 i wartości wynikającej z nastawy w rejestrze AUDFx, jest również wielokrotnością liczby 3. Z tego faktu z kolei oraz z reguł podanych w tabelach 5 i 6 wynika, że przy użyciu zegara div114 dostępne są tylko kategorie brzmienia C2 i C4 czyli basy C i cisza. Jest to pierwsze ograniczenie. Drugie dotyczy ścieżek próbkowania. Okazuje się, że są one przypisane na stałe do konkretnych kanałów. Zasada, która to powoduje, będzie opisana później. Można jednak zauważyć, że dostępność tylko i wyłącznie podzielników będących wielokrotnością liczby 3 powoduje ograniczenie rozdzielczości próbkowania sekwencji poly4 (której długość jest również wielokrotnością 3) do co trzeciego elementu i brak możliwości przesunięcia o inną liczbę elementów niż wielokrotność 3. Proponuję teraz przyjrzeć się jeszcze raz rysunkowi 5 i trzem ścieżkom próbkowania dostępnym w kategorii C2.

    Podobnie, jak w przypadku pozostałych zegarów, wybrana ścieżka zależy od momentu rozpoczęcia próbkowania, z tym, że w przypadku div114 ten moment to moment resetu układu POKEY. Każdy kanał po resecie wpada na swoją ścieżkę i już na niej pozostaje aż do następnego resetu. Po każdym resecie dany kanał wpada na tą samą ścieżkę, o ile reset przeprowadzony jest prawidłowo, czyli trwa odpowiednio długo. To od razu sugeruje, że teoretycznie jest możliwa zmiana przypisań scieżek próbkowania do kanałów, jeżeli reset będzie zbyt krótki. Nie sprawdzałem jednak w praktyce tej możliwości.

    Układ POKEY jest skonstruowany w ten sposób, że każdy z kanałów próbkuje sekwencję poly4 z różnym opóźnieniem a różnice opóźnień między dwoma sąsiednimi kanałami wynoszą 1 cykl phi2. To powoduje, że przy użyciu zegara div114 kanały trafiają na różne ścieżki próbkowania.

    Stałe przypisanie ścieżek próbkowania do kanałów przy użyciu zegara div114 jest przedstawione w poniższej tabeli.

    Kanał

    Ścieżka próbkowania (STx)

    1

    ST0

    2

    ST2

    3

    ST1

    4

    ST0

    Tab. 14. Stałe przypisanie ścieżki próbkowania do kanału przy użyciu zegara div114

    Z faktu, że przy użyciu zegara div114 ścieżka próbkowania nie może się zmieniać, wynika stabilność, czy też niezależność uzyskiwanego brzmienia od chwili rozpoczęcia próbkowania co stanowi zaletę. Brzmienie zależy tylko od R czyli od częstotliwości, zgodnie z tabelą 12. Kanały 1, 2 i 4 mogą generować dwa brzmienia – T0 i T2. Kanał 3, który używa "złotej" ścieżki ST1, generuje brzmienie T1 niezależnie od częstotliwości i jest "złotym" kanałem.

    W kategorii C4 każdy z kanałów może podać na wyjście jeden z pięciu tylko elementów należących do przypisanej do niego ścieżki próbkowania.

    Formalizmy dotyczące pojęcia ścieżki próbkowania

    Przeczytanie tego rozdziału nie jest konieczne do zrozumienia zagadnienia generacji dźwięku o zniekształceniu C. Może być jednak przydatne przy analizie innych rodzajów zniekształceń dostępnych w układzie POKEY.

    Jak podawałem wcześniej, ścieżka próbkowania jest podzbiorem elementów sekwencji próbkowanej (poly4), które są osiągalne w procesie próbkowania dla zadanej częstotliwości próbkowania lub inaczej dla zadanej wartości R.

    Podzbiór ten zawiera co I-ty element sekwencji próbkowanej, gdzie I jest najmniejszym możliwym interwałem próbkowania czyli odległością między elementami próbkowanej sekwencji. I jest równe największemu wspólnemu podzielnikowi (GCD – greatest common divisor) długości sekwencji próbkowanej (w ty przypadku 15) i różnicy "długość sekwencji - R" (tu 15 - R):

    I = GCD(15, 15 - R)

    Dla danego R istnieje I ścieżek próbkowania, z których każda zawiera 15/I elementów. Stosując interwał będący wielokrotnością I będziemy poruszać się po tej samej ścieżce próbkowania co w przypadku stosowania pojedynczego interwału I.

    Tak więc w przypadku kategorii C1 liczba I wynosi 1, ponieważ wszystkie wartości R są względnie pierwsze z długością sekwencji poly4 (15). To oznacza, że jest tylko jedna ścieżka próbkowania do której należą wszystkie elementy sekwencji poly4. Jak wspominałem, sekwencja wyjściowa ma 15 elementów w okresie i może być generowana w piętnastu zgrubnych (skokowych) przesunięciach fazowych.

    Dla kategorii C3 czyli dla R równego 5 lub 10 liczba I wynosi 5. Oznacza to, że co piąty element sekwencji poly4 należy do jednej ścieżki próbkowania. Tak więc każda ścieżka ma 3 elementy a ścieżek jest 5. Dla każdej z pięciu ścieżek sekwencja wyjściowa ma 3 elementy w okresie i może być generowana w trzech zgrubnych przesunięciach fazowych.

    W przypadku kategorii C4 liczba I wynosi 15. Mamy więc 15 jednoelementowych ścieżek. Próbkowany jest zawsze jeden i ten sam element sekwencji poly4 co daje sygnał stały. W zależności od tego, która ścieżka jest wybrana (który element jest próbkowany), poziom sygnału może mieć wartość 0 lub 1.

    Wartości R należące do kategorii C2 to 3, 6, 9 i 12 a liczba I równa się dla nich 3. To oznacza, że w kategorii C2 są 3 ścieżki próbkowania a każda z nich zawiera 5 elementów.

    Stabilne zniekształcenie C2

    Wiemy już, co należy zrobić aby uzyskać stabilne basy C czyli mówiąc ogólniej stabilne zniekształcenie C2. Należy sprawić, by próbkowanie sygnału poly4 przebiegało po ścieżce ST1. Ścieżka ta zapewnia jedno spójne brzmienie T1 niezależnie od częstotliwości. Wiemy też, że aby to uzyskać w przypadku używania zegara div114 należy po prostu użyć kanału 3. Kanał ten i tylko ten próbkuje sygnał poly4 zawsze po ścieżce ST1. Nie wiemy natomiast jak sprawić, by proces próbkowania przebiegał po ścieżce ST1 w przypadku używania pozostałych zegarów.

    Synchronizacja czyli wybór ścieżki próbkowania i zgrubnego przesunięcia fazowego
    W przypadku używania zagarów phi2 i div28 nie ma możliwości sprawdzenia, po której ścieżce odbywa się próbkowanie w danym kanale w danym momencie. Układ POKEY nie daje możliwości odpytania stanu swoich liczników (z wyjątkiem fragmentu licznika poly17 przez rejestr RANDOM). Daje natomiast możliwość ustawiania liczników w znany stan początkowy czyli wykonania programowego "resetu". Istnieją dwie metody resetowania liczników a każda z nich dotyczy innej grupy rejestrów. Pierwsza metoda zeruje wszystkie liczniki wielomianowe czyli liczniki odpowiedzialne za generację zniekształceń i szumu poly4, poly5 i poly17 oraz liczniki stosowane do generacji sygnałów zegarowych div28 i div114. Uzyskuje się to poprzez wyzerowanie dwóch najmniej znaczących bitów rejestru SKCTL na okres przynajmniej 17 cykli zegara phi2. Wymienione liczniki są w istocie rejestrami przesuwnymi a czas ich zerowania zależy od ilości przerzutników (bitów) składających się na dany licznik. Zawsze zerowane są wszystkie liczniki więc należy poczekać na pełne wyzerowanie najdłuższego. Druga metoda resetowania liczników dotyczy timerów związanych z kanałami dźwiękowymi i polega na ustawieniu wszystkich timerów na wartości ustawione w odpowiednich rejestrach AUDFx. Uzyskuje się to przez zapis dowolnej wartości do rejestru STIMER. Timery kanałów dźwiękowych to liczniki liczące wstecz, odliczające wartości będące zadanymi podzielnikami częstotliwości (patrz: tabela 2 – podzielnik względny div).
    Używając obu tych możliwości można sprowadzić wszystkie liczniki POKEY-a do znanego stanu. Mając taką wiedzę o stanie początkowym można precyzyjnie wymusić moment pierwszego próbkowania sekwencji poly4 tak by trafić na wybrany jej element Ex i w ten sposób wybrać ścieżkę próbkowania oraz zgrubne przesunięcie fazowe generowanego sygnału. W przypadku używania zegara div114 ścieżki próbkowania są na stałe przypisane do kanałów ale wciąż można wybierać zgrubne przesunięcie fazowe. Podobnie w kategorii C1 przy zegarach div28 lub phi2.

    Aby rozpocząć nowy proces próbkowania (z nową częstotliwością) od wybranego elementu sekwencji poly4 niezbędne jest zsynchronizowanie trzech liczników. Są to:

    1. licznik wielomianowy poly4,
    2. licznik wielomianowy odliczający wartość podzielnika stałego dla zegara kanału div28 lub div114 (nie dotyczy zegara phi2),
    3. timer wybranego kanału.

    Synchronizacja polega na tym, aby pierwsze próbkowanie wynikające ze stanu zegara kanału i timera kanału zdarzyło się w tym czasie, kiedy na wejściu kanału pojawi się wybrany element sekwencji poly4.

    Istnieją przynajmniej dwie metody synchronizacji liczników. Różnią się one od siebie tylko sposobem ustawienia w znany stan początkowy timera kanału. Zerowanie liczników wielomianowych odbywa się przy każdej z metod. Niezależnie od wybranej metody synchronizacja może dotyczyć jednego lub więcej kanałów dźwiękowych. Jeżeli dwa lub więcej kanałów podlega synchronizacji liczników i kanały te używają takiej samej częstotliwości generacji dźwięku to mówimy o synchronizacji kanałów. Tylko w takim przypadku znaczenie ma przesunięcie fazowe generowanych sygnałów.

    Przydatnym pojęciem jest selektor punktu synchronizacji czyli inaczej mówiąc selektor elementu Ex sekwencji poly4, który w wyniku synchronizacji zostanie spróbkowany jako pierwszy. Jest dokładnie 15 różnych selektorów odpowiadających piętnastu elementom Ex sekwencji poly4. Selektor jest wyrażany za pomocą wartości wpisywanych do rejestrów AUDFx. Wartość selektora danego elementu Ex jest zależna od zastosowanej metody synchronizacji oraz użytego zegara kanału. Wartość danego selektora oznacza wartość początkową jaką należy wpisać do rejestru AUDFx aby przy danej metodzie synchronizacji i zegarze próbkowanie rozpoczęło się od wskazanego elementu Ex sekwencji poly4.

    Dla dobrego wyjaśnienia metod synchronizacji liczników pomocna jest poniższa tabela. Ukazuje ona niektóre aspekty działania POKEY-a po zakończonym zerowaniu liczników wielomianowych i przy założeniu, że do generacji dźwięku używamy zegara div28. Pierwszy wiersz tabeli obrazuje ostatni cykl stanu zerowania liczników wielomianowych czyli ostatni cykl, w którym najmłodsze dwa bity rejestru SKCTL maja wartość '00'. Jednocześnie jest to ostatni cykl rozkazu STA SKCTL, który wpisuje do SKCTL wartość akumulatora równą 3 (najmłodsze bity równe '11').

    W kolumnie "Efektywny moment próbkowania oparty na zegarze div28" zaznaczone są pierwsze trzy momenty, w których teoretycznie może nastąpić próbkowanie. Następują one w cyklach 25, 53 i 81, zgodnie z taktem zegara div28 co 28 cykli phi2. Moment pierwszego próbkowania w cyklu 25 po zerowaniu liczników wynika z wewnętrznej budowy układu POKEY. Wartości selektorów czyli początkowe wartości AUDFx podane w nawiasach (o ile zostaną załadowane do timerów przed cyklem numer 25) spowodują rzeczywiste próbkowanie w tych momentach. Podane wartości selektorów są właściwe dla pierwszej metody synchronizacji liczników opisanej w następnym rozdziale. Ostatnie cztery kolumny ukazują numery elementów sekwencji poly4 "widzianych" przez poszczególne kanały w kolejnych cyklach phi2.

    Cykl zegara phi2

    Reset (init)

    Efektywny moment próbkowania oparty na zegarze div28

    Element Ex sekwencji poly4 "widziany" przez kanały

    Kanał 1

    Kanał 2

    Kanał 3

    Kanał 4

    -1

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    .

    .

    80

    81

    82

    83

    84

    1

    0

    0

    0

    .

    .

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    1 (selektor = 0)

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    2 (selektor = 1)

     

    .

    .

     

    3 (selektor = 2)

    0

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    .

    .

    5

    6

    7

    8

    9

    0

    0

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    .

    .

    4

    5

    6

    7

    8

    0

    0

    0

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    .

    .

    3

    4

    5

    6

    7

    0

    0

    0

    0

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    0

    1

    2

    3

    4

    5

    6

    .

    .

    2

    3

    4

    5

    6

    Tab. 15. Działanie POKEY-a po zerowaniu liczników wielomianowych

    Pierwsza metoda synchronizacji liczników

    Pierwsza metoda synchronizacji jest prostsza i trwa znacznie krócej, niż druga. Do ustawienia timerów w znany stan początkowy używa zapisu do rejestru STIMER. Jest to jej pewna wada, ponieważ wszystkie kanały, których synchronizacja nie dotyczy, emitują w takiej chwili słyszalne kliknięcie. W trakcie odtwarzania muzyki nie zawsze jest to akceptowalne. Nie da się uniknąć tego efektu przez wyciszenie niesynchronizowanych kanałów na czas synchronizacji, gdyż wynika on z losowej zmiany fazy generowanego sygnału. Efekt nie jest zawsze słyszalny, ponieważ losowa zmiana fazy może być niewielka.

    Zaprezentowany poniżej kod synchronizuje metodą pierwszą kanał 1 z elementem E6 sekwencji poly4 przy założeniu, że używany jest zegar div28. Przełącza POKEY w stan zerowania liczników wielomianowych, wpisuje do AUDF1 wartość 2 (zadeklarowaną jako stała sE6Ch1), czyli selektor, który pozwoli na synchronizację kanału 1 dokładnie z elementem E6 sekwencji poly4 oraz ładuje timery wszystkich kanałów wartościami z rejestrów AUDFx poprzez zapis do rejestrru STIMER. Timer kanału 1 zostaje ustawiony na wartość 2.

    sE10Ch1 = 0  ; it's safer to use selector values increased by 15
    sE8Ch1 = 1
    sE6Ch1 = 2
    sE6Ch3 = 1
     
          ; reset POKEY polynomial counters
          lda #0
          sta SKCTL
          ; the period of resetting POKEY (SKCTL = 0) should last for
          ; at least 17 cycles to clear the longest 17-bit polycounter
     
          ; set AUDF1 register with selector value needed to reach desired E6
          ; poly4 element by channel 1
          lda #sE6Ch1   ; 2 cycles
          sta AUDF1     ; 4 cycles
          nop           ; 2 cycles
          sta STIMER    ; 4 cycles
     
          ; finish resetting
          lda #3        ; 2 cycles
          sta SKCTL     ; 4 cycles
     
          ; set AUDF1 register with desired frequency divisor
          lda tmpAudF1
          sta AUDF1
          ; setting AUDF1 register with desired frequency divisor must complete
          ; before next sampling based on selector (next loading a timer)!

    Następnie przełącza POKEY w stan normalnej pracy. W tym momencie liczniki wielomianowe zaczynają normalnie pracować co powoduje między innymi, że zegar div28 uderza w cyklach 25, 53, 81 itd. co 28 cykli. Kod wpisuje do AUDF1 pożądaną wartość podzielnika częstotliwości. Kolejne uderzenia zegara div28 zmniejszają wartość timera kanału 1 o 1. Pierwsze uderzenie zegara div28 w cyklu 25 zmniejsza timer kanału1 z 2 na 1. Drugie uderzenie zmniejsza ten timer na 0 w cyklu 53. Trzecie uderzenie w cyklu 81 powoduje próbkowanie sygnału poly4 i przesłanie jego bieżącej wartości (E6) na wyjście kanału 1 oraz załadowanie timera zawartością rejestru AUDF1, który zawiera pożądaną wartość podzielnika częstotliwości. Oprócz selektora sE6Ch1 w kodzie mamy jeszcze trzy inne. Dwa pozwalają zsynchronizować kanał 1 z elementami E10 i E8. Trzeci – kanał 3 z elementm E6. Warto odnieść wartości tych selektorów do tabeli 15 w momentach próbkowania aby zrozumieć zasadę ich tworzenia.

    Należy zwrócić uwagę, że wpisanie pożądanej (ostatecznej) wartości do AUDF1 musi nastąpić przed pierwszym próbkowaniem, które odbywa się w cyklu 81. W podanym przykładzie nie ma z tym problemu, ale można zauważyć, że czas do pierwszego próbkowania mocno zależy od tego, który kanał i z którym elementem poly4 synchronizujemy. Ponadto zasada obowiązuje także wtedy gdy synchronizujemy więcej niż jeden kanał i musimy dokonać znacznie więcej ustawień. Ponadto do czasu ustawiania rejestrów AUDFx należy doliczyć czas zabrany przez cykle odświeżania pamięci i cykle DMA. Czas na ustawianie rejestrów AUDFx na ostateczne wartości jest krytyczny dla poprawnego działania metody. Liczy się on od momentu przełączenia POKEY-a na tryb normalnej pracy do czasu pierwszego próbkowania.

    W rzeczywistości nie ma z tym żadnego problemu, ale trzeba mieć świadomość takiego ograniczenia. Problem mógłby się pojawić przy niskich wartościach selektorów wpisywanych do AUDFx skutkujących pierwszym próbkowaniem już w pierwszych cyklach div28 (25, 53). Problemu można się pozbyć na dwa sposoby. Pierwszy sposób to zmienić kod tak, aby przełączenie POKEY-a na tryb normalnej pracy miało miejsce dopiero po ustawieniu ostatecznych wartości w AUDFx. To całkowicie rozwiązuje problem ale jest możliwe tylko w pierwszej metodzie synchronizacji. Druga metoda (opisana poniżej) też ma ten problem ale podane właśnie rozwiązanie nie jest w niej możliwe do zastosowania. Drugie rozwiązanie to zwiększenie niskich wartości selektorów o 15. Takie zwiększone wartości powodują synchronizację z tymi samymi elementami Ex, tyle że o 15 * 28 = 420 cykli phi2 później. Takie rozwiązanie stosuje się również do drugiej metody synchronizacji. Ogólna zasada mówi, że w przypadku używania zegara div28 lub phi2 zwiększenie wartości selektora o 15 (lub wielokrotność) zachowuje wskazywany element Ex. W przypadku używania zegara div114 zwiększenie selektora o wielokrotność 5 zachowuje wskazywany element Ex. To z uwagi na fakt, że tylko 5 z 15 elementów Ex jest dostępne dla każdego z kanałów (1 z 3 ścieżek próbkowania w kategorii C2 – patrz: tabela 10 i 14).

    Dodatkowego wyjaśnienia wymaga jeszcze sygnał zegara div28. W rzeczywistości pierwsze uderzenie tego zegara po przełączeniu POKEY-a na tryb normalnej pracy ma miejsce w cyklu numer 19. Niemniej to uderzenie skutkuje próbkowaniem sygnału poly4 dopiero 6 cykli później czyli w cyklu 25. Opóźnienie dotyczy oczywiście również kolejnych uderzeń. Takie opóźnienie wynika z wewnętrznej konstrukcji układu POKEY. Sygnał div28 musi przedostać się przez 6 przerzutników aby wyzwolić próbkowanie poly4. Podobnie jest w przypadku zegara div114. Pierwsze uderzenie pojawia się na jego wyjściu w cyklu 78 a skutkuje próbkowaniem poly4 w cyklu 84.

    Druga metoda synchronizacji liczników

    Druga metoda synchronizacji jest nieco bardziej skomplikowana i ma dłuższy czas wykonania. Zaletą jej jest to, że nigdy nie wykonuje zapisu do rejestru STIMER dzięki czemu nie ma problemu słyszalnego kliknięcia. Ustawianie timerów w znany stan początkowy odbywa się w następujący sposób. Do AUDFx wpisujemy 0 a następnie oczekujemy przez taką ilość czasu, która gwarantuje załadowanie timera nową wartością 0. Zakładamy najbardziej niekorzystny przypadek czyli taki, że timer jest początkowo ustawiony na N = 255. To oznacza, że w przypadku użycia zegara div28 trzeba odczekać przynajmniej (N + 1) * 28 = 256 * 28 = 7168 cykli. Wyrażenie N + 1 to wzór na podzielnik przy użyciu zegara div28 (patrz: tabela 2). Ten czas można znacznie skrócić, jeżeli synchronizowany jest kanał 1 lub 3. Można wtedy przełączyć zegar na phi2, odczekać N + 4 = 259 cykli, następnie przełączyć na div28 i odczekać jeszcze 4 * 28 = 112 cykli (po przełączeniu zegara timer może liczyć jeszcze przez max 4 dodatkowe cykle – to wynika ze wzoru na podzielnik dla phi2: N + 4). To daje w sumie tylko 371 cykli oczekiwania. Po upływie czasu oczekiwania do timera synchronizowanego kanału mamy wpisane 0, co gwarantuje, że nowa wartość wpisana do AUDFx zostanie załadowana do timera przy najbliższym uderzeniu zegara div28. Dodam jeszcze, że na czas przełączenia na zegar phi2 należy synchronizowany kanał wyciszyć. Teraz, podobnie jak w metodzie pierwszej resetujemy liczniki wielomianowe, ustawiamy AUDFx na wartość selektora, która spowoduje synchronizację z wybranym elementem sekwencji poly4 i przełączamy POKEY-a na tryb normalnej pracy. Następnie oczekujemy na pierwsze uderzenie zegara div28, które powoduje załadowanie wartości selektora do timera. Począwszy od cyklu 25 możemy wpisywać do AUDFx ostateczną wartość podzielnika częstotliwości. Czas na to ustawienie jest krytyczny podobnie jak w metodzie pierwszej. Można ten czas wydłużyć powiększając wartość selektora o 15 w przypadku gdy jest ona niska.

    Należy zauważyć, że wartości selektorów w tej metodzie są o jeden mniejsze od odpowiadających im wartości używanych w metodzie pierwszej (z zastrzeżeniem, że do liczb ujemnych dodajemy 15). Wynika to z faktu, że pierwsze uderzenie zegara div28 po resecie jest tracone na wpisanie wartości selektora do timera, podczas gdy w metodzie pierwszej to wpisanie odbywało się jeszcze w trakcie resetu przy pomocy zapisu do rejestru STIMER.

    Druga metoda synchronizacji, podobnie jak pierwsza, może być stosowana do więcej niż jednego kanału. W sytuacji, gdy synchronizacji podlega kanał 2 lub 4, konieczne jest zastosowanie długiego czasu oczekiwania na wyzerowanie timera takiego kanału (7168 cykli przy div28). Wariantem tej metody może być rozpoczęcie synchronizacji przez wpisanie 0 do AUDFx już w poprzedzającym cyklu playera muzyki.

    Oto przykładowy kod synchronizujący liczniki metodą drugą przy założeniu, że używany jest zegar div28.

    sE10Ch1 = 14  ; it's safer to use selector values increased by 15 
     sE8Ch1 = 0 
     sE6Ch1 = 1 
     sE6Ch3 = 0 
       
           ; begin setting channel 1 timer with 0 
           lda #0 
           sta AUDF1     ; put 0 to AUDF1 
           lda #$C0 
           sta AUDC1     ; set channel 1 volume to 0 
           lda tmpAudCtl 
           ora #$40      ; clock channel 1 with phi2/1.79MHz 
           sta AUDCTL 
       
           ; wait at least 259 phi2 cycles so that timer counts down to 0 
           jsr wait260Cycles 
       
           ; restore AUDCTL desired value, i.e. clock channel 1 with div28 
           lda tmpAudCtl 
           sta AUDCTL 
       
           ; wait at least 112 phi2 cycles so that timer counts down to 0 
           jsr wait112Cycles 
           ; now channel 1 timer is set to 0 
           ; each div28 clock pulse loads channel 1 timer with AUDF1 = 0 
       
           ; reset POKEY polynomial counters 
           lda #0 
           sta SKCTL 
           ; the period of resetting POKEY (SKCTL = 0) should last for 
           ; at least 17 cycles to clear the longest 17-bit polycounter 
       
           ; set AUDF1 register with selector value needed to reach desired E6 
           ; poly4 element by channel 1 
           lda #sE6Ch1   ; 2 cycles 
           sta AUDF1     ; 4 cycles 
       
           nop           ; 2 cycles 
           nop           ; 2 cycles 
           nop           ; 2 cycles 
       
           ; finish resetting 
           lda #3        ; 2 cycles 
           sta SKCTL     ; 4 cycles 
       
           ; wait for first div28 clock pulse to load timer with selector 
           :12 nop       ; 24 cycles 
       
           ; set AUDF1 register with desired frequency divisor 
           lda tmpAudF1 
           sta AUDF1 
           ; setting AUDF1 register with desired frequency divisor must complete 
           ; before next sampling based on selector (next loading a timer)! 
       
           ; set AUDC1 register with desired volume (restore volume) 
           lda tmpAudC1 
           sta AUDC1

    Druga metoda synchronizacji nie ma wady metody pierwszej czyli wytwarzania słyszalnego kliknięcia na wszystkich kanałach. Niemniej, konieczność wyciszania i przywracania głośności w kanale synchronizowanym też może czasem skutkować podobnym kliknięciem. Wniosek jest taki, że żadna z metod nie nadaje się do częstego stosowania. Metodę drugą można śmiało zastosować, w momencie gwałtownego narastania głośności nowej nuty (faza attack) lub też w czasie całkowitego wyciszenia. Metoda ta ma przewagę na pierwszą, ponieważ można ją stosować w dogodnych momentach w danym kanale niezależnie od tego co jest odgrywane na pozostałych kanałach. W przypadku metody pierwszej wybranie dogodnego momentu jak gwałtowne narastanie głośności we wszystkich kanałach czy całkowite wyciszenie wszystkich może być trudne co mocno ogranicza możliwość stosowania tej metody.

    Selektory punktu synchronizacji

    W poprzednich rozdziałach pojawiały się informacje dotyczące selektorów punktu synchronizacji czyli inaczej mówiąc selektorów elementu Ex sekwencji poly4, który w wyniku synchronizacji zostanie spróbkowany jako pierwszy.

    Wartości selektorów zależą od zastosowanej metody synchronizacji oraz użytego zegara kanału ale dla każdego przypadku jest ich dokładnie 15 i odpowiadają one piętnastu elementom Ex sekwencji poly4. Synchronizacja kanału przy użyciu danego selektora oznacza, że pierwsze próbkowanie po synchronizacji natrafi na element sekwencji poly4 wskazany przez dany selektor. Selektory wyrażane są za pomocą wartości wpisywanych do rejestrów AUDFx. Wartość danego selektora oznacza wartość początkową jaką należy wpisać do rejestru AUDFx aby przy danej metodzie synchronizacji i zegarze próbkowanie rozpoczęło się od wskazanego elementu Ex sekwencji poly4. Poprzednie rozdziały (i w szczególności tabela 15) pokazywały też, jak można wyznaczyć wartości selektorów. Poniższa tabela zestawia przypisania elementów Ex sekwencji poly4 do poszczególnych wartości selektorów dla wszystkich kanałów dla zegarów div28 i div114 i obu metod synchronizacji.

    Wartość selektora

    Zegar div28

    Zegar div114

    Metoda 1

    Metoda 2

    Kanał 1

    Kanał 2

    Kanał 3

    Kanał 4

    Kanał 1

    Kanał 2

    Kanał 3

    Kanał 4

    0

    -1  (14 | 4)

    E10

    E9

    E8

    E7

    E9

    E8

    E7

    E6

    1

    0

    E8

    E7

    E6

    E5

    E3

    E2

    E1

    E0

    2

    1

    E6

    E5

    E4

    E3

    E12

    E11

    E10

    E9

    3

    2

    E4

    E3

    E2

    E1

    E6

    E5

    E4

    E3

    4

    3

    E2

    E1

    E0

    E14

    E0

    E14

    E13

    E12

    5

    4

    E0

    E14

    E13

    E12

     

     

     

     

    6

    5

    E13

    E12

    E11

    E10

     

     

     

     

    7

    6

    E11

    E10

    E9

    E8

     

     

     

     

    8

    7

    E9

    E8

    E7

    E6

     

     

     

     

    9

    8

    E7

    E6

    E5

    E4

     

     

     

     

    10

    9

    E5

    E4

    E3

    E2

     

     

     

     

    11

    10

    E3

    E2

    E1

    E0

     

     

     

     

    12

    11

    E1

    E0

    E14

    E13

     

     

     

     

    13

    12

    E14

    E13

    E12

    E11

     

     

     

     

    14

    13

    E12

    E11

    E10

    E9

     

     

     

     

    Tab. 16. Zestawienie selektorów punktów synchronizacji i odpowiadających im elementów Ex sekwencji poly4

    Tabela 16 nie zawiera przypisań elementów Ex do wartości selektorów dla zegara phi2. Można je w łatwy sposób wyznaczyć na podstawie pierwszych wierszy tabeli 15 pamiętając, że wzór na podzielnik przy użyciu zegara phi2 to N + 4.

    Jak wspominałem, w przypadku używania zegara div28 lub phi2 zwiększenie wartości selektora o wielokrotność 15 zachowuje wskazywany element Ex. W przypadku używania zegara div114 zwiększenie selektora o wielokrotność 5 zachowuje wskazywany element Ex. Wynika to z faktu, że tylko 5 z 15 elementów Ex jest dostępne dla każdego z kanałów (1 z 3 ścieżek próbkowania w kategorii C2 – patrz: tabela 10 i 14).

    W przypadku używania zegara div28 lub phi2 możliwa jest synchronizacja wielu kanałów generujących sygnał o takiej samej częstotliwości w kategorii C2 tak, aby próbkowanie przebiegało po tej samej ścieżce i wszystkie kanały były w tej samej fazie zgrubnej. Wystarczy w czasie procedury synchronizującej użyć dla poszczególnych kanałów takich wartości selektorów, które wskazują na ten sam element Ex. Przykładowo, jeśli chcemy aby próbkowanie rozpoczęło się we wszystkich kanałach od elementu E6 przy użyciu pierwszej metody synchronizacji i zegara div28 to musimy użyć selektorów o wartościach odpowiednio: kanał 1 – 2, kanał 2 – 9, kanał 3 – 1 i kanał 4 – 8. W przypadku używania zegara div114 do każdego kanału przypisana jest na stałe jedna ścieżka próbkowania. Ścieżka ST0, do której należą elementy E0, E3, E6, E9 i E12, jako jedyna przypisana jest do dwóch kanałów – 1 i 4 (patrz: tabela 10 i 14). Dzięki temu możliwa jest synchronizacja kanałów 1 i 4 poprzez ustawienie ich w tej samej fazie zgrubnej. Nie ma możliwości synchronizacji innej pary kanałów przy użyciu zegara div114.

    Kiedy potrzebna jest synchronizacja?

    Po lekturze ostatnich rozdziałów wiemy, jak synchronizować liczniki POKEY-a by ustawić wybrany kanał na wybranej ścieżce próbkowania a nawet w wybranej fazie zgrubnej. Jeżeli wybierzemy ścieżkę ST1 to mamy zapewnione stabilne brzmienie zniekształcenia C2 niezależnie od częstotliwości generowanego dźwięku. Teraz musimy odpowiedzieć na pytanie, w jakich sytuacjach potrzebna jest ponowna synchronizacja czyli ponowny wybór ścieżki próbkowania. Intuicyjnie można przypuszczać, że jest to konieczne przy każdej zmianie częstotliwości generowanego dźwięku czyli np. przy zmianie odgrywanej nuty lub w trakcie wykonywania efektów, które modulują częstotliwość, takich jak vibrato, portamento czy arpeggio. Każda zmiana częstotliwości rozpoczyna nowy proces próbkowania, a pierwsza próbka trafia w losowy element sekwencji poly4. Wydaje się też oczywiste, że zmiana zegara bazowego, która niewątpliwie pociąga za sobą zmianę generowanej częstotliwości, wymaga ponownego wyboru ścieżki próbkowania. W tym ostatnim przypadku tak jest w istocie lecz zmiana zegara bazowego w trakcie odgrywania muzyki zdarza się względnie rzadko i stosowanie procedury synchronizującej nie będzie raczej problemem. Zmiana wysokości nuty zdarza się z kolei stosunkowo często, co kilka ramek (przerwań VBLK). O ile jeszcze można sobie wyobrazić stosowanie procedury synchronizującej z taką częstością to stosowanie takiej procedury co ramkę w trakcie efektu modulującego częstotliwość raczej odpada (przede wszystkim ze względu na pojawiające się słyszalne kliknięcia). Okazuje się na szczęście, że synchronizacja nie jest potrzebna przy każdej zmianie częstotliwości. Nie jest potrzebna, jeżeli poruszamy się po częstotliwościach należących do jednej kategorii (choć nie jest to wyczerpujące stwierdzenie).

    Zasada zachowania ścieżki próbkowania

    Zdefiniujmy zbiór M3 jako sumę zbiorów okresów próbkowania P2 i P4 oraz zbiór M5 jako sumę zbiorów P3 i P4 (patrz: tabele 4 i 5). Zbiory okresów próbkowania Px odpowiadają kategoriom zniekształcenia Cx.

    Zbiór

    Definicja zbioru

    Reguła mapowania dziedzin

    Warunek przynależności do zbioru

    M3

    M3 = P2 ∪ P4

    p ∊ M3 ↔ R ∊ {0, 3, 6, 9, 12}

    p MOD 3 = 0 ↔ R MOD 3 = 0

    M5

    M3 = P3 ∪ P4

    p ∊ M5 ↔ R ∊ {0, 5, 10}

    p MOD 5 = 0 ↔ R MOD 5 = 0

    Tab. 17. Definicje zbiorów okresów rozszerzonych o elementy neutralne czyli o wielokrotności liczby 15

    Zbiór M3 to zbiór podzielników bezwzględnych, które są wieloktrotnościami liczby 3. Wartości R odpowiadające wszystkim tym podzielnikom i wyliczone z wzoru R = p MOD 15 są także wielokrotnościami liczby 3, w tym R = 0 pochodzące ze zbioru P4.
    Analogicznie zbiór M5 to zbiór podzielników bezwzględnych, które są wieloktrotnościami liczby 5. Wartości R odpowiadające wszystkim tym podzielnikom i wyliczone z wzoru R = p MOD 15 są także wielokrotnościami liczby 5, w tym R = 0 pochodzące ze zbioru P4.

    Elementy, dla których R = 0, są neutralne a ustawienie podzielnika częstotliwości próbkowania na wartość neutralną można traktować jako pauzę w procesie próbkowania.

    Zbiory M3 i M5 to odpowiedniki zbiorów P2 i P3 rozszerzone o elementy neutralne z P4.
    Szczególną właściwością zbiorów P2 i P3 oraz M3 i M5 jest to, że próbkowanie z użyciem podzielników należących do tych zbiorów może przebiegać po jednej z wielu ścieżek. Zbiór podzielników nienależących ani do M3 ani do M5 to zbiór P1 a dla podzielników należących do tego zbioru możliwa jest tylko jedna ścieżka próbkowania.
    Zbiór podzielników, dla których istnieje wiele ścieżek próbkowania, rozszerzony o elementy neutralne, czyli w naszym przypadku M3 lub M5, nazwiemy ogólnie Mx.

    Zasada zachowania ścieżki próbkowania mówi:

    Jeżeli bezwzględny podzielnik częstotliwości próbkowania zmienia się z jednej wartości należącej do zbioru Mx na inną wartość należącą do tego samego zbioru to bieżąca ścieżka próbkowania zostaje zachowana czyli próbkowanie po zmianie nadal odbywa się po tej samej ścieżce co przed zmianą podzielnika. Jeżeli bieżącym podzielnikiem jest element neutralny to próbkowanie zatrzymuje się na jednym elemencie poly4 a bieżąca ścieżka próbkowania zostaje zachowana i próbkowanie będzie odbywać się po tej samej ścieżce, gdy nastąpi zmiana podzielnika na inny niż neutralny.

    Innymi słowy, zmieniając częstotliwość próbkowania posługując się przy tym wyłącznie podzielnikami należącymi do zbioru Mx nigdy nie spowodujemy zmiany bieżącej ścieżki próbkowania. Ta zasada ma ogromne znaczenie ponieważ eliminuje konieczność synchronizacji liczników POKEY-a po każdej zmianie częstotliwości odgrywanej nuty. Jak już wcześniej pisałem, niemożność zmiany ścieżki wynika z ograniczonej do co trzeciego elementu rozdzielczości próbkowania sekwencji poly4 i braku możliwości przeskoku o inną odległość między elementami poly4 niż wielokrotność 3. Tak więc w przypadku zegarów phi2 i div28 utrzymanie ścieżki sprowadza się do zapewnienia, że przełączamy się tylko pomiędzy wartościami AUDFx, które należą do Mx. W przypadku zegara div114 wszystkie możliwe wartości AUDFx należą do M3 więc mamy automatycznie zapewnione utrzymanie ścieżki.

    Zmiana podzielnika z należącego do danego Mx na podzielnik nienależący do tego Mx a następnie przywrócenie podzielnika należącego do Mx powoduje utratę wiedzy o bieżącej ścieżce próbkowania i może (choć nie musi) spowodować zmianę ścieżki próbkowania.

    W praktyce zasada zachowania ścieżki próbkowania oznacza, że konieczność synchronizacji liczników i ponownego wyboru ścieżki będzie występować bardzo rzadko. W szczególności może się okazać, że w czasie całego utworu na danym kanale pojawiają się tylko częstotliwości należące do jednej kategorii lub jednego zbioru Mx. W takiej sytuacji wystarczy dokonać jednokrotnego wyboru ścieżki próbkowania przed rozpoczęciem odgrywania utworu.

    Należy podkreślić, że zasada zachowania ścieżki próbkowania obowiązuje niezależnie od ustawionego w rejestrze AUDCx zniekształcenia generowanego dźwięku. Jeżeli więc jesteśmy w stanie zapewnić, że tablice podzielników częstotliwości używane dla różnych instrumentów w utworze czyli różnych rodzajów zniekształceń (w tym czystych tonów) zawierają tylko podzielniki należące do szczególnie nas interesującego zbioru M3 to problem niestabilności zniekształcenia C2 przestaje istnieć.

    Pewien problem stanowi zmiana podzielnika 16-bitowego w kanale łączonym z dwóch. Taka zmiana wymaga dwóch wpisów do rejestrów AUDFx i może się zdarzyć, że przeładowanie timera nastąpi pomiędzy jednym a drugim wpisem, skutkując ustawieniem timera na niepożądaną wartość spoza zbioru Mx. Rozwiązaniem tego problemu jest zmiana podzielnika w obsłudze przerwania IRQ timera lub używanie procedury synchronizującej po każdej zmianie.

    Na koniec przyjrzyjmy się liczbie zero, która może być często wpisywana przez odtwarzacze muzyki do rejestrów AUDFx w czasie inicjalizacji POKEY-a przed pierwszym bądź kolejnym odtworzeniem muzyki czy też w czasie pauzy. Liczbie tej odpowiadają następujące podzielniki bezwzględne odpowiednio dla zegarów: phi2 – 4, div28 – 28, div114 – 114. Podzielniki o wartości 4 i 28 nie należą do zbioru M3 ani do M5. Podzielnik 114 należy do M3. To oznacza, że wpisanie zera do rejestru AUDFx, gdy jest używany zegar bazowy phi2 bądź div28, powoduje utratę wiedzy o ścieżce próbkowania, jeżeli była wybrana wcześniej dla kategorii C2 lub C3.

    Wpływ synchronizacji liczników wielomianowych na generator liczb pseudolosowych

    Synchronizacja liczników wielomianowych powoduje wyzerowanie licznika poly17 odpowiedzialnego za generację liczb losowych. Powstaje pytanie czy może to zakłócić generację liczb pseudolosowych w trakcie gier. Pełen cykl licznika poly17 trwa 131071 taktów zegara phi2, czyli około 3,7 ramki (klatki obrazu) w systemie PAL oraz 4,4 ramki w systemie NTSC. Używanie procedury synchronizującej liczniki częściej niż co 4 ramki (przerwania VBLK) mogłoby teoretycznie wpłynąć na sekwencje liczb losowanych przez daną grę, ale w praktyce synchronizacja nie będzie się odbywała tak często więc można uznać, że wpływu synchronizacji na losowane sekwencje nie ma. W przypadku zamiany licznika poly17 na licznik poly9 wpływu synchronizacji na losowane sekwencje nie ma tym bardziej, ponieważ długość cyklu tego licznika to 511 taktów phi2 czyli około 4,5 linii obrazu.

    Skala muzyczna

    Odpowiedni dobór podzielników w tablicach nut używanych dla różnych instrumentów czyli różnych rodzajów zniekształceń w taki sposób, że będą występować w nich tylko podzielniki należące do zbioru M3, może spowodować, że problem niestabilności zniekształcenia C2 przestanie istnieć. Wystarczy wtedy tylko jednokrotny wybór ścieżek próbkowania dla poszczególnych kanałów przed rozpoczęciem odgrywania muzyki. Czy jest możliwe zbudowanie takich tablic? Okazuje się, że tak. Poniżej przedstawiona jest tablica 8-bitowych podzielników dla nut w zakresie oktaw 1 – 3 (bas, zniekształcenie C2), oraz oktaw 3 – 5 (czyste tony). Częstotliwości wynikające z dobranych podzielników nie są idealne w przypadku niektórych nut ale idealny dobór nie jest możliwy przy ograniczeniu się do 8-bitowych podzielników. Ten sam problem dotyczy podzielników podanych w oryginalnej dokumentacji układu POKEY dla zakresu nut C-3 – C-6 i czystych tonów. Tam częstotliwości są prawidłowe tylko w zakresie dwóch oktaw od C-3 do C-5. Powyżej nuty C-5 odchyłki od prawidłowych częstotliwości są dość spore i dla niektórych nut niekaceptowalne. W podobny sposób nie jest doskonała oryginalna tablica podzielników dla basów C. Tu prawidłowe częstotliwości są dla nut G#1 – C-3 a powyżej również pojawiają się nieakceptowalne odchyłki. Podana poniżej tablica łączy w sobie najbardziej prawidłowe obszary z obu wspomnianych oryginalnych tablic a jej zaletą jest to, że wszystkie występujące w niej podzielniki należą do zbioru M3.

    Częstotliwości są nieco wyższe od tych dobranych we wspomnianych dwóch oryginalnych tablicach co powoduje, że nie ma między nimi harmonii i że nie można używać ich zamiennie w jednym utworze. Dostajemy za to spójnie brzmiącą tablicę podzielników dla nut w zakresie czterech oktaw od nuty G-1 do F#5, choć podzieloną na dwa brzmienia – C2 i czyste tony.

    Znieksz.

    Oktawa

    C

    C#

    D

    D#

    E

    F

    F#

    G

    G#

    A

    A#

    B

    C (C2)

    1

     

     

     

     

     

     

     

    FB

    F2

    E3

    D7

    CB

    2

    BF

    B6

    AA

    A1

    98

    8F

    89

    80

    7A

    71

    6B

    65

    3

    5F

    (5C)

    (56)

    (50)

    (4D)

    (47)

    (44)

     

     

     

     

     

    A

    3

    EF

    E3

    D7

    CB

    BF

    B3

    AA

    A1

    98

    8F

    86

    80

    4

    77

    71

    6B

    65

    5F

    59

    53

    50

    4A

    47

    44

    3E

    5

    3B

    38

    35

    32

    2F

    2C

    29

     

     

     

     

     

    Tab. 18. Tablica wartości AUDF (hex) podzielników należących do M3 dla nut w zakresie G-1 – F#5

    Problem doboru częstotliwości dotyczy tylko podzielników 8-bitowych i tylko czystych tonów oraz zniekształcenia C2. W przypadku instrumentów bazujących na szumach korekta podzielników na należące do M3 nie będzie żadnym problemem. Nie będzie też problemem dobór podzielników 16-bitowych. Zarówno dla czystych tonów jak i zniekształcenia C2 możliwe jest dobranie prawidłowych 16-bitowych podzielników należących do M3 dla nut w zakresie oktaw 0 – 7.

    Liczność zbiorów podzielników

    Jak wynika z poprzedniego rozdziału, dobór podzielników do skali muzycznej jest nieco problematyczny w wypadku podzielników 8-bitowych. Przyjrzyjmy się więc liczości podzielników należących do poszczególnych kategorii. W pierwszej kolejności zobaczmy jakie są liczności jeżeli używamy zegara bazowego div28 lub phi2. W takim przypadku co trzeci podzielnik jest podzielny przez 3. To oznacza, że 1/3 podzielników należy do zbioru M3. Z kolei co piąty podzielnik jest podzielny przez 5 czyli 1/5 podzielników należy do M5. Częścią wspólną obu zbiorów jest zbiór P4 podzielników należących do kategorii C4. Co piętnasty podzielnik jest podzielny przez 15 czyli 1/15 podzielników należy do P4. Podzielniki nienależące do żadnego z wymienionych zbiorów należą do P1 czyli zbioru podzielników należących do kategorii C1. Proporcje pomiędzy licznościami poszczególnych podzbiorów są jednakowe w zbiorze podzielników 8-bitowych i 16-bitowych. Podsumowanie znajduje się w poniższej tabeli.

    Zbiór podzielników

    Udział w całym zbiorze

    Liczność podz. 8-bit

    Liczność podz. 16-bit

    P1/C1

    8/15

    137

    34953

    P2/C2

    4/15

    68

    17476

    P3/C3

    2/15

    34

    8738

    P4/C4

    1/15

    17

    4369

    M3 = P2 ∪ P4

    1/3 = 5/15

    85

    21845

    M5 = P3 ∪ P4

    1/5 = 3/15

    51

    13107

    Tab. 19. Liczność zbiorów podzielników w poszczególnych kategoriach brzmienia dla zegarów div28 i phi2

    W przypadku użycia zegara div114 każdy podzielnik jest podzielny przez 3 i należy do zbioru M3. Co piąty jest podzielny przez 5 a przez to również przez 15, co oznacza, że 1/5 podzielników należy do P4. W tabeli poniżej znajduje się podsumowanie liczności zbiorów podzielników dla zegara div114.

    Zbiór podzielników

    Udział w całym zbiorze

    Liczność podz. 8-bit

    Liczność podz. 16-bit

    P1/C1

    brak

     

     

    P2/C2

    4/5

    205

    52429

    P3/C3

    brak

     

     

    P4/C4

    1/5

    51

    13107

    M3 = P2 ∪ P4

    1

    256

    65536

    M5 = P3 ∪ P4

    brak

     

     

    Tab. 20. Liczność zbiorów podzielników w poszczególnych kategoriach brzmienia dla zegara div114

    Przesunięcie fazowe

    Dotąd zaniedbywaliśmy przesunięcie (bądź opóźnienie) fazowe generowanego sygnału. Zazwyczaj nie ma ono znaczenia. Inaczej jest w sytuacji gdy dwa kanały (lub więcej) generują sygnał o tej samej częstotliwości. Mamy wtedy możliwość uzyskania ciekawych kształtów generowanej fali dźwiękowej będących sumą sygnałów z poszczególnych kanałów składowych.

    Przesunięcie fazowe sygnału o zniekształceniu C jest sumą dwóch składników. Pierwszy z nich to przesunięcie o małej rozdzielczości i dużym znaczeniu jednostkowej zmiany czyli zgrubne. Drugi składnik to przesunięcie o dużej rozdzielczości i małym znaczeniu jednostkowej zmiany czyli dokładne.

    Najczęściej rozpatrujemy przesunięcie fazowe jako opóźnienie jednego kanału względem innego, stanowiącego odniesienie. Możemy też jednak rozpatrywać przesunięcie fazowe jako początkowe opóźnienie pierwszego próbkowania względem momentu synchronizacji liczników.

    Przesunięcie fazowe zgrubne było już kilkukrotnie wspominane w poprzednich rozdziałach. Przesunięcie to może przyjąć jedną z N wartości gdzie N jest liczbą elementów (próbek) w okresie generowanego sygnału. Dla brzmień z kategorii C1 jest to 15, dla kategorii C2 – 5 i dla kategorii C3 – 3 (patrz: tabela 8). Wartość przesunięcia zgrubnego ustala się losowo w momencie zmiany częstotliwości kanału. Zależy ona od elementu Ex sekwencji poly4, od którego rozpoczęło się próbkowanie po zmianie częstotliwości. Początkowe przesunięcie zgrubne może zostać ustalone poprzez synchronizację liczników POKEY-a z użyciem selektora wskazującego na wybrany element Ex sekwencji poly4, od którego ma sie rozpocząć próbkowanie.

    Przesunięcie dokładne liczone jest w cyklach zegara bazowego. Może ono przyjmować tyle wartości ile cykli zegara mieści się w okresie generowanego sygnału. Wartość przesunięcia dokładnego po zmianie częstotliwości kanału jest określona przez moment pierwszego próbkowania sygnału poly4. Przesunięcie fazowe dokładne jednego kanału względem innego to ilość cykli zegara bazowego pomiędzy odpowiadającymi sobie próbkowaniami w obu tych kanałach. Początkowe przesunięcie dokładne może zostać ustalone poprzez synchronizację liczników POKEY-a. Jak wspominałem, wartość użytego przy synchronizacji selektora można zwiększać o wielokrotność liczby 15 (w przypadku zegara div114 o wielokrotność 5) nie zmieniając wybranej fazy zgrubnej i ścieżki próbkowania ale za to opóźniając moment pierwszego próbkowania. To opóźnianie pierwszego próbkowania to właśnie zwiększanie przesunięcia dokładnego.
    Wartość przesunięcia fazowego dokładnego można zwiększać niezależnie od zmian częstotliwości lub synchronizowania liczników. W tym celu należy do rejestru AUDFx kanału wpisać liczbę odpowiadającą efektywnemu podzielnikowi 15 lub wielokrotności (czyli podzielnikowi ze zbioru P4), a gdy ta zostanie załadowana do timera kanału, przywrócić w AUDFx właściwą wartość. Użycie podzielnika ze zbioru P4 powoduje powtarzanie próbkowania tego samego elementu poly4 co można traktować jako pauzę w procesie próbkowania. Jeżeli takie krótkotrwałe używanie podzielnika z P4 będzie okresowo powtarzane to zaowocuje płynnym zwiększaniem przesunięcia fazowego dokładnego danego kanału.

    Tym sposobem możemy zwiększać ale nie możemy zmniejszać przesunięcia fazowego dokładnego. Jeżeli jednak chcielibyśmy zmniejszać przesunięcie jednego z dwóch kanałów, to możemy zwyczajnie zwiększać przesunięcie drugiego z kanałów.
    Z płynnym zwiększaniem przesunięcia dokładnego wiąże się jeden problem. Przełączenie na podzielnik ze zbioru P4 powinno być krótkotrwałe, tzn. taki podzielnik powinien być użyty przez timer kanału tylko jeden raz. Aby to osiągnąć, konieczne jest użycie przerwania IRQ timera danego kanału. Handler takiego przerwania musi przywrócić właściwą wartość rejestru AUDFx. Należy zauważyć, że nie jest dużym problemem opóźnione wykonanie takiego handlera. Jeżeli handler nie zdąży przywrócić właściwej wartości rejestru AUDFx przed przeładowaniem timera to w najgorszym razie podzielnik ze zbioru P4 zostanie użyty drugi lub kolejny raz. Może to co najwyżej przez moment minimalnie przyśpieszyć płynne zwiększanie przesunięcia fazowego dokładnego, co raczej trudno będzie usłyszeć. Problemem jest natomiast fakt, że kanał 3 nie generuje przerwania IRQ, przez co płynne zwiększanie przesunięcia dokładnego nie może być zastosowane dla tego kanału.

    Generacja fali dźwiękowej przy użyciu kanałów zsynchronizowanych

    Sumowanie dwóch lub więcej kanałów generujących sygnał z tą samą częstotliwością może dać ciekawe efekty brzmieniowe. Wynikowy kształt sygnału zależy wtedy od względnych przesunięć fazowych oraz głośności sygnałów składowych. Należy pamiętać, że wyjścia kanałów 1 i 2 są inwertowane. Ma więc znaczenie, które kanały podlegają sumowaniu.

    Zasadniczo możemy uzyskać dwa rodzaje efektów:

    1. płynna zmiana przesunięcia fazowego jednego kanału (dwóch, trzech) względem pozostałych,
    2. stały kształt generowanej fali dźwiękowej jako suma kształtów fali dwóch do czterech kanałów.

    Pierwszy rodzaj efektów był już wspomniany w poprzednim rozdziale. Wymaga on użycia IRQ więc nie może być stosowany dla kanału 3. Zwiększanie przesunięcia fazowego dokładnego może być powtarzane bez końca. Następuje wtedy naturalne zapętlenie efektu. Zwiększanie przesunięcia fazowego poszczególnych kanałów można prowadzić z różnymi prędkościami. Jeżeli używamy tylko dwóch kanałów, ich względne przesunięcie dokładne możemy naprzemiennie zwiększać i zmniejszać, niekoniecznie w zakresie całego okresu generowanej fali. Zmiana względnego przesunięcia fazowego jednego z dwóch kanałów to efekt nieco zbliżony do modulacji współczynnika wypełnienia fali prostokątnej (ang. PWM – pulse>

    Drugi rodzaj efektów, choć wygląda prosto, jest dość kłopotliwy. Problemem jest utrzymanie stałego względnego przesunięcia fazowego między wybranymi kanałami przy zmianach częstotliwości. Niestety nie istnieje żadna zasada zachowania przesunięcia fazowego zgrubnego. Utrzymanie stałego przesunięcia fazowego wymaga aby w przypadku każdego z kanałów zmiana częstotliwości nastąpiła dokładnie przy próbkowaniu tego samego elementu Ex sekwencji poly4 czyli innymi słowy, aby próbkowanie z nową częstotliwością rozpoczęło się od tego samego elementu Ex. To jest ta sama sytuacja, którą uzyskujemy w wyniku synchronizacji. Aby zagwarantować, że zmiana częstotliwości nastąpi przy próbkowaniu tego samego Ex w wybranych kanałach, zmiana rejestrów AUDFx tych kanałów musiałaby być atomowa w takim sensie, że zmiany poszczególnych rejestrów AUDFx nie mogłyby być rozdzielone poprzez przeładowanie któregokolwiek z timerów wybranych kanałów. Inaczej mówiąc, musiałaby być zapewniona atomowość ustawiania wszystkich AUDFx względem przeładowań wszystkich timerów dla wybranych kanałów. Takiej atomowości oczywiście nie ma. Na skutek tego przy zmianie częstotliwości może dojść do zmiany zgrubnego przesunięcia fazowego i utraty informacji o nim. Stanie się tak, gdy zmiana częstotliwości w poszczególnych kanałach nastąpi przy próbkowaniu różnych elementów Ex i przez krótki moment kanały ustawione bedą na różne częstotliwości. Wymaganą atomowość można próbować zapewnić używając handlera przerwań IRQ związanego z kanałem, który próbkuje dany element Ex jako ostatni. Taki handler powinien dokonywać ustawiania rejestrów AUDFx wszystkich wybranych kanałów. Przy tym podejściu maksymalne względne przesunięcie fazowe między kanałami zostaje ograniczone do jednego okresu próbkowania czyli 1/5 okresu generowanej fali dla kategorii C2. Ponadto w tym pojedynczym okresie próbkowania musi się zawierać czas wykonania handlera IRQ.

    Jak więc widać, utrzymanie stałego przesunięcia fazowego między kanałami jest wyjątkowo trudne a ponadto ograniczone do 1/5 okresu generowanej fali. Inną opcją zawsze pozostaje synchronizacja liczników POKEY-a podczas której wybierane jest przesunięcie zgrubne i dokładne. Takie podejście wyklucza jednak zastosowanie efektu modulacji częstotliwości na zbiorze kanałów utrzymujących stałe przesunięcia fazowe (ze względu na możliwe słyszalne kliknięcia przy każdej zmianie częstotliwości).
    Jako ciekawostkę dodam, że istnieje też metoda ustawiania fazy zgrubnej bez konieczności synchronizacji liczników POKEY-a. Wymaga ona użycia przerwań IRQ i przebiega w trzech etapach co komplikuje handler IRQ. Metoda pozwala na ustalenie przesunięć fazowych zgrubnych przy zachowaniu bieżącej ścieżki próbkowania. Zakładamy, że używamy zegara bazowego div28 i częstotliwości z kategorii C2. W pierwszym etapie do rejestrów AUDFx wybranych kanałów wpisujemy liczbę 2 co odpowiada podzielnikowi 3. W momencie, gdy do timerów wybranych kanałów podzielnik 3 został załadowany, wszystkie one znajdują się w takiej samej fazie zgrubnej. W drugim etapie do AUDFx wpisujemy docelową wartość wspólnego podzielnika częstotliwości ale powiększoną odpowiednio dla poszczególnych kanałów o różnice fazy zgrubnej. Takie wartości podzielników mogą być załadowane do timerów tylko jeden raz. W trzecim etapie wpisujemy docelową wartość wspólnego podzielnika częstotliwości. W drugim i trzecim etapie należy oczywiście zachować atomowość ustawiania rejestrów AUDFx względem przeładowań timerów.

    Z uwagi na trudność w kontrolowaniu przesunięcia fazowego między kanałami zsynchronizowanymi przy zmieniającej się częstotliwości jednoczesne zastosowanie efektu modulacji fazy (jako substytutu PWM) oraz efektu modulacji częstotliwości jest niemożliwe.

    Podsumowanie

    To wszystko, co udało mi się ustalić na podstawie przeprowadzonych badań wytwarzania zniekształcenia C przez układ POKEY. Myślę, że ostatecznie udało się odpowiedzieć na pytania postawione we wstępie do tego artykułu. W szczególności udało się ustalić, czym jest niestabilność dźwięków określanych jako basy C oraz jak można ustabilizować te dźwięki. Oto najważniejsze odpowiedzi oraz krótki przepis na stabilizację, używający terminologii podanej w artykule.

    Basy C to dźwięki należące do jednej z czterech kategorii zniekształcenia C – C2. W kategorii tej dostępne są trzy różne brzmienia: T0, T1 i T2. Jedynym niezależnym od częstotliwości brzmieniem jest T1. Jest ono dostępne wyłącznie na ścieżce próbkowania ST1.

    Chcąc uzyskać stabilne czyli jednolite brzmienie zniekształcenia C w kategorii C2 używając zegara bazowego div28 lub phi2 należy zsynchronizować się jednokrotnie do ścieżki próbkowania ST1 i utrzymywać tą ścieżkę używając tylko podzielników częstotliwości należących do zbioru M3. Przy nastawach 8-bitowych można posłużyć się tablicą podzielników przedstawioną w tabeli 18. W przypadku używania zegara bazowego div114 nie ma potrzeby synchronizacji ale należy użyć kanału 3. Wszystkie podzielniki dla zegara div114 należą do zbioru M3 a kanał 3 ma na stałe przypisaną ścieżkę ST1.

    Cieszę się, że udało się odkryć drzemiące jeszcze w POKEY-u tajemnice jak "złota" ścieżka próbkowania, "złoty" kanał 3 czy zasada zachowania ścieżki próbkowania.
    Myślę, że udokumentowanie sposobów stabilizacji basów C otwiera drogę do implementacji tego rodzaju dźwieków w playerach i trackerach muzycznych. Użycie 8-bitowych basów C może być mocno ograniczone ze względu na nieduży zakres dostępnych nut – zaledwie dwie oktawy. Natomiast 16-bitowe basy C wydają się być ciekawą alternatywą dla powszechnie używanych 16-bitowych basów E. Mam nadzieję, że zgromadzona w tym artykule wiedza na temat zniekształcenia C okaże się przydatna do wydobycia z układu POKEY nowych brzmień.

    Do pobrania:

    Komentarze gości atari.area

    Momencik, uaktualniam...  

    Nie jesteś zalogowany. Tylko zarejestrowani i zalogowani użytkownicy mog± dodawać komentarze.

Lotharek.pl
Retronics
Grawitacja 2024
Lost Party 2024
Silly Venture 2024 SE

Szukaj

Wyszukiwarka przeszukuje zasoby atari.area, atariki oraz forum.

Twoliner

Momencik, uaktualniam...  .

Pamiętaj, żeby linki do Twolinera dodawać wyłącznie po skróceniu za pomocą serwisu tiny.pl. Jeśli coś Ciebie ominęło - skorzystaj z archiwum.

Network

konto

Nie jesteś zalogowany. Zaloguj się lub załóż konto

forum

Artykuły

Wywiady

Allegro

Jako, że Allegro.pl jest bardzo często odwiedzanym serwisem przez Atarowców, umiejscowiłem poniżej wyszukiwarkę produktów związanych z naszym kochanym Atari. Chcesz coś kupić - wystarczy wpisać w okienko poniżej.


Wystarczy wpisac czego szukamy i po chwili znajdujemy sie juz na Allegro.pl.