[#1] Generowanie dźwięku/tonu w asemblerze
Szukam minimalnego kodu w asemblerze, który raz wykonany będzie generował dźwięk o określonej, stałej częstotliwości na wyjściach audio każdej Amigi (w tym A1000). Kod nie może być zapętlony, czyli po włączeniu dźwięku, program musi wykonywać się dalej. Czy jest taka możliwość i czy ktoś wie, jak to zrobić?
[#2] Re: Generowanie dźwięku/tonu w asemblerze

@RomanWorkshop, post #1

Jesli ma to byc sinus to wygenrowac tablice w asmone, podac ja jako start dla dma ktoregos kanalu audio i odpalic, ustawic przerwanie konca sampla i w nim odpalac sampel ponownie. Wczesniej ustawic rejestr z jakia predkoscia na byc odtwarzany sampel.
Mam gdzies kawalek kodu w domu na Ami bez przerwania, mige obczaic w weekend.

Ostatnia aktualizacja: 30.11.2018 17:51:03 przez flops
[#3] Re: Generowanie dźwięku/tonu w asemblerze

@flops, post #2

O to super, przykładowy program byłby pomocny, bo nigdy nie kodowałem dźwięku na Amidze.
[#4] Re: Generowanie dźwięku/tonu w asemblerze

@RomanWorkshop, post #3

Jak umiesz czytać C to popatrz jak jest zrobiony dźwięk w ACE (tu plik .h).

Popatrz na funkcję audioPlay: wybierasz sobie kanał i dla niego odpowiednio w rejestrze ac_ptr podajesz adres sampli 8-bitowej ze znakiem, ac_len to długość sampli, ac_vol to jej głośność a ac_per to okres - jak to liczyć masz w Amiga Hardware Reference Manual. Potem włączasz DMA danego kanału i leci. ;)

Jak chcesz puścić to raz lub tylko określoną liczbę razy to musisz zrobić handler przerwania od kanału audio i tam zresetować kanał. Jak chcesz w pętli to nic dalej nie musisz robić, Paula sama będzie powtarzać dźwięk. Jak chcesz go zatrzymać to wyłącz DMA kanału i ustaw wszystkie jego rejestry na zero.
[#5] Re: Generowanie dźwięku/tonu w asemblerze

@RomanWorkshop, post #1

To jest kawałek kodu pisany (pewnie przepisany z książki) jeszcze w latach '90 i tylko dodałem tylko sin jako sampel i ustawiłem częstotliwość.

incdir "includes:"
include "hardware/custom_all.i"
lea CUSTOM,a0
move.l #sinuso,AUD0LC(a0)
move.w #18,AUD0LEN(a0) ; dlugosc sampla/2
move.w #$40,AUD0VOL(a0)
; move.w #358,AUD0PER(a0) ; 10kHz odwarzanie probek
move.w #124,AUD0PER(a0) ; max Ami Hz (~28kHz teoretycznie)
move.w #$8201,DMACON(a0); ale czestotliwosc sinusa z 36 probek to tylko 801Hz
mouse:
btst #6,$bfe001
bne mouse2
bchg #1,$bfe001
mouse2:
btst #2,$dff016
bne mouse
rts

section code,code_c
sinuso:
EVEN
DC.B $00,$16,$2B,$40,$52,$61,$6E,$77,$7D,$7F,$7D,$77,$6E,$61,$52,$40
DC.B $2B,$16,$00,$EA,$D5,$C1,$AE,$9F,$92,$89,$83,$81,$83,$89,$92,$9F
DC.B $AE,$C0,$D5,$EA

Kompilator asm-one, gdyby brakowało Ci includes, to mogę spakować i podrzucić gdzieś na email. Ja mam głowny katalog includów asmowych assign jako includes:

Ostatnia aktualizacja: 02.12.2018 18:03:41 przez flops
[#6] Re: Generowanie dźwięku/tonu w asemblerze

@flops, post #5

Dzięki. Dzisiaj przestudiowałem dokumentację i wszystko stało się jasne. Opracowałem swój kod, ale na WinUAE nic nie słychać. Druga sprawa, to jak zapewnić aby sampel znalazł się w pamięci CHIP? Chyba odpowiada za to dyrektywa "section code,code_c" w ASM-One?

;Każda Amiga może generować dźwięk w 4 kanałach (po 2 kanały na każde wyjście audio stereo).
;Kanały nr 0/3 tworzą lewe wyjście, a kanały nr 1/2 - prawe wyjście audio stereo.


        move.l   $DFF000,A6   ;adres bazowy rejestrów kontrolnych układów specjalizowanych Amigi
;Ustawienie początku danych (tablicy 8-bitowych próbek) sampla do odtworzenia
        lea      Wave(pc),A1  ;adres początku danych sampla do odtworzenia
        move.l   A1,$A0(A6)   ;zapis adresu początku sampla do rejestrów [AUD0LCH:AUD0LCL] (kanał 0)
        move.l   A1,$B0(A6)   ;zapis adresu początku sampla do rejestrów [AUD1LCH:AUD1LCL] (kanał 1)
;Ustawienie długości danych sampla, wyrażonej w słowach (1 = 2 bajty, czyli 2 próbki 8-bitowe)
        move.w   #4,$A4(A6)   ;zapis długości danych sampla (w słowach) do rejestru AUD0LEN (kanał 0)
        move.w   #4,$B4(A6)   ;zapis długości danych sampla (w słowach) do rejestru AUD1LEN (kanał 1)
;Ustawienie głośności odtwarzania w danym kanale (0-64, 64 = maksymalna głośność)
        move.w   #64,$A8(A6)  ;zapis poziomu głośności do rejestru AUD0VOL (kanał 0)
        move.w   #64,$B8(A6)  ;zapis poziomu głośności do rejestru AUD1VOL (kanał 1)
;Ustawienie przerwy między odtwarzaniem kolejnych próbek sampla (częstotliwość odtwarzania)
        move.w   #443,$A6(A6) ;zapis liczby cykli opóźnienia do rejestru AUD0PER (kanał 0)
        move.w   #443,$B6(A6) ;zapis liczby cykli opóźnienia do rejestru AUD1PER (kanał 1)

;Wartość opóźnienia 443, powoduje odtwarzanie sampla z częstotliwością ok. 1 kHz.

;Jest to liczba cykli zegara systemowego, która upływa przed odtworzeniem kolejnej 8-bitowej
;próbki sampla. Minimalna wartość wynosi 123/124 cykle dla Amigi pracującej w standardzie PAL/NTSC,
;a maksymalna wynosi 65535. Im mniejsza wartość, tym większa częstotliwość odtwarzania sampla.
;Maksymalna szybkość odtwarzania sampla przez jednoskę DMA, wynosi 28867 próbek (bajtów) na sekundę.

;Aby obliczyć prawidłową liczbę cykli opóźnienia CX dla uzyskania dowolnej częstotliwości odtwarzania,
;należy dokonać następujących obliczeń: CX = cc/(f*sn), gdzie: cc - stała zależna od standardu pracy
;Amigi: 3546895 (PAL); 3579545 (NTSC), f - zakładana częstotliwość odtwarzania [Hz], sn - liczba
;próbek (bajtów) w samplu.

;Włączenie odtwarzania sampla
        move.w   #$8203,$96(A6) ;zapis do rejestru DMACON, ustawienie bitów nr: 15 - SET/CLR,
                                ;9 - DMAEN (włączenie jednostki DMA), 1 - AUD1EN (włączenie kanału 1),
                                ;0 - AUD0EN (włączenie kanału 0).

;Czekanie na naciśnięcie lewego przycisku myszy
Wait:   btst     #6,$BFE001
        bne.s    Wait

;Wyłączenie odtwarzania sampla
        move.w   #$0003,$96(A6) ;zapis do rejestru DMACON, zerowanie bitów nr: 15 - SET/CLR,
                                ;1 - AUD1EN (wyłączenie kanału 1), 0 - AUD0EN (wyłączenie kanału 0).
        rts

;Dane sampla muszą znajdować się pod parzystym adresem (wyrównanie do słowa) w pamięci CHIP,
;aby jednostka DMA miała do nich dostęp.

;Każdy bajt to 8-bitowa próbka, określająca amplitudę (poziom) sygnału generowanego na wyjściu audio
;w danym momencie odtwarzania sampla. Amplituda każdej próbki zawiera się w zakresie od -128 do +127,
;co przy ustawionej maksymalnej głośności odtwarzania (64), zapewnia uzyskanie napięcia od -0.4 do +0.4V
;na wyjściu audio.

Wave:   dc.b     0,90,127,90,0,-90,-127,-90 ;sinus
        dc.b     127,127,127,127,-127,-127,-127,-127 ;prostokąt


Ostatnia aktualizacja: 02.12.2018 18:21:45 przez RomanWorkshop
[#7] Re: Generowanie dźwięku/tonu w asemblerze

@RomanWorkshop, post #6

Druga sprawa, to jak zapewnić aby sampel znalazł się w pamięci CHIP? Chyba odpowiada za to dyrektywa "section code,code_c" w ASM-One?

Dokładniej data_c

section sample,data_c
[#8] Re: Generowanie dźwięku/tonu w asemblerze

@Hexmage960, post #7

A czy bootblock dyskietki zawsze jest ładowany do pamięci CHIP?
[#9] Re: Generowanie dźwięku/tonu w asemblerze

@RomanWorkshop, post #8

Tak.
[#10] Re: Generowanie dźwięku/tonu w asemblerze

@Don_Adan, post #9

Na 3.1 jesli jest FAST to zostanie wczytany do FAST. Sprawdzone.
[#11] Re: Generowanie dźwięku/tonu w asemblerze

@RomanWorkshop, post #6

Wiem już czemu poprzedni kod mi nie działał. Głupi błąd: zamiast załadować adres $DFF000 do rejestru A6 ("move.l #$DFF000,A6"), ładowałem tam zawartość komórki pamięci o tym adresie ("move.l $DFF000,A6"). Jeden znak, a dużo zmienia.

Poniżej działający kod, który generuje sygnał sinusoidalny 1 kHz na obu wyjściach audio stereo Amigi:

;Każda Amiga może generować dźwięk w 4 kanałach (po 2 kanały na każde wyjście audio stereo).
;Kanały nr 0/3 tworzą lewe wyjście, a kanały nr 1/2 - prawe wyjście audio stereo.

        move.l   #$DFF000,A6  ;adres bazowy rejestrów kontrolnych układów specjalizowanych Amigi
;Ustawienie początku danych (tablicy 8-bitowych próbek) sampla do odtworzenia
        move.l   #Wave,A1     ;adres początku danych sampla do odtworzenia
        move.l   A1,$A0(A6)   ;zapis adresu początku sampla do rejestrów [AUD0LCH:AUD0LCL] (kanał 0)
        move.l   A1,$B0(A6)   ;zapis adresu początku sampla do rejestrów [AUD1LCH:AUD1LCL] (kanał 1)
;Ustawienie długości danych sampla, wyrażonej w słowach (1 = 2 bajty, czyli 2 próbki 8-bitowe)
        move.w   #4,$A4(A6)   ;zapis długości danych sampla (w słowach) do rejestru AUD0LEN (kanał 0)
        move.w   #4,$B4(A6)   ;zapis długości danych sampla (w słowach) do rejestru AUD1LEN (kanał 1)
;Ustawienie głośności odtwarzania w danym kanale (0-64, 64 = maksymalna głośność)
        move.w   #64,$A8(A6)  ;zapis poziomu głośności do rejestru AUD0VOL (kanał 0)
        move.w   #64,$B8(A6)  ;zapis poziomu głośności do rejestru AUD1VOL (kanał 1)
;Ustawienie przerwy między odtwarzaniem kolejnych próbek sampla (częstotliwość odtwarzania)
        move.w   #443,$A6(A6) ;zapis liczby cykli opóźnienia do rejestru AUD0PER (kanał 0)
        move.w   #443,$B6(A6) ;zapis liczby cykli opóźnienia do rejestru AUD1PER (kanał 1)

;Wartość opóźnienia 443, powoduje odtwarzanie sampla z częstotliwością ok. 1 kHz.

;Jest to liczba cykli zegara systemowego, która upływa przed odtworzeniem kolejnej 8-bitowej
;próbki sampla. Minimalna wartość wynosi 123/124 cykle dla Amigi pracującej w standardzie PAL/NTSC,
;a maksymalna wynosi 65535. Im mniejsza wartość, tym większa częstotliwość odtwarzania sampla.
;Maksymalna szybkość odtwarzania sampla przez jednoskę DMA, wynosi 28867 próbek (bajtów) na sekundę.

;Aby obliczyć prawidłową liczbę cykli opóźnienia CX dla uzyskania dowolnej częstotliwości odtwarzania,
;należy dokonać następujących obliczeń: CX = cc/(f*sn), gdzie: cc - stała zależna od standardu pracy
;Amigi: 3546895 (PAL); 3579545 (NTSC), f - zakładana częstotliwość odtwarzania [Hz], sn - liczba
;próbek (bajtów) w samplu.

;Włączenie odtwarzania sampla
        move.w   #$8203,$96(A6) ;zapis do rejestru DMACON, ustawienie bitów nr: 15 - SET/CLR,
                                ;9 - DMAEN (włączenie jednostki DMA), 1 - AUD1EN (włączenie kanału 1),
                                ;0 - AUD0EN (włączenie kanału 0).

;Czekanie na naciśnięcie lewego przycisku myszy
Wait:   btst     #6,$BFE001
        bne.s    Wait

;Wyłączenie odtwarzania sampla
        move.w   #$0003,$96(A6) ;zapis do rejestru DMACON, zerowanie bitów nr: 15 - SET/CLR,
                                ;1 - AUD1EN (wyłączenie kanału 1), 0 - AUD0EN (wyłączenie kanału 0).
        rts

;Dane sampla muszą znajdować się pod parzystym adresem (wyrównanie do słowa) w pamięci CHIP,
;aby jednostka DMA miała do nich dostęp.

;Każdy bajt to 8-bitowa próbka, określająca amplitudę (poziom) sygnału generowanego na wyjściu audio
;w danym momencie odtwarzania sampla. Amplituda każdej próbki zawiera się w zakresie od -128 do +127,
;co przy ustawionej maksymalnej głośności odtwarzania (64), zapewnia uzyskanie napięcia od -0.4 do +0.4V
;na wyjściu audio.

 SECTION data,DATA_C

Wave:   dc.b     0,90,127,90,0,-90,-127,-90 ;sinus
        dc.b     127,127,127,127,-127,-127,-127,-127 ;prostokąt


Ostatnia aktualizacja: 06.12.2018 13:06:01 przez RomanWorkshop
[#12] Re: Generowanie dźwięku/tonu w asemblerze

@RomanWorkshop, post #11

Sprawdziłem, czy parametry dźwięku generowanego przez powyższy kod na mojej Amidze 600 (rev 1.5, PAL), zgadzają się z dokumentacją. Przy odtwarzaniu 8-bajtowego sampla (sinusoida) i wartościach rejestrów: AUDxPER=443, AUDxVOL=64, sygnał wyjściowy miał częstotliwość 1000 Hz oraz napięcie przemienne (AC) 225 mV. Po zmianie wartości rejestru na AUDxPER=123, sygnał wyjściowy miał częstotliwość 3605 Hz. Jest to zgodne z dokumentacją, która mówi o maksymalnej szybkości odtwarzania sampla przez jednostkę DMA, wynoszącej 28867 próbek (bajtów) na sekundę (3605 Hz * 8 próbek = 28840 próbek na sekundę). Dziękuję za uwagę.
[#13] Re: Generowanie dźwięku/tonu w asemblerze

@RomanWorkshop, post #12

Dziękuję za uwagę.


:) no ja czytam uważnie.

Kiedyś miałem chęć zaprogramowania na Amidze generatora akustycznego. Doszedłem do tego że Amiga już ładnie piszczała sinusem. Korzystałem z książki "Asembler Amiga 500-4000" - o ile nie przekręciłem nazwy, nie mam pod ręką żeby sprawdzić. W każdym razie na tym poprzestałem z jakichś tam powodów. Genarotor miał mieć interfejs przypominający stary analogowy generator zbudowany na lampach produkcji polskiej. Głównym feature miało być pokaźnych rozmiarów pokrętło, aluminum metal panel i wskaźnik aktualnie generowanej częstotliwości. Wskaźnik miał być cyfrowy, reprezentowany graficznie jako ledowe wskaźniki numeryczne - wygląd zbliżony do cyfr na wskaźniku zegarka z wyświetlaczem ciekło-krystalicznym.
[#14] Re: Generowanie dźwięku/tonu w asemblerze

@ede, post #13

:) no ja czytam uważnie.
Chociaż jeden ;)

Dawniej (lata 90) możliwości Amigi były wystarczające do pracy jako generator obrazu i dźwięku (była używana w serwisach RTV, rozbudowane Amigi również w stacjach TV). Taki program na pewno cieszył by się popularnością. Dzisiaj masowo produkowany sprzęt (czy nawet "glut" na płytce) ma dużo większe możliwości i lepsze parametry.

Tak, czy inaczej liczy się dobry pomysł, bo to połowa sukcesu ;) Wspomniana książka nazywa się "Kurs asemblera dla początkujących - Amiga 500-4000".
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem