Artykuły

    Kurs Assemblera cz. 6 1/2

    Uzupełnienie do kursu "InertiaPlayer & ProTracker"

    Pewnie to wszyscy wiedzieli, tylko nie Ja, że pomysłodawcą i autorem programu do odtwarzania plików MOD (MD8) jest Pecuś. Dzięki jego uprzejmości można teraz lepiej wyjaśnic zasadę działania playera.

    Dodatkowo jest jeszcze sprawa Epiego i jego NeoTrackera ;), który chwali się że jest szybszy, ciekawe jak? Sample w Neo zajmują zawsze bank pamięci (16kb), ale wątpie żeby to przyspieszyło samego playera, co najwyżej procedurę dekodującą pattern, czyli pare cykli, które nijak bądą się miały do całego grania. Epi pochwal się swoimi osiągnięciami ! :)

    Jak ładować do pamięci dane i znajdować odpowiednio dużo miejsca ?

    Dostępna pamięć reprezentowana będzie przez tablicę z bitami, każdy bit to strona pamięci. Bit 1 - strona pamięci zajęta, bit 0 - strona wolna. Oczywiście każdy bit w tablicy to odpowiedni adres w pamięci. Teraz obliczamy ile stron zajmują dane, np. $150 = 2strony, szukamy w tablicy najmniejszego wolnego obszaru >= 2 i tam załadujemy dane. Dzięki temu załadujemy więcej sampli i oszczędzimy pamięć. Proste, prawda ?:)

    Teraz wróćmy do fragmentu playera, mało zrozumiałego, czyli etykiety "ist_0" itd.

    Pecuś rozjaśni obraz:

    pmain  equ *
    bank0  lda #$fe          ;bank w którym znajduje się sampl
           sta $d301
    ist_0  lda #0            ;tego nie rozumiem, bo brak w playerze odwolan do ist_0 itp.
    iad0_m adc #0            ;ale sa odwołania do "iad0_m" i "iad0_s"
           sta ist_0+1 
           lda p_0c+1        ;modyfikacja adresu sampla, dodajemy wartosc z tablicy czestotliwosci 
           ...
           ...
    

    Sprawa jest prosta, jedno słowo wystarczy "ułamek" :)

    Jeśli chcesz odtworzyć dźwiek o częstotliwości np. o połowę mniejszej niż wzorcowa, a petla licząca pozycje w samplu tylko dodaje i nie można sterować częstotliwością jej wywołania, to ile musisz dodawać za każdym obrotem pętli by osiągnąć o połowę mniejszą częstotliwość (czyli każda próbka odtwarzana jest dwa razy)?

    To oczywiste musisz dodać 0,5 - czyli dodajesz ułamek a i tak część po przecinku jest Ci potem niepotrzebna. No ale dodawać tak trzeba. W przypadku mojego playera $80 zapisane w tej "nieużywanej" komórce, a zera w pozostałych oznacza właśnie 0,5 tak jak $33 oznacza około 0,2, a dodawanie tej wartości spowoduje pięciokrotnie wolniejsze odtwarzanie sampla. Poprostu traktujemy 2 bajty jako adres sampla i dodatkowo jeszcze jeden bajt jako ułamkową część adresu.

    Być może ta komórka jest w innym obszarze strony zerowej i nie jest tak że liczba całkowita i ułamek są zapisane kolejno - ale to wynikało z prób i dodawania pewnych rzeczy po napisaniu wstępnej wersji.

    A teraz największe zaskoczenie i ciekawostka. Przy pisaniu tych procedur trzeba było stworzyć tablicę dodawanych wartości - nazwaną potem niezbyt poprawnie tablicą częstotliwości dźwieku. Zacząłem to liczyć za pomocą programu w basicu i tabeli częstotliwości kolejnych dźwięków z gamy. Wyliczyłem pierwszą oktawę i rzuciłem okiem na część kodu playera z Amigi. Tam jest inaczej bo 4 przetworniki mogą grać z niezależnie ustawianymi szybkościami... No ale do rzeczy - jakież było moje zdziwienie kiedy zauważyłem że tablica, którą zacząłem wyliczać odpowiada DOKŁADNIE tablicy częstotliwości przetworników w playerze Amigowym przepisanej tylko od końca :) - tak więc dałem sobie spokój z liczeniem i przewaliłem te tablice z Amigi.

    A co do odtwarzania, to player nie gra na JEDNYM generatorze - gra na TRZECH. Poprostu nieliniowość POKEYa powoduje, że odtwarzanie sampla na jednym generatorze powoduje zniekształcenia sampla granego na drugim - nie sumuje sie to zwyczajnie - a przy 3 już się nie da słuchać nie mówiąc o 4. Podobno niezły efekt uzyskuje sie przez ustawienie dźwieku o najwższej możliwej częstotliwości na każdym kanale i sterowanie głośnością (a nie bezpośrednie sterowanie głośnikiem). Ja poszedłem inną drogą, pomierzyłem napięcia uzyskiwane na wyjściu POKEYa przy wpisywaniu różnych wartości do generatorów, ułożyłem wyniki liniowo i stworzyłem tablice wpisów dla trzech generatorów - poczatkowo było na czterech, ale niestety mamy tylko 3 rejestry, a rozkaz ładowania rejestru po drodze zakłócał dźwiek.

    Uff... Na AIM wrzuciłem kiedyś źrodła playera i konwertera, ale ja nie komentowałem ich zbyt dobrze (słynna etykieta SPRDAL - osnaczająca oczywiście "Sprawdzaj Dalej" :) - poza tym to nie jest ostatnia wersja, a chyba nawet jedna z pierwszych - polecam zdisasemblowanie wersji z Intel Oudside. A to ładowanie na DOSa to nie zabezpieczenie - poprostu miało chodzić na 64kb, więc potrzebna była maksymalna ciągła pamięć, stąd loader z CHAOSa w środku i tak niskie ładowanie. A zabezpieczenienie było dlatego, że jak dałem do testowania w Bajtku wersje niezabezpieczoną to za tydzień krążyła już po giełdzie (a nie miała jeszcze niezależnej głośności kanałów i zapętleń końcówek sampli).

    Pozdro. Pecuś.

    pmain   equ *
    bank0   lda #$fe            ;bank w którym znajduje się sampl
            sta $d301
    
    ist_0   lda #0              ;to już rozumiem bo Pecuś wytłumaczył :)
    iad0_m  adc #0              ;modyfikacja wartości w "iad0_m" i "iad0_s"
            sta  ist_0+1 
    
            lda p_0c+1          ;modyfikacja adresu sampla, dodajemy wartosc z tablicy czestotliwosci 
    iad0_s  adc #0              ;mlodszy bajt adresu
            sta p_0c+1
            bcc p_0c
            inc p_0c+2          ;starszy bajt adresu
            lda p_0c+2          ;sprawdzenie czy to już koniec sampla
    ien0_s  cmp #0
            bcc p_0c
    
    ire0_m  lda #0              ;ustawienie nowego adresu poczatkowego sampla
            sta p_0c+1          ;czyli petla sampla
    ire0_s  lda #0
            sta p_0c+2
            jmp bank1
    
    p_0c    ldx $ffff           ;wartość sampla
    ivol10  lda $d800,x         ;tablica głośności
    ch0     sta $d600           ;graj, jeśli urzadzeniem jest POKEY to będzie adres $d200
    
    bank1   ...........  nastepny kanal itd.
    

    Sprawa głośności sampla. Nie ma szybszego sposobu niż:

        ldx $ffff      ;wartość sampla (bajt)
        lda $d800,x    ;tablica głośności - modyfikowany adres
        sta $d600      ;graj, jeśli urzadzeniem jest POKEY to będzie adres $d200
    

    MOD ma 64-o stopniową skalę głośności, ale na potrzeby Atari wystarczająca jest 32 stopniowa skala, zajmuje o połowe mniej miejsca :), jak wyliczyć tablice? Wartości w samplu są z zakresu <0,255>, więc te wartości będą skalowane przez tablice głośności. 256 wartości przez 32 głośności = 8, czyli co 8 jednostek będzie zmieniała się głośność.

    Czyli mamy głośności tak naprawdę 0,8,16,32 ... 256, np. glośność =8 oznacza że w 256 wartościach naszej tablicy głośności musimy zmieścić wartości z zakresu 0..8, głośność =48 oznacza, że w 256 wartościach są liczby z zakresu 0..48 itd. Dla głośności =0, wszystkie wartości w tablicy będą =0, czyż nie jest to oczywiste :D Chyba już rozumiecie że skalujemy w ten sposób wartości sampla :)

    Oto programik w stylu Turbo Pascala, wyliczający tablice głośności:

    uses crt;
    
    var z,i,skala:integer;           {deklaracje zmiennych INTEGER-całkowite}
        co_ile_stopni:integer;       
        x:real;                      {zmienna typu rzeczywistego, dla ułamków}
        v:byte;                      {byte}
    
    begin
      clrscr;                        {czyścimy ekran}
      co_ile_stopni:=8;              {czyli 256wartości przez 32 stopniowa}
                                     {skale głośności = 8}
      for skala:=1 to 32 do begin
        z:=skala*co_ile_stopni;      {obliczamy zakres}
        x:=z/256;                    {obliczamy wartość kroku, aby wszystkie}
                                     {elementy zmieściły się w 256 bajtach}
        for i:=0 to 255 do begin
          v:=round(i*x);             {liczymy zaokrąglając wartości}
          write(v,',');              {wypisujemy na ekran, albo do pliku}
        end;
      end;
    
    end.                             {koniec przykładu}

    Dla każdej głośności będzie więc 256 bajtowa tablica. 32*256 = 8192bajtów zajmą wszystkie tablice. Normalnie w Inertii taka tablica siedzi sobie w dodatkowym banku, i dopiero gdy jest potrzebna przepisywana jest pod ROM, $d800...

    Pytanie za 100punktów

    Czy da się przyspieszyć player? Jakieś sugestie co do jego przyspieszenia? Pamiętajcie tylko, że cały kod mieści się na stronie zerowej.

    A może tak przydałby się player grający 256 bajtowymi samplami, do tego wibracje i inne efekty z MOD-a, tak żeby można było stworzyć chiptunes. Takiego 256bajtowego sampla możnaby było sobie samemu edytować, nadać mu kształt trójkąta, fali czy czegoś innego, tak aby wydobyć dźwięki np. podobne do SIDa. Jak myślicie, można na takim 256 bajtowym sampelku coś zrobić ??

    Player dla 256bajtowych próbek byłby szybszy, a mógłby wyglądać tak:

    pmain  equ *
    
    ist_0  lda #0             ;to już rozumiem bo Pecuś wytłumaczył :)
    iad0_m adc #0             ;modyfikacja wartości w "iad0_m" i "iad0_s"
           sta ist_0+1 
    
           lda p_0c+1         ;modyfikacja adresu sampla, dodajemy wartosc z  tablicy czestotliwosci 
    iad0_s adc #0             ;mlodszy bajt adresu
           sta p_0c+1
           bcc p_0c
    ien0_s cmp #0             ;test dlugosci
           bcc p_0c
    
    ire0_m lda #0             ;ustawienie nowego adresu (mlodszy) poczatkowego sampla
           sta p_0c+1         ;czyli petla sampla
           jmp kanal2
    
    p_0c   ldx $ffff          ;wartość sampla
    ivol10 lda $d800,x        ;tablica głośności
    ch0    sta $d600          ;graj, jeśli urzadzeniem jest POKEY to będzie adres $d200
    
    kanal2 ...........  nastepny kanal itd.
    

    Sample nie musiałyby znajdować się w dodatkowych bankach, zawsze miałyby 256bajtów, sprawdzany byłby tylko młodszy bajt adresu. Dzięki takiej oszczędności cykli możnaby do playera dorzucić procedurki odpowiedzialne za inne fx-y niż Volume. Chyba w ten sposób działa SoftSynth, jeśli ktoś zna działanie SoftSytnha od "kuchni" chętnie posłucham. Przydałby się jeszcze dokładny opis z implementacją efektów dźwiękowych z MOD-a, ktoś chętny??

    Komentarze gości atari.area

    Momencik, uaktualniam...  

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

Lotharek.pl
Retronics
Silly Venture
Last Party 2025
Lost Party 2025

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.