Optimized base displacement by reordering variables

Further optimized ADSR code
This commit is contained in:
Chris Hodges 2022-12-27 19:35:06 +01:00
parent 0d05dbf24c
commit 74c2b492f0
2 changed files with 104 additions and 102 deletions

View File

@ -98,4 +98,14 @@ which is significant more than a standard Protracker replayer
about 34 on average!).
Watch out for *Presto*, the [LightSpeedPlayer](https://github.com/arnaud-carre/LSPlayer) variant that should
solve this problem.
solve this problem.
## Changelog
### V1.1 (unreleased)
- Optimized base displacement by reordering variables
- Further optimized ADSR code
### V1.0 (26-Dec-22)
- Initial release

View File

@ -1,9 +1,11 @@
;--------------------------------------------------------------------
; Raspberry Casket Player V1.0 (26-Dec-2022)
; Raspberry Casket Player V1.0+ (27-Dec-2022)
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Provided by Chris 'platon42' Hodges <chrisly@platon42.de>
;
; Latest: https://github.com/chrisly42/PretrackerRaspberryCasket
;
; Rewritten by platon42/Desire based on a resourced, binary identical
; version of the original Pretracker V1.0 replayer binary provided
; by hitchhikr (thanks!), originally written in C by Pink/Abyss.
@ -100,7 +102,8 @@
;
; Watch out for Presto, the LightSpeedPlayer variant that should
; solve this problem.
;
; Changelog see https://github.com/chrisly42/PretrackerRaspberryCasket#Changelog
;--------------------------------------------------------------------
; Here come the various options for you to configure.
@ -411,13 +414,13 @@ uii_SIZEOF rs.b 0
; MySong offsets
rsreset
sv_waveinfo_table rs.l MAX_WAVES ; 24 pointers to wave infos to avoid mulu
sv_inst_patterns_table rs.l MAX_INSTRUMENTS ; 32 pointers to pattern data
sv_wavelength_table rs.l MAX_WAVES ; 24 longwords to sample lengths (standard octave) (NEW)
sv_wavetotal_table rs.l MAX_WAVES ; 24 longwords to sample lengths for all octaves (NEW)
sv_wavegen_order_table rs.b MAX_WAVES ; 24 bytes
sv_num_waves_b rs.b 1
sv_num_steps_b rs.b 1
sv_patterns_ptr rs.l 1
sv_inst_patterns_table rs.l MAX_INSTRUMENTS ; 32 pointers to pattern data
sv_curr_pat_pos_w rs.w 1 ; only byte used FIXME why is this part of MySong? Should be in Player
sv_pat_pos_len_w rs.w 1 ; only byte used
sv_pat_restart_pos_w rs.w 1 ; only byte used
@ -482,16 +485,14 @@ pcd_last_trigger_pos_w rs.w 1 ; I think this makes sure that we don't re
pcd_pat_portamento_speed_b rs.b 1
pcd_pat_adsr_rel_delay_b rs.b 1 ; counts down until adsr release. Seems unused?
pcd_new_inst_num_b rs.b 1 ; load new instrument (number)
pcd_note_off_delay_b rs.b 1 ; time before note is released ($ff = disabled)
pcd_inst_pattern_steps_b rs.b 1 ; number of steps in instrument pattern
pcd_note_delay_b rs.b 1 ; $ff = no note delay
pcd_track_delay_steps_b rs.b 1 ; $00 = no track delay, $ff = stop track delay (this is for the next channel!)
pcd_track_delay_vol16_b rs.b 1
pcd_track_init_delay_b rs.b 1 ; number of frames to ignore the delay
pcd_inst_pattern_steps_b rs.b 1 ; number of steps in instrument pattern
rs.b 1
pcd_inst_num_w rs.w 1 ; current instrument number (lower byte used)
;pcd_inst_new_step_w rs.w 1 ; seems to be unused
pcd_inst_ping_pong_s_w rs.w 1 ; direction of pingpong (-1 / +1)
@ -510,6 +511,8 @@ pcd_adsr_phase_speed_b rs.b 1
pcd_adsr_pos_w rs.w 1 ; pos in adsr curve
pcd_adsr_vol64_w rs.w 1 ; some adsr volume
pcd_new_inst_num_b rs.b 1 ; load new instrument (number) ! do not change order
rs.b 1 ; gets cleared
pcd_vibrato_pos_w rs.w 1 ;
pcd_vibrato_delay_w rs.w 1 ; is a byte value ! do not change order
pcd_vibrato_depth_w rs.w 1 ; is a byte value ! do not change order
@ -1112,7 +1115,11 @@ pre_PlayerInit:
move.b d1,pv_wg_curr_wave_num_b(a4)
ENDC
lsl.w #2,d1
lea sv_wavelength_table(a6,d1.w),a6
move.l pv_wave_sample_table(a4,d1.w),a0
move.l a0,pv_wg_curr_sample_ptr(a4)
add.w #sv_wavelength_table,d1
adda.w d1,a6
move.l sv_wavelength_table-sv_wavelength_table(a6),d0
move.w d0,pv_wg_curr_sample_len_w(a4)
IFNE PRETRACKER_PROGRESS_SUPPORT
@ -1120,9 +1127,6 @@ pre_PlayerInit:
ENDC
move.l sv_waveinfo_table-sv_wavelength_table(a6),a3
move.l pv_wave_sample_table(a4,d1.w),a0
move.l a0,pv_wg_curr_sample_ptr(a4)
; clear sample data (a0 and d0 from above)
bsr pre_MemClr
move.l a0,pv_wg_curr_samend_ptr(a4)
@ -2093,8 +2097,9 @@ pre_PlayerInit:
ENDC
lsl.w #2,d0
move.l sv_wavelength_table(a6,d0.w),d3
move.l pv_wave_sample_table(a4,d0.w),a1
add.w #sv_wavelength_table,d0
move.l (a6,d0.w),d3
move.w pv_wg_curr_sample_len_w(a4),d4 ; length of the sample to mix to
cmp.w d3,d4
@ -2768,7 +2773,7 @@ pre_PlayerTick:
; ----------------------------------------
.pat_set_track_delay
cmp.b #NUM_CHANNELS-1,pcd_channel_num_b(a5)
beq.s .pat_play_cont ; we are at channel 3 -- track delay not available here
beq .pat_play_cont ; we are at channel 3 -- track delay not available here
lea pcd_SIZEOF+pcd_track_delay_buffer+ocd_volume(a5),a1
moveq.l #MAX_TRACK_DELAY-1,d2
@ -2998,6 +3003,7 @@ pre_PlayerTick:
; a4: pv
; a5: channel struct
; a6: mysong struct
.inst_pattern_processing
lea pv_channeldata(a4),a5
@ -3039,7 +3045,6 @@ pre_PlayerTick:
moveq.l #0,d0
move.w d0,pcd_inst_pitch_slide_w(a5)
move.b d0,pcd_inst_vol_slide_b(a5)
moveq.l #-1,d4
; IFNE PRETRACKER_PARANOIA_MODE ; new step is never written
; move.w pcd_inst_new_step_w(a5),d1
@ -3049,13 +3054,14 @@ pre_PlayerTick:
; moveq.l #$20,d1
;.inst_good_new_step_pos
; move.b d1,pcd_inst_step_pos_b(a5)
; move.w d4,pcd_inst_new_step_w(a5)
; move.w #$ffff,pcd_inst_new_step_w(a5)
;.inst_no_new_step_pos
; ENDC
move.b pcd_inst_step_pos_b(a5),d0
cmp.b pcd_inst_pattern_steps_b(a5),d0
bhs .inst_pat_loop_exit
moveq.l #-1,d4
moveq.l #0,d7
moveq.l #0,d3 ; flag for stitching -- if set, must not trigger new note
; enters with d4 = -1, meaning no first note pos yet
@ -3063,8 +3069,7 @@ pre_PlayerTick:
move.w pcd_inst_num_w(a5),d1
add.w d1,d1
add.w d1,d1
add.w #sv_inst_patterns_table,d1
movea.l -4(a6,d1.w),a0
movea.l sv_inst_patterns_table-4(a6,d1.w),a0
add.w d0,a0
add.w d0,a0
@ -3237,7 +3242,7 @@ pre_PlayerTick:
.inst_adsr_release
move.w pcd_adsr_volume_w(a5),d5
asr.w #6,d5 ; FIXME lsr?
asr.w #6,d5
move.w d5,pcd_adsr_vol64_w(a5)
moveq.l #16,d6
move.w d6,pcd_adsr_pos_w(a5)
@ -3287,8 +3292,7 @@ pre_PlayerTick:
move.w pcd_inst_num_w(a5),d1
add.w d1,d1
add.w d1,d1
add.w #sv_inst_patterns_table,d1
movea.l -4(a6,d1.w),a0
movea.l sv_inst_patterns_table-4(a6,d1.w),a0
add.w d5,a0
add.w d5,d5
@ -3423,7 +3427,6 @@ pre_PlayerTick:
.inst_no_inst_active
.inst_pat_loop_exit3
move.w wi_subloop_len_w(a3),d3
; ----------------------------------------
@ -3431,11 +3434,65 @@ pre_PlayerTick:
; a5 = channel
move.w pcd_inst_vol_w(a5),d1
moveq.l #0,d2
move.b pcd_new_inst_num_b(a5),d2
beq.s .dont_load_instrument
tst.b pcd_new_inst_num_b(a5)
bne.s .load_instrument
.loadinstrument
.dont_load_instrument
move.w pcd_adsr_volume_w(a5),d2
move.w pcd_adsr_phase_w(a5),d4
beq.s .adsr_attack
subq.w #1,d4
move.w d4,d3
beq.s .adsr_decay_and_release ; we destinguish via d3 == 0 -> decay
subq.w #1,d4
beq .adsr_sustain
.adsr_release
move.w pcd_adsr_pos_w(a5),d4
add.w pcd_adsr_vol64_w(a5),d4
move.w d4,pcd_adsr_pos_w(a5)
sub.w #16,d4
blt.s .adsr_done
move.w d4,pcd_adsr_pos_w(a5)
; same code for both release and decay
.adsr_decay_and_release
moveq.l #0,d4
move.b pcd_adsr_phase_speed_b(a5),d4
cmpi.b #$8f,d4
bhs.s .adsr_absurd_slow_release
move.b d4,d5
addq.b #1,d5
add.w d4,d4
lea pre_roll_off_table(pc),a1
move.w (a1,d4.w),d4
bra.s .adsr_release_cont
.adsr_absurd_slow_release
moveq.l #2,d4 ; FIXME I guess this should be 1, if I look at the roll-off table
moveq.l #-$71,d5 ; same as $8f, we only need the byte
.adsr_release_cont
move.b d5,pcd_adsr_phase_speed_b(a5)
tst.w d3
beq.s .adsr_is_actually_decay
sub.w d4,d2
bpl.s .adsr_done
moveq.l #0,d2
bra.s .adsr_done
.adsr_is_actually_decay
sub.w d4,d2
cmp.w uii_adsr_sustain(a2),d2
bgt.s .adsr_done
.adsr_enter_sustain
move.w #2,pcd_adsr_phase_w(a5)
move.w uii_adsr_sustain(a2),d2
bra.s .adsr_done
.load_instrument
move.b d1,pcd_loaded_inst_vol_b(a5)
move.l uii_vibrato_delay(a2),pcd_vibrato_delay_w(a5) ; and uii_vibrato_depth
;move.w uii_vibrato_delay(a2),pcd_vibrato_delay_w(a5)
@ -3450,94 +3507,24 @@ pre_PlayerTick:
;move.w d2,pcd_adsr_phase_w(a5)
;move.w d2,pcd_adsr_volume_w(a5)
move.w d2,pcd_vibrato_pos_w(a5)
move.b d2,pcd_new_inst_num_b(a5)
move.l d2,pcd_new_inst_num_b(a5) ; and pcd_vibrato_pos_w
.adsr_attack
add.w uii_adsr_attack(a2),d2
cmpi.w #MAX_VOLUME<<4,d2
blt .adsr_done
blt.s .adsr_done
.adsr_do_decay
move.w #MAX_VOLUME<<4,d2
move.w #1,pcd_adsr_phase_w(a5)
move.b uii_adsr_decay+1(a2),pcd_adsr_phase_speed_b(a5)
bra .adsr_done
.dont_load_instrument
move.w pcd_adsr_volume_w(a5),d2
move.w pcd_adsr_phase_w(a5),d4
beq.s .adsr_attack
subq.w #1,d4
beq.s .adsr_decay
subq.w #1,d4
beq .adsr_sustain
.adsr_release
move.w pcd_adsr_pos_w(a5),d4
add.w pcd_adsr_vol64_w(a5),d4
move.w d4,pcd_adsr_pos_w(a5)
cmpi.w #15,d4
ble.s .adsr_sustain
; release?
moveq.l #0,d5
move.b pcd_adsr_phase_speed_b(a5),d5
cmpi.b #$8E,d5
bhi.s .lbC001142
addq.b #1,pcd_adsr_phase_speed_b(a5)
add.w d5,d5
lea pre_roll_off_table(pc),a1
move.w (a1,d5.w),d5
bra.s .lbC001148
.adsr_decay
moveq.l #0,d4
move.b pcd_adsr_phase_speed_b(a5),d4
cmpi.b #$8E,d4
bhi.s .adsr_absurd_long_decay
move.b d4,d5
addq.b #1,d5
add.w d4,d4
lea pre_roll_off_table(pc),a1
move.w (a1,d4.w),d4
bra.s .adsr_decay_cont
.adsr_absurd_long_decay
moveq.l #2,d4 ; FIXME I guess this should be 1, if I look at the roll-off table
moveq.l #-$71,d5
.adsr_decay_cont
move.b d5,pcd_adsr_phase_speed_b(a5)
sub.w d4,d2
move.w d2,d4
move.w uii_adsr_sustain(a2),d2
cmp.w d4,d2
bge.s .adsr_enter_sustain
move.w d4,d2
bra.s .adsr_done
.adsr_enter_sustain
move.w #2,pcd_adsr_phase_w(a5)
bra.s .adsr_done
.lbC001142
moveq.l #2,d5
move.b #-$71,pcd_adsr_phase_speed_b(a5)
.lbC001148
sub.w d5,d2
bpl.s .adsr_noclip_vol
moveq.l #0,d2
.adsr_noclip_vol
sub.w #16,d4
move.w d4,pcd_adsr_pos_w(a5)
.adsr_sustain
.adsr_done
move.w d2,pcd_adsr_volume_w(a5)
lsr.w #4,d2
; ----------------------------------------
; return from .loadinstrument
; handle note cut-off command (EAx command)
move.b pcd_note_off_delay_b(a5),d4
beq.s .dont_release_note
subq.b #1,d4
@ -3548,18 +3535,24 @@ pre_PlayerTick:
move.w #3,pcd_adsr_phase_w(a5)
.dont_release_note
; ----------------------------------------
; calculate final volume output = inst_vol * ADSR volume * pattern volume
IFNE PRETRACKER_VOLUME_TABLE
lea pv_volume_table(a4),a1
lsl.w #7,d2
lsl.w #3,d2
and.w #127<<7,d2
or.b d1,d2
move.b (a1,d2.w),d1
lsl.w #7,d1
or.b pcd_pat_vol_b(a5),d1
move.b (a1,d1.w),pcd_out_vol_b(a5)
ELSE
lsr.w #4,d2
mulu d2,d1
lsr.w #6,d1
moveq.l #0,d2
move.b pcd_pat_vol_b(a5),d2
mulu d1,d2
@ -3569,12 +3562,11 @@ pre_PlayerTick:
; ----------------------------------------
; wave looping (FIXME this needs some serious tidying)
move.w wi_subloop_step_w(a3),d2
moveq.l #0,d1
move.b pcd_wave_offset_b(a5),d1
; FIXME can we merge this code path
tst.w d3
move.w wi_subloop_len_w(a3),d3
beq .lbC000D8E
tst.b d1