Fast AY music players?
- PROSM
- Manic Miner
- Posts: 477
- Joined: Fri Nov 17, 2017 7:18 pm
- Location: Sunderland, England
- Contact:
Fast AY music players?
I'm in need of a very fast AY music playback routine for a program I'm writing. I haven't really dabbled in 128k hardware before, so the only player I'm familiar with is the PT3 player by Sergey Bulba. My budget is about 5000 T-states max. I'd prefer it if I were able to loop the song from a certain point, not just the beginning, and also be able to fade out the channels (probably asking too much for the T-states I have ). These features aren't essential, but they'd be nice to have.
Can anybody suggest me a good player?
EDIT: Clarified point about preferences.
Can anybody suggest me a good player?
EDIT: Clarified point about preferences.
All software to-date
Working on something, as always.
Working on something, as always.
Re: Fast AY music players?
There are fast players, but for unpacked PSG files.
Packer / Player Features:
+ high playback speed: average speed of approximately 650 measures,
peak 1089 measures (not including looping music). For instance
the used Vortex Tracker player has an average speed of 5K,
peak around 10K when changing patterns.
+ there is a player option aligned for 4 measures (for use with
multicolor and border effects) with a speed of 1329 measures.
The downside is the very large size of the unpacked music file.
But then the speed is very high.
You have to choose - either-or
Packer / Player Features:
+ high playback speed: average speed of approximately 650 measures,
peak 1089 measures (not including looping music). For instance
the used Vortex Tracker player has an average speed of 5K,
peak around 10K when changing patterns.
+ there is a player option aligned for 4 measures (for use with
multicolor and border effects) with a speed of 1329 measures.
The downside is the very large size of the unpacked music file.
But then the speed is very high.
You have to choose - either-or
-
- Manic Miner
- Posts: 401
- Joined: Fri Jan 03, 2020 10:00 am
Re: Fast AY music players?
The default PT3 player (playFAS5.H) fits in 5000 t-states. You don't need to make a register stream.
ALASM peculiarities:
IF0 ?label means ifdef label
IFN ?label means ifndef label
IFN ?macro-2 means if macro was not yet defined
\0,\1 - macro parameters
DD 12345678 equals to DB 0x12,0x34,0x56,0x78
LD A,(DE),L,A equals to
LD A,(DE)
LD L,A
ALASM peculiarities:
IF0 ?label means ifdef label
IFN ?label means ifndef label
IFN ?macro-2 means if macro was not yet defined
\0,\1 - macro parameters
DD 12345678 equals to DB 0x12,0x34,0x56,0x78
LD A,(DE),L,A equals to
LD A,(DE)
LD L,A
Code: Select all
;fast(long) player,can be INCLUDEd
;#E21 3.31 by Nick/GDC Воронеж'97
;#D86 3.51 fix Mm<M,MOnS+eR Самара 26xii00
;#C03 3.695 fix AlCo 1vi01-26xi05
;#C11 3.699 fix AlCo (3xxx chnA/B when old 3xxx ends только что)
IFN ?frq
frq=1;all freq tables(3.4x)
ENDIF
IFN ?msx
msx=0
ENDIF
IFN ?smpfix
smpfix=1;vol,T,E/N cumulations in SMPs
ENDIF
IFN ?port3
port3=1;tone port.
ENDIF
IFN ?vib6
vib6=1;vibrate
ENDIF
IFN ?ts2
ts2=0;2nd TS player;играет пат47 вместо пат0 и т.д.
ENDIF
IFN ?jp-2
MACRO jp
JR \0 ;JP
ENDM
ENDIF
IFN ?m4-2
MACRO m4
SLA L,L
ENDM
ENDIF
IFN ?shut-2
MACRO shut
;LD HL,#E
IFN msx
LD BC,#A0
ELSE
LD BC,-3
ENDIF
DEC L
OUT (C),L
IFN msx
LD C,#A1
ELSE
LD B,#BF
ENDIF
OUT (C),A;0/255
JR NZ,$-10
ENDM
ENDIF
IFN ?esld-2
MACRO esld
Eef_sld LD A,(DE)
INC DE
LD (Esl_ist+1),A
LD A,(DE),L,A
INC DE
LD A,(DE),H,A
INC DE
LD (Esl_ids+1),HL
LD A,6,(E_ins0),A
RET
ENDM
ENDIF
IFN ?l-2
MACRO l
LD A,(DE)
INC DE
LD (\0),A
RET
ENDM
ENDIF
IF0 $-#8000
StAnDaLoNe
ORG #C000
begin
ENDIF
compile
LD HL,module
JR install
JP play
IFN frq
JR stop
ENDIF
install
DI
LD (sav_SP0+1),SP
LD (ia_pos0+1),HL
IFN frq
PUSH HL
LD DE,100
ADD HL,DE
PUSH DE
PUSH HL
DEC HL
LD E,(HL)
LD HL,NT_DATA
LD BC,T_
ADD HL,DE
ADD HL,DE
ADD HL,DE
LD E,(HL)
CALL MAKEfrq
POP HL
POP DE
POP BC
ELSE
LD B,H,C,L
LD DE,100
ADD HL,DE
ENDIF
LD A,(HL)
INC HL
LD (temp+1),A
LD SP,HL
ADD HL,DE
LD (Psa_beg+1),HL
POP AF
LD E,A
ADD HL,DE
LD (Psa_lop+1),HL
POP HL
ADD HL,BC
LD (Psa_chn+1),HL
LD HL,tba_smp
ia_s0 EX DE,HL
POP HL
ADD HL,BC
EX DE,HL
LD (HL),E
INC L
LD (HL),D
INC L
JR NZ,ia_s0
INC L
LD H,L
LD (A_qty),HL
LD (C_qty),HL
sav_SP0 LD SP,0
stop
LD HL,DUMMYORN
LD (Ao_adr+1),HL
LD (Bo_adr+1),HL
LD (Co_adr+1),HL
LD (Asi_adr+1),HL
LD (Bsi_adr+1),HL
LD (Cs_adr+1),HL
LD (Ach_adr+1),HL
XOR A
LD (Am_vol+1),A
LD (Bm_vol+1),A
LD (Cm_vol+1),A
LD (Ei_form+1),A ;no glu glu after switch module
SUB 16 ;FIX
LD (Agi_vol+1),A
LD (Bgi_vol+1),A
LD (Cg_vol+1),A
SBC A,A
LD (Avb_lok+1),A
LD (Cvb_lok+1),A
LD (Bvb_lok+1),A
XOR A
IF0 frq
NOP
ENDIF
shut
RET
IF0 frq
esld
ENDIF
tba_smp DS 64,0
tba_orn DS 32,0
DISPLAY $
tab_vol
frq_A DB 0,0
frq_B DB 0,0
frq_C DB 0,0
N_frq DB 0 ;;4
DB 0 ;mix ;no_use
vol_A DB 0
vol_B DB 0
vol_C DB 0
frq_E DB 0,0
E_form DB 0 ;;4
DUMMYORN
DUMMYSMP
DS 2
DB 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1
DB 0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2
DB 0,0,0,1,1,1,1,1,2,2,2,2,2,3,3,3
DB 0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4
DB 0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5
DB 0,0,1,1,2,2,2,3,3,4,4,4,5,5,6,6
DB 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7
DB 0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8
DB 0,1,1,2,2,3,4,4,5,5,6,7,7,8,8,9
DD 0001010203030405050607070809090A
DD 000101020304040506070708090A0A0B
DD 0001020203040506060708090A0A0B0C
DD 00010203030405060708090A0A0B0C0D
DD 00010203040506070708090A0B0C0D0E
DD 000102030405060708090A0B0C0D0E0F
tab_frq
DS #C0
IFN ?tabl-2
MACRO tabl
IF0 port3
\0ef_nsT=0
ENDIF
IF0 vib6
\0ef_vib=0
ENDIF
\0_eff DW \0ef_slT ;1/2xxx
DW \0ef_nsT ;3xxx
DW \0ef_dSm ;4.xx
DW \0ef_dOr ;5.xx
DW \0ef_vib ;6.xx
IF0 vib6
DS 4,1
ELSE
\0ef_vib LD A,(DE)
INC DE
JR \0VIB
ENDIF
DW Eef_sld
DW eff_tmp
IFN $-18!$&#FF00
DISPLAY "ERROR \0_eff
ENDIF
IFN vib6
;0ef_vib LD A,(DE)
;INC DE
\0VIB
LD (\0vb_ist+1),A;fix fr/st
IF0 "\0 "-"C "
LD (\0vb_stp+1),A
ENDIF
LD A,(DE)
INC DE
LD (\0vb_ifr+1),A;fix st/fr
IFN "\0 "-"C "
LD A,6,(\0_ins4),A
ENDIF
RET
ENDIF
ENDM
ENDIF
tabl A
tabl B
tabl C
A_qty NOP
B_qty NOP
C_qty NOP
play JP play_0
EXX ;for B'<>1
LD A,#C3,(play),A
;--- install_A ----
XOR A
LD L,A,H,A
LD DE,#618
A_gli LD (Asl_dsp+1),HL
A_ins0 JR A_ins0Q
LD (As_dsp+1),A ;note
IFN smpfix
LD (As_Nsl+1),A
LD (As_Esl+1),A
LD (As_dtn+1),HL
ENDIF
LD (Ao_dsp+1),A ;todo VARIABLE?
LD (Asl_stp+1),A
IFN vib6
LD (Avb_stp+1),A
ENDIF
Avb_cpl CPL
LD (Avb_lok+1),A
IFN port3
LD A,(A_ins3) ;3.699
CP E;24 ;
JZ $+8 ;
LD A,(Api_lok+1) ;
OR A ;
JZ $+7 ;
ENDIF
Asi_not LD A,0
LD (As_note+1),A
Asi_adr LD HL,0
LD (As_adr+1),HL
IFN smpfix
LD A,16
LD (As_Vsl+1),A
ENDIF
A_ins0Q
Agi_vol LD A,0 ;global_volume
avol LD (Ag_vol+1),A
A_ins2 JR A_ins2Q
XOR A ;ornament
LD (Ao_dsp+1),A
Aoi_adr LD HL,0
LD (Ao_adr+1),HL
Ami_vol LD A,0
LD (Am_vol+1),A
A_ins2Q
A_ins3 JR A_ins3Q
;port & sld
Api_stp LD A,0
LD (Asl_stp+1),A
LD (Asl_sts+1),A
Api_tfr LD HL,0
LD (Asl_tfr+1),HL
IFN port3
Api_not LD A,0
LD (Asl_not+1),A
Api_lok LD A,0
LD (Asl_plk-1),A
ENDIF
IFN vib6
XOR A
LD (Avb_stp+1),A
ENDIF
A_ins3Q
IFN vib6
A_ins4 JR A_ins4Q
LD A,E;24 ;vib
LD (A_ins4),A
Avb_ist LD A,0
LD (Avb_sts+1),A
LD (Avb_stp+1),A
Avb_ifr LD A,0
LD (Avb_frq+1),A
A_ins4Q
ENDIF
A_ins5 JR A_ins5Q
Asi_dsp LD A,0 ;disp_sample
LD (As_dsp+1),A
LD A,E;24
LD (A_ins5),A
A_ins5Q
A_ins6 JR A_ins6Q
Aoi_dsp LD A,0
LD (Ao_dsp+1),A;disp_ornament
LD A,E;24
LD (A_ins6),A
A_ins6Q
;--- install_B ---
XOR A
LD L,A,H,A
B_gli LD (Bsl_dsp+1),HL
B_ins0 JR B_ins0Q
LD (Bs_dsp+1),A
IFN smpfix
LD (Bs_Nsl+1),A
LD (Bs_Esl+1),A
LD (Bs_dtn+1),HL
ENDIF
LD (Bo_dsp+1),A
LD (Bsl_stp+1),A
IFN vib6
LD (Bvb_stp+1),A
ENDIF
Bvb_cpl CPL
LD (Bvb_lok+1),A
IFN port3
LD A,(B_ins3) ;3.699
CP E;24 ;
JZ $+8 ;
LD A,(Bpi_lok+1) ;
OR A ;
JZ $+7 ;
ENDIF
Bsi_not LD A,0
LD (Bs_note+1),A
Bsi_adr LD HL,0
LD (Bs_adr+1),HL
IFN smpfix
LD A,16
LD (Bs_Vsl+1),A
ENDIF
B_ins0Q
Bgi_vol LD A,0
bvol LD (Bg_vol+1),A
B_ins2 JR B_ins2Q
XOR A
LD (Bo_dsp+1),A
Boi_adr LD HL,0
LD (Bo_adr+1),HL
Bmi_vol LD A,0
LD (Bm_vol+1),A
B_ins2Q
B_ins3 JR B_ins3Q
Bpi_stp LD A,0
LD (Bsl_stp+1),A
LD (Bsl_sts+1),A
Bpi_tfr LD HL,0
LD (Bsl_tfr+1),HL
IFN port3
Bpi_not LD A,0
LD (Bsl_not+1),A
Bpi_lok LD A,0
LD (Bsl_plk-1),A
ENDIF
IFN vib6
XOR A
LD (Bvb_stp+1),A
ENDIF
B_ins3Q
IFN vib6
B_ins4 JR B_ins4Q
LD A,E;24
LD (B_ins4),A
Bvb_ist LD A,0
LD (Bvb_sts+1),A
LD (Bvb_stp+1),A
Bvb_ifr LD A,0
LD (Bvb_frq+1),A
B_ins4Q
ENDIF
B_ins5 JR B_ins5Q
Bsi_dsp LD A,0
LD (Bs_dsp+1),A
LD A,E;24
LD (B_ins5),A
B_ins5Q
B_ins6 JR B_ins6Q
Boi_dsp LD A,0
LD (Bo_dsp+1),A
LD A,E;24
LD (B_ins6),A
B_ins6Q
;--- install_E ---
Ei_form LD A,0 ;env_form
LD (E_form),A ;;4
OR A
JR Z,temp
Ei_frq LD HL,0 ;env_frq
LD (E_frq+1),HL
XOR A
LD L,A,H,A
LD (Ei_form+1),A
LD (Esl_frq+1),HL
LD (Esl_stp+1),A
temp LD A,3,(int_qty+1),A
Ni_frq LD A,0,(N_frq),A ;;4
E_ins0 JR Ei_Q
Esl_ids LD HL,0 ;stp_sld_env
LD (Esl_sds+1),HL
Esl_ist LD A,0 ;stp_sld_p
LD (Esl_stp+1),A
LD (Esl_sts+1),A
LD A,E;24
LD (E_ins0),A
Ei_Q
;--- nota_A + calc next position ---
LD HL,A_qty
DEC (HL)
LD H,E
;LD L,1 ;E
LD B,E
EXX
JR NZ,AqtyQ
;LD (avol+2),A
Ach_adr LD DE,tab_vol+16
LD A,(DE)
OR A
JR NZ,Ps_n0
LD (Ni_frq+1),A ;;5!!!
LD D,A ;;
LD (sav_SP2+1),SP
Psa_beg LD HL,module+201
LD A,(HL)
;LD E,A ;6
INC A ;AAA;6
JR NZ,Ps_n1 ;NC ;6
Psa_lop LD HL,module+201
Ps_n1
IFN ts2
LD A,47*3
SUB (HL)
LD E,A
ELSE
LD E,(HL) ;6
ENDIF
INC HL
LD (Psa_beg+1),HL
Psa_chn LD HL,0
ADD HL,DE
ADD HL,DE
LD SP,HL
POP HL
ia_pos0 LD BC,0
ADD HL,BC
EX DE,HL ;DE=adr_chn_A
POP HL
ADD HL,BC ;HL=adr_chn_B
LD (Bch_adr+1),HL
POP HL
ADD HL,BC ;HL=adr_chn_C
LD (Cch_adr+1),HL
sav_SP2 LD SP,0
Ps_n0
LD H,'compile
CALL An_clc1
LD (Ach_adr+1),DE
Ai_qty LD A,0,(A_qty),A
AqtyQ LD A,1
DJNZ $+4
LD A,34
LD (A_gli),A
EXX
LD A,B,(A_ins2),A
LD A,H,(A_ins0),A
LD A,E,(A_ins3),A
play_0 LD L,0 ;smp_sl_env
EXX
N_add LD IX,0 ;HX=noise LX=mix
LD (sav_SP1+1),SP
IFN ?sam1-2
MACRO sam1
\0vb_lok LD A,-1
LD H,A
INC A
JP Z,\0vb_n0
\0s_adr LD SP,DUMMYSMP ;sample
POP DE ;loop E=beg D=end
\0s_dsp LD A,0
LD L,A
INC A
CP D
JR C,$+3 ;bug NZ/C
LD A,E
LD (\0s_dsp+1),A
m4
ADD HL,SP
LD SP,HL
POP DE ;D= Nm ts ns Tm v3 v2 v1 v0
LD A,D ;E= sv +- N4 N3 N2 N1 N0 Em
IFN smpfix
OR #F0
LD L,A
LD A,E
ADD A,A
\0s_Vsl LD A,16
JR NC,\0s_VslG
JP M,\0s_n2
SUB 1
JR $+4
\0s_n2 CP 31
ADC A,0
LD (\0s_Vsl+1),A
\0s_VslG
ADD A,L
JR C,$+3
XOR A
CP 16
JR C,$+4
LD A,15
ELSE
AND 15
ENDIF
\0g_vol ADD A,#F0
LD L,A,H,'tab_vol
LD A,(HL)
SRL E
JR C,$+4
\0m_vol OR 0
EXA
LD A,D
RLCA
JR C,\0s_n5
IFN smpfix
\0s_Nsl LD A,0
ADD A,E
BIT 5,D
JR Z,$+5
LD (\0s_Nsl+1),A
LD HX,A
ELSE
LD HX,E
ENDIF
jp \0s_n7
\0s_n5 LD A,E
AND 31
CP 16
JR C,$+4
OR #F0
IFN smpfix
\0s_Esl ADD A,0
BIT 5,D
JR Z,$+5
LD (\0s_Esl+1),A
ENDIF
EXX
ADD A,L
LD L,A
EXX
\0s_n7 LD A,D
RRCA
RRCA
AND 36
ENDM
ENDIF
IFN ?sam2-2
MACRO sam2
LD LX,A
IFN smpfix
POP BC
\0s_dtn LD HL,0 ;dsp_frq_smp
ADD HL,BC
BIT 6,D
JR Z,$+5
LD (\0s_dtn+1),HL
EX DE,HL
ELSE
POP DE
ENDIF
\0o_adr LD SP,DUMMYORN ;ornament
POP BC ;loop C=beg B=end
\0o_dsp LD A,0
LD L,A
INC A
CP B
JR C,$+3 ;bug NZ/C
LD A,C
LD (\0o_dsp+1),A
LD H,0
ADD HL,SP
IFN port3
LD A,(\0s_note+1)
ELSE
\0s_note LD A,0
ENDIF
ADD A,(HL) ;dsp_orn
ADD A,A
JR NC,$+3
XOR A
LD L,A,H,'tab_frq
LD SP,HL
POP HL
ADD HL,DE
\0sl_dsp LD BC,0
ADD HL,BC
LD (frq_\0),HL
\0sl_stp LD A,0
DEC A
JP M,\0sl_s0
JR NZ,\0sl_s1
\0sl_tfr LD DE,0
ADD HL,DE
EX DE,HL
ADD HL,BC
LD (\0sl_dsp+1),HL
IFN port3
JR \0sl_sts ;port off/on
\0sl_plk
\0sl_not LD A,0
LD L,A
ADD HL,HL
LD H,'tab_frq
LD SP,HL
POP HL
\0s_note CP 0
JR NC,$+3
EX DE,HL
SBC HL,DE
JR C,\0sl_sts
LD (\0s_note+1),A
XOR A
LD L,A
LD (\0sl_dsp+1),HL
JR $+4
ENDIF
\0sl_sts LD A,0
\0sl_s1 LD (\0sl_stp+1),A
\0sl_s0 EXA
\0vb_n0 LD (vol_\0),A
IFN vib6
\0vb_stp LD A,0
DEC A
JP M,\0smpQ
JR NZ,\0vb_n1
DEC A ;;
LD HL,\0vb_lok+1;;
XOR (HL) ;;
LD (HL),A ;;4
\0vb_frq LD A,0
JR NZ,$+4
\0vb_sts LD A,0
\0vb_n1 LD (\0vb_stp+1),A
ENDIF
\0smpQ
ENDM
ENDIF
sam1 A
RRCA
RRCA
sam2 A
sam1 B
RRCA
OR LX
sam2 B
sam1 C
OR LX
sam2 C
;---- sampler_E ----
Esl_ EXX
LD A,L
Esl_frq LD DE,0 ;stp_sl_env
E_frq LD HL,0 ;frq_env
ADD A,L ;stp_smp_sl_env
LD L,A
ADD HL,DE
LD (frq_E),HL
Esl_stp LD A,0
DEC A
JP M,sav_SP1
JR NZ,E_n0
Esl_sds LD HL,0
ADD HL,DE
LD (Esl_frq+1),HL
Esl_sts LD A,0
E_n0 LD (Esl_stp+1),A
;---- out_to_processor ----
sav_SP1 LD SP,0
out_
IFN msx
LD DE,#A0A1
LD HL,frq_A
DUP 6
LD C,D
OUT (C),L
LD C,E
OUTI
EDUP
LD C,D
OUT (C),L
LD A,HX ;noise
LD (N_add+3),A
ADD A,(HL) ;;4
OUT (#A1),A
INC L
OUT (C),L
LD A,LX ;mix TODO (HL)
AND %00111111
OR %10000000 ;portA=input, portB=output
OUT (#A1),A
INC L
OUT (C),L
LD C,E
OUTI
DUP 4
LD C,D
OUT (C),L
LD C,E
OUTI
EDUP
LD A,(HL) ;;4
OR A
JR Z,int_qty
LD C,D
OUT (C),L
OUT (#A1),A
LD (HL),0 ;;4
ELSE ;zx
LD DE,#FFBF
LD BC,-3
LD HL,frq_A
DUP 6
OUT (C),L
LD B,E
OUTI
LD B,D
EDUP
OUT (C),L
LD A,HX ;noise
LD (N_add+3),A
ADD A,(HL) ;;4
LD B,E
OUT (C),A
INC L
LD B,D
OUT (C),L
LD A,LX ;mix TODO (HL)
LD B,E
OUT (C),A
INC L
DUP 5
LD B,D
OUT (C),L
LD B,E
OUTI
EDUP
LD A,(HL) ;;4
OR A
JR Z,int_qty
LD B,D
OUT (C),L
LD B,E
OUT (C),A
LD (HL),0 ;;4
ENDIF
;--- calc_next_positon_channels ---
int_qty LD A,3
DEC A
LD (int_qty+1),A
JR Z,notaC;if tmp=1,CALL notaB first!!!
DEC A
RET NZ
;--- nota_B ---
LD HL,B_qty
DEC (HL)
LD DE,#618
LD H,E
;LD L,1 ;E
LD B,E
EXX
JR NZ,BqtyQ
;LD (bvol+2),A
Bch_adr LD DE,0
LD H,'compile
CALL Bn_clc1
LD (Bch_adr+1),DE
Bi_qty LD A,0,(B_qty),A
BqtyQ LD A,1
DJNZ $+4
LD A,34
LD (B_gli),A
EXX
LD A,B,(B_ins2),A
LD A,H,(B_ins0),A
;LD A,L,(B_ins1),A
LD A,E,(B_ins3),A
RET
;--- nota_C ---
notaC
INC A;LD A,1
LD (play),A
LD HL,C_qty
DEC (HL)
RET NZ
Cch_adr LD DE,0
LD H,'compile
CALL Cn_clc1
LD (Cch_adr+1),DE
Ci_qty LD A,0,(C_qty),A
DEC B
RET NZ
LD H,B,L,B
LD (Csl_dsp+1),HL
RET
IFN ?not-2
MACRO not
IFN "\0 "-"C "
\0ni_v0 LD A,47
\0nivolU LD (\0vb_cpl),A
EXX
LD H,D
EXX
RET
\0ni_not LD (\0si_not+1),A
XOR A
LD B,1
jp \0nivolU
ENDIF
\0ni_vol JR Z,\0ni_v0
DUP 4
ADD A,A
EDUP
LD (\0gi_vol+1),A
jp \0n_clc2
\0ni_vqe JR Z,\0ni_v1
DEC A
JR NZ,\0ni_e0
LD A,(DE)
INC DE
LD (\0i_qty+1),A
jp \0n_clc2
\0ni_e0 LD (Ei_form+1),A
LD A,(DE)
INC DE
LD (Ei_frq+2),A
LD A,(DE)
INC DE
LD (Ei_frq+1),A
LD A,16
\0ni_v1 LD (\0mi_vol+1),A
IFN "\0 "-"C "
EXX
LD B,D
EXX
ENDIF
jp \0n_clc2
\0ni_s_o ADD A,A
ADD A,tba_orn
LD L,A
LD C,(HL)
INC L
LD B,(HL)
LD (\0oi_adr+1),BC
XOR A
\0ni_sm0 LD (\0mi_vol+1),A
IFN "\0 "-"C "
EXX
LD B,D
EXX
ELSE
XOR A
LD (\0o_dsp+1),A
ENDIF
LD A,(DE)
INC DE
\0nism0U ADD A,tba_smp
LD L,A
LD C,(HL)
INC L
LD B,(HL)
LD (\0si_adr+1),BC
\0n_clc1 LD BC,#1020
\0n_clc2 LD A,(DE)
INC DE
ADD A,B
JR C,\0ni_s_o
ADD A,C
JR C,\0ni_smp
ADD A,B
JR C,\0ni_vol
ADD A,B
JR C,\0ni_vqe
ADD A,96
JR C,\0ni_not
ADD A,B
JR C,\0ni_orn
IF0 "\0 "-"B "
ADD A,C
JR C,\0ni_noi
ADD A,B
ELSE
ADD A,48
ENDIF
JR C,\0ni_vse
RLA
LD HL,-256&\0_eff+.(\0_eff+30)
ADD A,L
LD L,A
LD A,(HL)
INC L
LD H,(HL)
LD L,A
PUSH HL
IF0 "\0 "-"C "
IFN port3
LD A,(Cs_note+1)
LD (CnsTnxt+1),A
ENDIF
ENDIF
jp \0n_clc2
IF0 "\0 "-"B "
\0ni_noi LD (Ni_frq+1),A;global_noise
jp \0n_clc2
ENDIF
\0ni_vse JR Z,\0ni_sm0
LD (Ei_form+1),A
LD A,(DE)
INC DE
LD (Ei_frq+2),A
LD A,(DE)
INC DE
LD (Ei_frq+1),A
LD A,16
jp \0ni_sm0
\0ni_smp RET Z
ADD A,A
jp \0nism0U
\0ni_orn ADD A,A
ADD A,tba_orn
LD L,A
LD C,(HL)
INC L
LD B,(HL)
LD (\0oi_adr+1),BC
IFN "\0 "-"C "
EXX
LD B,D
EXX
ELSE
XOR A
LD (Co_dsp+1),A
ENDIF
jp \0n_clc1
ENDM
ENDIF
not A
not B
Cgi_vol=Cg_vol
Cmi_vol=Cm_vol
Coi_adr=Co_adr
Csi_adr=Cs_adr
Cni_v0
IFN vib6
LD (Cvb_stp+1),A
ENDIF
DEC A
LD (Cvb_lok+1),A
RET
not C
Cni_not LD (Cs_note+1),A
XOR A
LD H,A,L,A
LD (Cs_dsp+1),A
LD (Co_dsp+1),A
LD (Csl_stp+1),A
LD (Cvb_lok+1),A
IFN vib6
LD (Cvb_stp+1),A
ENDIF
IFN smpfix
LD (Cs_Nsl+1),A
LD (Cs_Esl+1),A
LD (Cs_dtn+1),HL
LD A,16,(Cs_Vsl+1),A
ENDIF
LD B,1
RET
;---- special_effects_COM.xxxx ----
Aef_dSm LD A,6,(A_ins5),A
l Asi_dsp+1
Aef_dOr LD A,6,(A_ins6),A
l Aoi_dsp+1
Bef_dSm LD A,6,(B_ins5),A
l Bsi_dsp+1
Bef_dOr LD A,6,(B_ins6),A
l Boi_dsp+1
Cef_dSm l Cs_dsp+1
Cef_dOr l Co_dsp+1
Cpi_stp=Csl_stp
Cpi_tfr=Csl_tfr
IFN ?_slT-2
MACRO _slT
\0ef_slT LD A,(DE)
INC DE
LD (\0pi_stp+1),A
IF0 "\0 "-"C "
LD (\0sl_sts+1),A
ENDIF
LD A,(DE),L,A
INC DE
LD A,(DE),H,A
INC DE
LD (\0pi_tfr+1),HL
IFN port3
LD A,\0sl_sts-\0sl_plk
LD (\0pi_lok+1),A;port_off
ENDIF
ENDM
ENDIF
_slT A
EXX
LD E,D
EXX
RET
_slT B
EXX
LD E,D
EXX
RET
_slT C
IFN vib6
XOR A
LD (Cvb_stp+1),A
ENDIF
RET
IFN port3
IFN ?_nsT-2
MACRO _nsT
\0ef_nsT LD A,(DE)
INC DE
LD (\0pi_stp+1),A
IF0 "\0 "-"C "
LD (\0sl_sts+1),A
ENDIF
INC DE
INC DE
LD A,(DE),L,A
INC DE
LD A,(DE),H,A
INC DE
LD (\0pi_tfr+1),HL
XOR A
LD B,A
ENDM
ENDIF
_nsT A
LD (Api_lok+1),A;port_on
; LD HL,Asi_not+1
; LD A,(HL)
LD A,(Asi_not+1)
LD (Api_not+1),A
;LD A,(As_note+1)
; LD (HL),A
EXX
LD E,D
EXX
RET
_nsT B
LD (Bpi_lok+1),A
; LD HL,Bsi_not+1
; LD A,(HL)
LD A,(Bsi_not+1)
LD (Bpi_not+1),A
;LD A,(Bs_note+1)
; LD (HL),A
EXX
LD E,D
EXX
RET
_nsT C
IFN vib6
LD (Cvb_stp+1),A
ENDIF
LD (Csl_plk-1),A
LD HL,Cs_note+1
LD A,(HL)
LD (Csl_not+1),A
CnsTnxt LD (HL),0
RET
ENDIF
eff_tmp l temp+1
IFN frq
esld
MAKEfrq
;Roshin
INC HL
EX DE,HL
ADD HL,BC
LD A,(DE)
LD (COPF3),A
INC DE
LD A,(DE)
ADD A,C
LD C,A
ADC A,B
SUB C
LD B,A
PUSH BC
LD DE,tab_frq
PUSH DE
LD B,12
COPF1 PUSH BC
LD C,(HL)
INC HL
PUSH HL
LD B,(HL)
PUSH DE
EX DE,HL
LD DE,23
LD HX,8
COPF2 SRL B
RR C
;COPF3 NOP ;AND A
LD A,C
COPF3 ADC A,D ;=ADC 0
LD (HL),A
INC HL
LD A,B
ADC A,D
LD (HL),A
ADD HL,DE
DEC HX
JR NZ,COPF2
POP DE
INC DE,DE
POP HL
INC HL
POP BC
DJNZ COPF1
POP HL
POP DE
;LD A,E
;CP TCOLD_1
;JR NZ,CORR_1
;LD A,#FD,(FrTab+#2E),A
CORR_1 LD A,(DE)
AND A
RET Z
INC DE
RRA
PUSH HL
PUSH AF
ADD A,A
LD C,A
ADD HL,BC
POP AF
INC (HL)
JR NC,$+4
DEC (HL),(HL)
POP HL
;AND A
;SBC HL,BC
JR CORR_1
NT_DATA
DB T_NEW_0-T_
ADC A,D
DB TCNEW_0-T_
;DB T_OLD_0-T_
;AND A
;DB TCOLD_0-T_
DB T_NEW_1-T_
AND A
DB TCNEW_1-T_
;DB T_OLD_1-T_
;AND A
;DB TCOLD_1-T_
DB T_NEW_2-T_
ADC A,D
DB TCNEW_2-T_
;DB T_OLD_2-T_
;NOP
;DB TCOLD_2-T_
DB T_NEW_3-T_
ADC A,D
DB TCNEW_3-T_
;DB T_OLD_3-T_
;NOP
;DB TCOLD_3-T_
T_
;COLD_0 DB #00+1,#04+1,#08+1,#0A+1,#0C+1,#0E+1,#12+1,#14+1
; DB #18+1,#24+1,#3C+1,0
TCNEW_1
TCOLD_1 DB #5C+1,0
;COLD_2 DB #30+1,#36+1,#4C+1,#52+1,#5E+1,#70+1,#82,#8C,#9C
; DB #9E,#A0,#A6,#A8,#AA,#AC,#AE,#AE,0
TCNEW_3 DB #56+1
TCOLD_3 DB #1E+1,#22+1,#24+1,#28+1,#2C+1,#2E+1,#32+1,#BE+1,0
TCNEW_0 DB #1C+1,#20+1,#22+1,#26+1,#2A+1,#2C+1,#30+1,#54+1
DB #BC+1,#BE+1,0
TCNEW_2 DB #1A+1,#20+1,#24+1,#28+1,#2A+1,#3A+1,#4C+1,#5E+1
DB #BA+1,#BC+1,#BE+1,0
;first 12 values of tone tables
T_NEW_1
T_OLD_1 DW #0EF8*2,#0E10*2,#0D60*2,#0C80*2,#0BD8*2,#0B28*2
DW #0A88*2,#09F0*2,#0960*2,#08E0*2,#0858*2,#07E0*2
;_OLD_2 DW #0D3E*2,#0C80*2,#0BCC*2,#0B22*2,#0A82*2,#09EC*2
; DW #095C*2,#08D6*2,#0858*2,#07E0*2,#076E*2,#0704*2
T_NEW_3
T_OLD_3 DW #0CDA*2,#0C22*2,#0B73*2,#0ACF*2,#0A33*2,#09A1*2
DW #0917*2,#0894*2,#0819*2,#07A4*2,#0737*2,#06CF*2
T_OLD_0=T_OLD_3+2
T_NEW_0=T_OLD_3+2
DW #066D*2
T_NEW_2 DW #0D10*2,#0C55*2,#0BA4*2,#0AFC*2,#0A5F*2,#09CA*2
DW #093D*2,#08B8*2,#083B*2,#07C5*2,#0755*2,#06EC*2
ENDIF
DISPLAY $-compile
IFN vib6
Cvb_ifr=Cvb_frq
Cvb_ist=Cvb_sts
ENDIF
IFN port3
Cpi_lok=Csl_plk-2
ENDIF
IF0 ?StAnDaLoNe
module
INCBIN "*.m"
ENDIF
IF0 frq
plyend
ORG tab_frq
IF0 .{module+99}-0
;INCBIN "tb_PT
DD 220C730BCF0A330AA109170994081908A4073707CF066D06
DD 1106BA0567051A05D0048B044A040C04D2039B0367033703
DD 0803DD02B4028D026802460225020602E901CE01B4019B01
DD 84016E015A0146013401230112010301F500E700DA00CE00
DD C200B700AD00A3009A009100890082007A0073006D006700
DD 61005C00560052004D004900450041003D003A0036003300
DD 31002E002B00290027002400220020001F001D001B001A00
DD 180017001600140013001200110010000F000E000D000C00
ENDIF
IF0 .{module+99}-1
;INCBIN "tb_ST
DD F80E100E600D800CD80B280B880AF0096009E0085808E007
DD 7C070807B0064006EC0594054405F804B00470042C04FD03
DD BE03840358032003F602CA02A2027C02580238021602F801
DD DF01C201AC0190017B01650151013E012C011C010A01FC00
DD EF00E100D600C800BD00B200A8009F0096008E0085007E00
DD 770070006B0064005E00590054004F004B00470042003F00
DD 3B003800350032002F002C002A0027002500230021001F00
DD 1D001C001A00190017001600150013001200110010000F00
ENDIF
IF0 .{module+99}-2
;INCBIN "tb_ASM
DD 100D550CA40BFC0A5F0ACA093D09B8083B08C5075507EC06
DD 88062A06D2057E052F05E5049E045C041D04E203AB037603
DD 44031503E902BF02980272024F022E020F02F101D501BB01
DD A2018B01740160014C013901280117010701F900EB00DD00
DD D100C500BA00B000A6009D0094008C0084007C0075006F00
DD 690063005D00580053004E004A00460042003E003B003700
DD 340031002F002C00290027002500230021001F001D001C00
DD 1A00190017001600150014001200110010000F000E000D00
ENDIF
IF0 .{module+99}-3
;INCBIN "tb_REAL
DD DA0C220C730BCF0A330AA109170994081908A4073707CF06
DD 6D061106BA0567051A05D0048B044A040C04D2039B036703
DD 37030803DD02B4028D026802460225020602E901CE01B401
DD 9B0184016E015A0146013401230112010301F500E700DA00
DD CE00C200B700AD00A3009A009100890082007A0073006D00
DD 670061005C00560052004D004900450041003D003A003600
DD 330031002E002B00290027002400220020001F001D001B00
DD 1A00180017001600140013001200110010000F000E000D00
ENDIF
ORG plyend
ENDIF
IF0 ?StAnDaLoNe
end
DISPLAY "module end=",$
ORG #7000
GO CALL compile
play_l EI
HALT
CALL play
LD A,#7F
IN A,(-2)
RRA
JR C,play_l
LD L,#E
XOR A
shut
RET
ObjTab
DB "muzon C"
DW begin
DW end-begin
DB #10
DW begin
INCLUDE "B:SAVEOBJ*",#C4
ENDIF
- PROSM
- Manic Miner
- Posts: 477
- Joined: Fri Nov 17, 2017 7:18 pm
- Location: Sunderland, England
- Contact:
Re: Fast AY music players?
I've experimented with the PT3 player, but it's too slow. It ends up causing flickering. I'm racing the beam with a buffer copy, then drawing sprites directly on top of the freshly copied data, so the more T-states I spend in the music player, the less time I have access to the screen memory before contention timings apply.Alone Coder wrote: ↑Tue Jul 07, 2020 9:35 pm The default PT3 player (playFAS5.H) fits in 5000 t-states. You don't need to make a register stream.
Sounds great, but how can I pack my PT3 files into PSG? I've tried searching it up, but I can't find much.azesmbog wrote: ↑Tue Jul 07, 2020 7:15 pm There are fast players, but for unpacked PSG files.
Packer / Player Features:
+ high playback speed: average speed of approximately 650 measures,
peak 1089 measures (not including looping music). For instance
the used Vortex Tracker player has an average speed of 5K,
peak around 10K when changing patterns.
+ there is a player option aligned for 4 measures (for use with
multicolor and border effects) with a speed of 1329 measures.
The downside is the very large size of the unpacked music file.
But then the speed is very high.
You have to choose - either-or
All software to-date
Working on something, as always.
Working on something, as always.
Re: Fast AY music players?
The psg format itself is not packed. It's a recording of the stream of AY register values every vblank.
Most AY formats can be converted to psg with AYEmul (right-click on tune in playlist).
I know of a psg packer but don't know know which format azesmbog is referring to. .ym possibly? Although I don't actually know if it's fast.
Most AY formats can be converted to psg with AYEmul (right-click on tune in playlist).
I know of a psg packer but don't know know which format azesmbog is referring to. .ym possibly? Although I don't actually know if it's fast.
-
- Microbot
- Posts: 148
- Joined: Fri Nov 24, 2017 5:09 pm
- Location: Syracuse, NY, USA
- Contact:
Re: Fast AY music players?
I have used WYZ player in a past game and will be working again with it soon again.
I store the player in bank 0 and page in other banks for other code. Music files are stored compressed but for the song that you are playing, uncompressed to a buffer and then clear it after you are finished with the song.
The player gets called once during the game loop. I don’t have the numbers in front of me, but I’ve not had any issues with WYZ.
I store the player in bank 0 and page in other banks for other code. Music files are stored compressed but for the song that you are playing, uncompressed to a buffer and then clear it after you are finished with the song.
The player gets called once during the game loop. I don’t have the numbers in front of me, but I’ve not had any issues with WYZ.
Re: Fast AY music players?
What framerate does your game run at? Could you write music for a 25Hz interrupt, then call the player once every two frames? (This is what GLUF does.)
-
- Microbot
- Posts: 134
- Joined: Tue Jun 09, 2020 6:14 am
- Contact:
Re: Fast AY music players?
One thing you can try is separating the output to the AY (fast) from parsing the song data in the player (slow). For instance in VTII 1.0 standard player, the output code is located near the ROUT label. Put a RET before it, and then call the player this way:
There are also some other trackers you can try. For PC-based, there's Arkos Tracker 1 and 2 from the CPC people, and WYZ Tracker which is often used in the Spanish Speccy community. Keep in mind though that they might not necessarily support each other's formats. I think VTII is the most advanced of these, while WYZ is the most limited/basic (but possibly also fastest?), and Arkos is somewhat middle-ground. Arkos 2 can import Vortex songs but with some limitations.
Code: Select all
;just after an interrupt
call ROUT
;...
;somewhere you have free time in the frame
call VTIIPlayer+5
-
- Manic Miner
- Posts: 401
- Joined: Fri Jan 03, 2020 10:00 am
Re: Fast AY music players?
If you mean Sergey Bulba's player (from Vortex Tracker), it's a lot slower than Pro Tracker 3's player in the peak (because it decodes THREE channels at once, no one after another, and uses index registers for size optimization).PROSM wrote: ↑Tue Jul 07, 2020 10:07 pmI've experimented with the PT3 player, but it's too slow.Alone Coder wrote: ↑Tue Jul 07, 2020 9:35 pm The default PT3 player (playFAS5.H) fits in 5000 t-states. You don't need to make a register stream.
The Pro Tracker 3's player I quoted is used in one-frame scrolling viewer in Info Guide e-zine. It's fast.
- PROSM
- Manic Miner
- Posts: 477
- Joined: Fri Nov 17, 2017 7:18 pm
- Location: Sunderland, England
- Contact:
Re: Fast AY music players?
Yes, sorry, I meant convert a PT3 file. The PSG packer sounds interesting as well, though.XoRRoX wrote: ↑Tue Jul 07, 2020 11:22 pm The psg format itself is not packed. It's a recording of the stream of AY register values every vblank.
Most AY formats can be converted to psg with AYEmul (right-click on tune in playlist).
I know of a psg packer but don't know know which format azesmbog is referring to. .ym possibly? Although I don't actually know if it's fast.
I'll have to give WYZ a try then, see how well it works. Thanks!andydansby wrote: ↑Wed Jul 08, 2020 12:31 am I have used WYZ player in a past game and will be working again with it soon again.
I store the player in bank 0 and page in other banks for other code. Music files are stored compressed but for the song that you are playing, uncompressed to a buffer and then clear it after you are finished with the song.
The player gets called once during the game loop. I don’t have the numbers in front of me, but I’ve not had any issues with WYZ.
My game runs at 17fps, so maybe too low to use this technique.
Interesting workaround. It would certainly work for my purposes, but given my tight T-state budget, I'd rather cut out all the computational work rather than shift it elsewhere in the frame.Nienn Heskil wrote: ↑Wed Jul 08, 2020 5:32 am One thing you can try is separating the output to the AY (fast) from parsing the song data in the player (slow). For instance in VTII 1.0 standard player, the output code is located near the ROUT label. Put a RET before it, and then call the player this way:
Code: Select all
;just after an interrupt call ROUT ;... ;somewhere you have free time in the frame call VTIIPlayer+5
Thanks for the suggestions, I'll have to try some of these and see if their players are fast enough.Nienn Heskil wrote: ↑Wed Jul 08, 2020 5:32 am There are also some other trackers you can try. For PC-based, there's Arkos Tracker 1 and 2 from the CPC people, and WYZ Tracker which is often used in the Spanish Speccy community. Keep in mind though that they might not necessarily support each other's formats. I think VTII is the most advanced of these, while WYZ is the most limited/basic (but possibly also fastest?), and Arkos is somewhat middle-ground. Arkos 2 can import Vortex songs but with some limitations.
Sorry, I didn't realise. I'll have to give the other player a try then. Thanks!Alone Coder wrote: ↑Wed Jul 08, 2020 11:03 amIf you mean Sergey Bulba's player (from Vortex Tracker), it's a lot slower than Pro Tracker 3's player in the peak (because it decodes THREE channels at once, no one after another, and uses index registers for size optimization).
The Pro Tracker 3's player I quoted is used in one-frame scrolling viewer in Info Guide e-zine. It's fast.
All software to-date
Working on something, as always.
Working on something, as always.
Re: Fast AY music players?
Then a simple example.
Composition "Cuckoo" "Kukushka"
https://zxart.ee/rus/avtory/m/mmcm/kukushka/
In the archive the composition itself, 4 kB
unpacked in the same PSG - 38.7 kB
packaged for use in the program - 12.5 kB
Well, a snapshot for the Pentagon and a tap file for zx48
See and decide for yourself if necessary.
I needed for music and pictures on a border with smooth timing.
Composition "Cuckoo" "Kukushka"
https://zxart.ee/rus/avtory/m/mmcm/kukushka/
In the archive the composition itself, 4 kB
unpacked in the same PSG - 38.7 kB
packaged for use in the program - 12.5 kB
Well, a snapshot for the Pentagon and a tap file for zx48
See and decide for yourself if necessary.
I needed for music and pictures on a border with smooth timing.
Re: Fast AY music players?
You can download the psg packer and player here: https://drive.google.com/file/d/0B6VVwC ... JpelE/edit
In the package, there's also a "tbkplayer.fast.asm" but you'll have to check it out for yourself to see if it fits your need.
In the package, there's also a "tbkplayer.fast.asm" but you'll have to check it out for yourself to see if it fits your need.
-
- Manic Miner
- Posts: 401
- Joined: Fri Jan 03, 2020 10:00 am
Re: Fast AY music players?
This player is outdated.
You can have constant time (1201t) with TmK's player (AY-ZIP). I used it in some demos. http://alonecoder.nedopc.com/ay_zip_1_2.zip
In Space Monsters meet THE HARDY I used constant time bfox's player, it's a little slower but packs better. However, it isn't released yet AFAIK, bfox compiled his music himself.
You can have constant time (1201t) with TmK's player (AY-ZIP). I used it in some demos. http://alonecoder.nedopc.com/ay_zip_1_2.zip
In Space Monsters meet THE HARDY I used constant time bfox's player, it's a little slower but packs better. However, it isn't released yet AFAIK, bfox compiled his music himself.
- PROSM
- Manic Miner
- Posts: 477
- Joined: Fri Nov 17, 2017 7:18 pm
- Location: Sunderland, England
- Contact:
Re: Fast AY music players?
Thanks for the links. I'm going to try both of these over the next few days and see how well they work with the rest of my program.Alone Coder wrote: ↑Thu Jul 09, 2020 11:18 am This player is outdated.
You can have constant time (1201t) with TmK's player (AY-ZIP). I used it in some demos. http://alonecoder.nedopc.com/ay_zip_1_2.zip
In Space Monsters meet THE HARDY I used constant time bfox's player, it's a little slower but packs better. However, it isn't released yet AFAIK, bfox compiled his music himself.
All software to-date
Working on something, as always.
Working on something, as always.
Re: Fast AY music players?
And how do you make songs for these custom AY players ? Do you have to compose them in Notepad writing down sequences of bytes?
- PROSM
- Manic Miner
- Posts: 477
- Joined: Fri Nov 17, 2017 7:18 pm
- Location: Sunderland, England
- Contact:
Re: Fast AY music players?
Thankfully, the one Alone Coder has pointed me to has a PT3 converter. I've done beeper songs in Notepad, but AY is a bit of a step too far
All software to-date
Working on something, as always.
Working on something, as always.
- PROSM
- Manic Miner
- Posts: 477
- Joined: Fri Nov 17, 2017 7:18 pm
- Location: Sunderland, England
- Contact:
Re: Fast AY music players?
I've put the TBK player into my program, and it works a treat! Incredibly fast playback with no fuss. Obviously, because of the large size of the tracks, I'll have to limit it to in-game music, but that's no problem. Thank you to everyone who responded to the thread!
All software to-date
Working on something, as always.
Working on something, as always.
Re: Fast AY music players?
If anyone has need for music for a custom AY player for which no dedicated editor is available, I will be able to support those in Bintracker soon (in a couple of months). So just get in touch if need arises!