[#91] Re: Quite OK Audio

@alt_, post #85

Tryb 14-bitowy ma tę wadę, że jest cichy...
To wynika z AHI i liczby ustawionych w nim "kanałów", jeżeli używamy Paulę w trybie 14-bitowym poprzez ten system. Gdy nie mamy AHI to sytuacja jest taka:
  • W trybie 8-bitowym używane są dwa kanały Pauli z głośnością 64.
  • W trybie 14-bitowym używane są dwa kanały Pauli z głośnością 64 i dwa z głośnością 1.
Gdy odgrywam ten sam plik programem Play16 w trybie Paula8 albo Paula14, nie ma różnicy w głośności. Tak samo będzie w moim playerze.
[#92] Re: Quite OK Audio

@Hexmage960, post #90

SongPlayer 1.53 działa bez AHI
[#93] Re: Quite OK Audio

@Don_Adan, post #81

Byl blad.
Nie zamienilem d1 na a5. a przeciez D1.l mialo byc wolne :)
MOVEA.W d1,a4
Ale teraz kod jest o nastepne 2 bajty krotszy, bo d6 jest ustawiane w hist1.
Ale to trzebaby jeszcze sprawdzic, czy czegos gdzies nie pominalem.
Wydaje mi sie ze jest juz ok.

;
; QOA decoder

;==============================================================================
; STEREO DECODING STRATEGY
;
; Stereo QOA files have interleaved slices in LR order. Decoding them in order
; means LMS state has to be swapped for each slice. To avoid this, there are 
; two passes over a frame. The first pass loads L channel LMS state then
; decodes only even slices and stores audio samples at output buffer offset 0,
; advancing 4 bytes after each sample. The second pass loads R channel LMS
; state, then decodes only odd slices and stores audio samples at output buffer
; offset 2, advancing 4 bytes after each sample.
;==============================================================================

;==============================================================================
; Decodes QOA mono frame to a buffer.
; INPUTS:
;   d0 - number of slices available in the frame buffer (1 to 256 including)
;   a0 - frame buffer
;   a1 - output buffer
;==============================================================================

		XDEF    _DecodeMonoFrame

_DecodeMonoFrame:
		MOVEM.L d2-d7/a2-a6,-(sp)
		SUBQ.L  #1,d0
		MOVE.W  d0,d7                  ; slice counter
		BSR.S   loadlms
 clr.w (a5)
nextslice:	SWAP    d7
		BSR.S   slice                  ; decode slice
		SWAP    d7
		DBF     d7,nextslice
		MOVEM.L (sp)+,d2-d7/a2-a6
		RTS

;==============================================================================
; Decodes QOA stereo frame to a buffer.
; INPUTS:
;   d0.w - number of slices per channel available in the frame buffer (1 to 256
;          including)
;   a0.l - frame buffer
;   a1.l - output buffer
;==============================================================================

		XDEF    _DecodeStereoFrame

_DecodeStereoFrame:
		MOVEM.L d2-d7/a2-a6,-(sp)
		SUBQ.L  #1,d0
		MOVE.L  a0,-(sp)
		MOVE.L  a1,-(sp)
		MOVE.W  d0,-(sp)

		; L channel pass

		MOVE.W  d0,d7                  ; slice counter
		BSR.S   loadlms
 move.w #2,(a5)
		LEA     16(a0),a0              ; skip R channel LMS state
nextleft:	SWAP    d7
		BSR.S   slice                  ; decode slice
		SWAP    d7
		ADDQ.L  #8,a0                  ; skip R channel slice
		DBF     d7,nextleft

		; R channel pass

		MOVE.W  (sp)+,d7               ; slice counter
		MOVEA.L (sp)+,a1               ; output buffer
		MOVEA.L (sp)+,a0               ; input buffer
		ADDQ.L  #2,a1                  ; R channel samples
		LEA     16(a0),a0              ; skip L channel LMS state
		BSR.S   loadlms
nextright:	ADDQ.l   #8,a0                  ; skip L channel slice
		SWAP    d7
		BSR.S   slice                  ; decode slice
		SWAP    d7
		DBF     d7,nextright

		MOVEM.L (sp)+,d2-d7/a2-a6
		RTS


loadlms:	MOVEA.W (a0)+,a2               ; loading LMS history
		MOVEA.W (a0)+,a3
;		MOVEA.W (a0)+,a4
 move.w (A0)+,D6
move.w  (a0)+,d5
		MOVE.L  (a0)+,d2               ; loading LMS weights
		MOVE.L  (a0)+,d3
 lea     sampoff(pc),a5
		RTS

;==============================================================================
; Decodes QOA slice of mono/stereo stream.
; Registers usage:
;   d0   - slice
;   d2,d3 - LMS weights (updated)
;   d4 - residual sample, quantized, dequantized, scaled
;   d5 - predicted sample
;   d6 - scratch register
;   d7 - not used (slice loop counter)
;   a0 - not used (input data pointer)
;   a1 - output data pointer (advanced)
;   a2,a3,a4,d1 - LMS history (updated)
;   a6 - pointer to 'dequant' lookup table (modified)
;==============================================================================

slice:		MOVE.L  (a0)+,d0
		LEA     dequant(pc),a6
		ROL.L   #8,d0
		MOVE.B  d0,d4
		ANDI.W  #$00F0,d4              ; scale factor in bits 7:4 of d4
		ADDA.W  d4,a6                  ; select lookup table row

		;extract 9 residuals from d0, r[0] is in position already

		MOVE.W  #8,d7              ; can't MOVEQ, upper half in use
		BSR.S   DecSamp

		; now the first bit of r[9] is in d0:0, pull two bits from d1
	
 moveq #1,D4
 and.b D0,D4
 move.l (A0)+,D0
 add.l D0,D0
 addx.b D4,D4
 add.l D0,D0
 addx.b D4,D4
 add.b D4,D4
 clr.w D7
 bsr.b OnlyOnce
 rol.l #4,D0 

		; extract 10 residuals from d0

		MOVE.W  #9,d7
		BRA.S   DecSamp            ; (ab)use RTS at end of DecSamp

;==============================================================================
; Decodes a single sample. 3-bit encoded sample is in bits 3:1 of register d4
;==============================================================================

DecLoop:	ROL.L   #3,d0

		; decode residual sample using lookup table, store in d4

DecSamp:	MOVEQ   #$E,d4
		AND.W   d0,d4                ; extract encoded sample in d4
OnlyOnce:
move.w (a6,d4.w),a5         ; decode with lookup table

		; calculate predicted sample, store in d5

move.w d5,d4                  ; history[-1]
		MULS.W  d3,d5                  ; *= weights[-1]
		SWAP    d3
;		MOVE.W  a4,d6                  ; history[-2]
		MULS.W  d3,d6                  ; *= weights[-2]
		ADD.L   d6,d5
		MOVE.W  a3,d6                  ; history[-3]
		MULS.W  d2,d6                  ; *= weights[-3]
		ADD.L   d6,d5
		SWAP    d2
		MOVE.W  a2,d6                  ; history[-4]
		MULS.W  d2,d6                  ; *= weights[-4]
		ADD.L   d6,d5
		ASR.L   #6,d5
		ASR.L   #7,d5                  ; predicted sample in d5

		; add predicted sample to reconstructed residual with clamp to
		; 16-bit signed range, store in d5

 add.l  a5,d5
 move.w d4,d6
 move.l a5,d4

		MOVEA.W d5,a5              ; with sign-extend to 32 bits
		CMP.L   a5,d5
		BEQ.S   clamped
		SGT     d5                 ; ??FF positive, ??00 negative
		EXT.W   d5                 ; FFFF positive, 0000 negative
		EORI.W  #$8000,d5          ; 7FFF positive, 8000 negative

		; update LMS weights, reconstructed sample in d5, decoded
		; residual in d4

clamped:	ASR.W   #4,d4                  ; scale residual signal down

 move.w d6,a5

		SUB.W   d4,d2
		MOVE.W  a2,d6
		BMI.S   hist3
		ADD.W   d4,d2
		ADD.W   d4,d2

hist3:		SWAP    d2
		SUB.W   d4,d2
		MOVE.W  a3,d6
		BMI.S   hist2
		ADD.W   d4,d2
		ADD.W   d4,d2

hist2:		SUB.W   d4,d3
		MOVE.W  a4,d6
		BMI.S   hist1
		ADD.W   d4,d3
		ADD.W   d4,d3

hist1:		SWAP    d3
		SUB.W   d4,d3
move.w  a5,d6
		BMI.S   update
		ADD.W   d4,d3
		ADD.W   d4,d3

		; update history vector

update: 
 move.w d5,(a1)+
    	MOVEA.W a3,a2
		MOVEA.W a4,a3
;		MOVEA.W d1,a4
 move.w a5,a4
; 	   MOVE.W d5,d1 wywalone
		; store output sample

;		MOVE.W  d5,(a1)+
		ADDA.W  sampoff(pc),a1
		DBF     d7,DecLoop
		RTS

; not very effective, should be stored in some register once registers
; usage is optimized

sampoff:	DC.W    0

dequant:	DC.W       1,    -1,    3,    -3,    5,    -5,     7,     -7
		DC.W       5,    -5,   18,   -18,   32,   -32,    49,    -49
		DC.W      16,   -16,   53,   -53,   95,   -95,   147,   -147
		DC.W      34,   -34,  113,  -113,  203,  -203,   315,   -315
		DC.W      63,   -63,  210,  -210,  378,  -378,   588,   -588
		DC.W     104,  -104,  345,  -345,  621,  -621,   966,   -966
		DC.W     158,  -158,  528,  -528,  950,  -950,  1477,  -1477
		DC.W     228,  -228,  760,  -760, 1368, -1368,  2128,  -2128
		DC.W     316,  -316, 1053, -1053, 1895, -1895,  2947,  -2947
		DC.W     422,  -422, 1405, -1405, 2529, -2529,  3934,  -3934
		DC.W     548,  -548, 1828, -1828, 3290, -3290,  5117,  -5117
		DC.W     696,  -696, 2320, -2320, 4176, -4176,  6496,  -6496
		DC.W     868,  -868, 2893, -2893, 5207, -5207,  8099,  -8099
		DC.W    1064, -1064, 3548, -3548, 6386, -6386,  9933,  -9933
		DC.W    1286, -1286, 4288, -4288, 7718, -7718, 12005, -12005
		DC.W    1536, -1536, 5120, -5120, 9216, -9216, 14336, -14336
2
[#94] Re: Quite OK Audio

@Don_Adan, post #93

Ja to sobie na spokojnie przeanalizuję, bo może samo w sobie zwolnienie D1 nie jest jakoś bardzo istotne... Ale! Możnaby wtedy w D1 trzymać to, co teraz jest w 'sampoff'. Wtedy licząc 68000 zaoszczędzamy 8 cykli na sampla. Na 020 też może być tłusto, bo z pamięci zawsze wolniej niż z rejestru.
2
[#95] Re: Quite OK Audio

@Krashan, post #94

Tak, o tym nie pomyslalem, a to lepsze niz wywalenie swap D7.

Na 68020 bedzie wiecej, bo ext.l odpada czyli 2c zamiast 4c.
O ile o czyms nie zapomnialem.

I jakby dzialalo to mozna chyba wtedy uzyc highword counter, powinno byc wtedy szybciej na 68020, 2xswap+dbf vs sub.l+bxx.

Ostatnia aktualizacja: 09.05.2025 23:34:04 przez Don_Adan
1
[#96] Re: Quite OK Audio

@Don_Adan, post #95

A jak zrobisz tak to zyskasz jeszcze pare bajtow i cykli.
Tylko trzeba odpowiednio ustawic/zamienic D1 i D7 wczesniej.

; store output sample

		MOVE.W  d5,(a1)+
;		ADDA.W  sampoff(pc),a1
:		DBF     d7,DecLoop

 add.w D7,A1
 dbf D1,DecLoop
		RTS

; not very effective, should be stored in some register once registers
; usage is optimized

;sampoff:	DC.W    0


Ostatnia aktualizacja: 10.05.2025 06:59:37 przez Don_Adan
1
[#97] Re: Quite OK Audio

@Krashan, post #1

Hej. Tak z ciekawości zassałem paczkę z przykładowymi utworami w tym formacie i omawiany tutaj program. O dziwo udało mi się odtworzyć utwór w czasie rzeczywistym. Wpisałem w CLI:

QOAtoAIFF FROM utwór.qoa TO AUDIO:

W ustawieniach AHI mam sterownik UAE 44KHz więc nie dziwię się, że to zadziałało. Tak sobie teraz myślę, że gdyby program posiadał opcje ustalenia częstotliwości wyjściowej dla pliku AIFF to każdy mógł by dostosować ją do swoich ustawień w systemie aby odtwarzać plik w czasie rzeczywistym. Bo jeżeli ktoś nie posiada żadnej karty dźwiękowej to pozostaje tylko Paula, a ta natomiast choćby w PALu nie odtworzy 44KHz.
[#98] Re: Quite OK Audio

@Ponki1986, post #97

Zmieniłem w ustawieniach AHI wszystkie opcje na Paula 8 bit mono 11KHz i wszystko brzmi poprawnie, a sądziłem że odtwarzanie będzie spowolnione. Teraz pytanie czy AHI w wersji 6, które mam w systemie posiada jakąś wewnętrzną procedurę dekodowania AIFF na strumień zgodny z zastosowanymi ustawieniami? Próbowałem podobnie zrobić z programem OPUSDec aby odtworzyć w czasie rzeczywistym plik Opus Audio, ale ten dekoduje do WAV lub PCM I nie można odwrócić bitów (Big/Little Endian) co skutkuje usłyszeniem tylko szumów, trzasków.
[#99] Re: Quite OK Audio

@Ponki1986, post #98

QoaToAiff jest konwerterem formatu, więc nie planuję opcji zmiany częstotliwości próbkowania, od tego są inne programy. Natomiast powstający program QoaPlay to co innego, w nim postaram się wykrywać do ilu kHz Paula może odtwarzać i wypuszczać co drugą próbkę, jeżeli 44 kHz nie jest możliwe.

Natomiast AHI załatwia to automagicznie i owszem, ma wbudowany resampling, nie tylko w wersji 6, ale nawet 4.

Ostatnia aktualizacja: 15.05.2025 22:57:54 przez Krashan
[#100] Re: Quite OK Audio

@Krashan, post #99

w nim postaram się wykrywać do ilu kHz Paula może odtwarzać i wypuszczać co drugą próbkę, jeżeli 44 kHz nie jest możliwe


Czy nie jest tak, że na AGA da się wycisnąć z Pauli więcej niż na ECS/OCS zmieniając tryb graficzny z większym odświeżaniem? Nie wiem jaka by była użyteczność takiego rozwiązania, ale taka możliwość istnieje. Podobno da się wycisnąć 54/56KHz.

powstający program QoaPlay

No i druga sprawa nie wiem czy związana z tym tematem, to tryb "14 bitowy". Jeśli taki miałby być obsługiwany, to przydałoby się jakieś narzędzie do kalibracji. Może nawet pro, gdzie dałoby się pomierzyć oscyloskopem, bo takie kieszonkowe poradzą sobie już spokojnie z pasmem audio. To będzie kosztowało dodatkowe cykle CPU no i twój czas. Nie żebym ci dokładał roboty. To tylko takie luźne pomysły.
[#101] Re: Quite OK Audio

@snifferman, post #100

Czy nie jest tak, że na AGA da się wycisnąć z Pauli więcej niż na ECS/OCS zmieniając tryb graficzny z większym odświeżaniem?
Jest tak, nawet na ECS jest tak, o ile ktoś używa tych trybów (ECS zapewnia chyba tylko 4 kolory wtedy, więc słabo). AHI wykrywa i obsługuje to automatycznie, bez niego trzeba to sprawdzić samodzielnie.
Jeśli taki miałby być obsługiwany, to przydałoby się jakieś narzędzie do kalibracji. Może nawet pro, gdzie dałoby się pomierzyć oscyloskopem
Narzędzie do kalibracji przecież jest. Ono umieszcza tablicę kalibracji w określonym formacie i znanej lokalizacji, więc też mogę sobie go załadować i użyć. O ile AHI nie jest w robocie, bo tryby "Paula 14-bit calibrated" robią to same. Co do pomiaru oscyloskopem, to ciekawy temat, trzebaby najpierw zobaczyć jak to wygląda przy standardowym kalibratorze i czy można w nim coś ulepszyć pod kątem obserwacji oscyloskopowej.
1
[#102] Re: Quite OK Audio

@Krashan, post #99

A to nie lepiej zrobic QoaPlay22k, i brac srednia z 2 kolejnych probek zamiast pomijac co druga probke?
Wedlug mnie jakosc bedzie duzo lepsza a to tylko 1 add i 1 asr wiecej, byc moze move tez, zalezy od koncepcji.
[#103] Re: Quite OK Audio

@Krashan, post #101

czy można w nim coś ulepszyć pod kątem obserwacji oscyloskopowej.Cytuj


Musiałbym sprawdzić jak działa ten kalibrator na słuch, ale mój słuch już nie taki jak kiedyś a oscyloskopy coraz lepsze i tańsze. Trochę ironia, że mogę sobie to dzisiaj idealnie pomierzyć, ale nie wiem czy to usłyszę, chociaż przy MP3 słyszę różnicę 128kbit vs 320kbit. Na Pauli kalibratora jeszcze nie testowałem.
[#104] Re: Quite OK Audio

@Don_Adan, post #102

A to nie lepiej zrobic QoaPlay22k, i brac srednia z 2 kolejnych probek zamiast pomijac co druga probke?
Najlepiej zrobić do wyboru. A nawet można dodać jeszcze jakiś bardziej serio filtr. Jak ktoś ma 040 i lepiej.
2
[#105] Re: Quite OK Audio

@Krashan, post #104

Ja to juz stary jestem i nie mam za dobrego sluchu.
Ale zakladajac, ze znajda sie chetni z dobrym sluchem do testowania/sluchania.
To mozesz stworzyc paczke w ktorej bedzie utwor lub utwory w 44kHz (wzorzec).
I 3 wersje 22kHz do sluchania jako IFF.
Bo byc moze ktoras wersja bedzie na tyle dobra lub slaba, ze wybor bylby prosty, tego co powinno byc default.
Wtedy szkoda czasu na inny kod, zakladajac, ze taki player ma dzialac na minimum 68020/68030 25 MHz.
[#106] Re: Quite OK Audio

@Don_Adan, post #105

Ja to juz stary jestem i nie mam za dobrego sluchu.

To mozesz stworzyc paczke w ktorej bedzie utwor lub utwory w 44kHz (wzorzec).
I 3 wersje 22kHz do sluchania jako IFF.


Ja jeszcze za starca się nie uważam, ale słuch jeszcze w miarę no i każdy swój i gust też. Jednemu mogą się spodobać jedne zniekształcenia i filtry a drugiego będą irytować. Wzorzec też może akurat być korzystny dla jednego algorytmu a przy innym utworze może się już nie sprawdzić. No i jak to mierzyć i oceniać? Ustawimy stolik z 10 osobami i słuchawkami i damy tabliczki 0-10? Może to byłoby przydatne?






Najlepiej zrobić do wyboru.

To jest chyba najlepszy pomysł. I dodatkowo w postaci osobnej biblioteki/pliku, ale nie wiem czy to nie spowolni odtwarzania vs filtr zaszyty w samym playerze. Wtedy....

Wtedy szkoda czasu na inny kod


Może ktoś inny zmarnuje czas, gdy zostawi się otwartą furtkę.

ze taki player ma dzialac na minimum 68020/68030 25 MHz.

Mam kilka kart 030 50Mhz i w nich dostęp do pamięci ma wpływ na wydajność. Jedna karta ma 9Mips a druga 11.98Mips w sysinfo. Nie wiem jak jest w kartach z niższym taktowaniem. Podejrzewam, że wtedy pamięć się wyrabia i CPU nie musi czekać.
[#107] Re: Quite OK Audio

@snifferman, post #106

Dlatego testowe probki powinny byc nieopisane, zeby nic nie sugerowac testujacemu.
Wiec zamast nazw probek typu : srednie, parzyste, nieparzyste, mozna uzyc v1,v2,v3.
Jak 9 na 10 testujacych wybierze np. probke v3, to raczej nie ma sensu robic playera dla wersji v1 i v2.
Choc oczywiscie mozna.
[#108] Re: Quite OK Audio

@Don_Adan, post #107

Dlatego testowe probki

Testowe próbki trzeba wygenerować, czyli przepuścic przez filtr/algorytm. Jak już go masz to zamiast go wycinać, to może sobie być jako opcja. Najwyżej nikt jej nie użyje. Jakieś bardziej zaawansowane algorytmy mogą zjeść czas CPU, który został zaoszczędzony optymalizacją dekodera. Te 3 proste, które wymieniłeś nie będą chyba dużo kosztować to by na początek starczyły. Będzie fajnie jak na 030/50MHz będzie działać w 14bit 44Khz.
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