@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:
@Don_Adan, post #81
;
; 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 @Don_Adan, post #93
@Krashan, post #94
@Don_Adan, post #95
; 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
@Krashan, post #1
@Ponki1986, post #97
@Ponki1986, post #98
@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
powstający program QoaPlay
@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ć oscyloskopemNarzę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.
@Krashan, post #101
czy można w nim coś ulepszyć pod kątem obserwacji oscyloskopowej.Cytuj
@Krashan, post #104
@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.
Najlepiej zrobić do wyboru.
Wtedy szkoda czasu na inny kod
ze taki player ma dzialac na minimum 68020/68030 25 MHz.
@snifferman, post #106
@Don_Adan, post #107
Dlatego testowe probki
@Krashan, post #5
@koczis, post #110
@Krashan, post #111
@Krashan, post #112
@Krashan, post #111
po prostu brak chęci do programowania
@kiero, post #113
To chyba używa po prostu niedeterministycznego generatora wartości losowych.To używa Math.random() z JavaScript, nie masz kontroli nad seedem, zakładam, że kolejne wywołania programu dają inne sekwencje pseudolosowe. Funkcja next_solution() generuje kolejny zestaw parametrów enkodera do przetestowania przy poszukiwaniu najlepszego zestawu. I tam masz właśnie Math.random().