sound, add native rate mode, change resampling

This commit is contained in:
kub 2022-03-06 20:40:50 +00:00
parent d26d4c2965
commit 882f697ad4
11 changed files with 90 additions and 167 deletions

View file

@ -853,6 +853,8 @@ extern short cdda_out_buffer[2*1152];
void cdda_start_play(int lba_base, int lba_offset, int lb_len);
#define YM2612_NATIVE_RATE() (((Pico.m.pal?OSC_PAL:OSC_NTSC)/7 + 3*24) / (6*24))
void ym2612_sync_timers(int z80_cycles, int mode_old, int mode_new);
void ym2612_pack_state(void);
void ym2612_unpack_state(void);

View file

@ -18,7 +18,7 @@ void (*PsndMix_32_to_16l)(s16 *dest, s32 *src, int count) = mix_32_to_16l_stereo
// master int buffer to mix to
// +1 for a fill triggered by an instruction overhanging into the next scanline
static s32 PsndBuffer[2*(44100+100)/50+2];
static s32 PsndBuffer[2*(53267+100)/50+2];
// cdda output buffer
s16 cdda_out_buffer[2*1152];

View file

@ -974,7 +974,6 @@ static int update_algo_channel(chan_rend_context *ct, unsigned int eg_out, unsig
ct->mem = op_calc(ct->phase2, eg_out2, c1);
}
else ct->mem = 0;
if (ct->eg_timer >= (1<<EG_SH)) break;
if( eg_out < ENV_QUIET ) { /* SLOT 3 */
c2 = op_calc(ct->phase3, eg_out, m2);
@ -993,7 +992,6 @@ static int update_algo_channel(chan_rend_context *ct, unsigned int eg_out, unsig
if( eg_out2 < ENV_QUIET ) { /* SLOT 2 */
ct->mem+= op_calc(ct->phase2, eg_out2, 0);
}
if (ct->eg_timer >= (1<<EG_SH)) break;
if( eg_out < ENV_QUIET ) { /* SLOT 3 */
c2 = op_calc(ct->phase3, eg_out, m2);
@ -1013,7 +1011,6 @@ static int update_algo_channel(chan_rend_context *ct, unsigned int eg_out, unsig
ct->mem = op_calc(ct->phase2, eg_out2, 0);
}
else ct->mem = 0;
if (ct->eg_timer >= (1<<EG_SH)) break;
if( eg_out < ENV_QUIET ) { /* SLOT 3 */
c2 += op_calc(ct->phase3, eg_out, m2);
@ -1033,7 +1030,6 @@ static int update_algo_channel(chan_rend_context *ct, unsigned int eg_out, unsig
ct->mem = op_calc(ct->phase2, eg_out2, c1);
}
else ct->mem = 0;
if (ct->eg_timer >= (1<<EG_SH)) break;
if( eg_out < ENV_QUIET ) { /* SLOT 3 */
c2 += op_calc(ct->phase3, eg_out, 0);
@ -1048,7 +1044,6 @@ static int update_algo_channel(chan_rend_context *ct, unsigned int eg_out, unsig
/* M1---C1-+-OUT */
/* M2---C2-+ */
/* MEM: not used */
if (ct->eg_timer >= (1<<EG_SH)) break;
c1 = ct->op1_out>>16;
if( eg_out < ENV_QUIET ) { /* SLOT 3 */
@ -1069,7 +1064,6 @@ static int update_algo_channel(chan_rend_context *ct, unsigned int eg_out, unsig
/* +----C2----+ */
m2 = ct->mem;
ct->mem = c1 = c2 = ct->op1_out>>16;
if (ct->eg_timer >= (1<<EG_SH)) break;
if( eg_out < ENV_QUIET ) { /* SLOT 3 */
smp = op_calc(ct->phase3, eg_out, m2);
@ -1088,7 +1082,6 @@ static int update_algo_channel(chan_rend_context *ct, unsigned int eg_out, unsig
/* M2-+-OUT */
/* C2-+ */
/* MEM: not used */
if (ct->eg_timer >= (1<<EG_SH)) break;
c1 = ct->op1_out>>16;
if( eg_out < ENV_QUIET ) { /* SLOT 3 */
@ -1109,7 +1102,6 @@ static int update_algo_channel(chan_rend_context *ct, unsigned int eg_out, unsig
/* M2-+ */
/* C2-+ */
/* MEM: not used*/
if (ct->eg_timer >= (1<<EG_SH)) break;
smp = ct->op1_out>>16;
if( eg_out < ENV_QUIET ) { /* SLOT 3 */
@ -1139,20 +1131,6 @@ static void chan_render_loop(chan_rend_context *ct, s32 *buffer, int length)
ct->eg_timer += ct->eg_timer_add;
if (ct->eg_timer >= 3<<EG_SH && !(ct->pack&0xf000)) {
int cnt = (ct->eg_timer>>EG_SH)-2;
if (ct->pack & 8) { /* LFO enabled ? (test Earthworm Jim in between demo 1 and 2) */
int inc = cnt*ct->lfo_inc;
ct->pack = (ct->pack&0xffff) | (advance_lfo(ct->pack >> 16, ct->lfo_cnt, ct->lfo_cnt + inc) << 16);
ct->lfo_cnt += inc;
}
ct->phase1 += cnt*ct->incr1;
ct->phase2 += cnt*ct->incr2;
ct->phase3 += cnt*ct->incr3;
ct->phase4 += cnt*ct->incr4;
}
while (ct->eg_timer >= 1<<EG_SH) {
ct->eg_timer -= 1<<EG_SH;
@ -1168,62 +1146,56 @@ static void chan_render_loop(chan_rend_context *ct, s32 *buffer, int length)
update_eg_phase_channel(ct);
}
ct->vol_out1 = ct->CH->SLOT[SLOT1].vol_out;
ct->vol_out2 = ct->CH->SLOT[SLOT2].vol_out;
ct->vol_out3 = ct->CH->SLOT[SLOT3].vol_out;
ct->vol_out4 = ct->CH->SLOT[SLOT4].vol_out;
if (ct->eg_timer < (2<<EG_SH) || (ct->pack&0xf000)) {
if (ct->pack & 4) goto disabled; /* output disabled */
if (ct->pack & 8) { /* LFO enabled ? (test Earthworm Jim in between demo 1 and 2) */
ct->pack = (ct->pack&0xffff) | (advance_lfo(ct->pack >> 16, ct->lfo_cnt, ct->lfo_cnt + ct->lfo_inc) << 16);
ct->lfo_cnt += ct->lfo_inc;
}
/* calculate channel sample */
eg_out = ct->vol_out1;
if ( (ct->pack & 8) && (ct->pack&(1<<(SLOT1+8))) )
eg_out += ct->pack >> (((ct->pack&0xc0)>>6)+24);
if( eg_out < ENV_QUIET ) /* SLOT 1 */
{
int out = 0;
if (ct->pack&0xf000) out = ((ct->op1_out + (ct->op1_out<<16))>>16) << ((ct->pack&0xf000)>>12); /* op1_out0 + op1_out1 */
ct->op1_out <<= 16;
ct->op1_out |= (unsigned short)op_calc1(ct->phase1, eg_out, out);
} else {
ct->op1_out <<= 16; /* op1_out0 = op1_out1; op1_out1 = 0; */
}
if (ct->eg_timer < (2<<EG_SH)) {
eg_out = ct->vol_out3; // volume_calc(&CH->SLOT[SLOT3]);
eg_out2 = ct->vol_out2; // volume_calc(&CH->SLOT[SLOT2]);
eg_out4 = ct->vol_out4; // volume_calc(&CH->SLOT[SLOT4]);
if (ct->pack & 8) {
unsigned int add = ct->pack >> (((ct->pack&0xc0)>>6)+24);
if (ct->pack & (1<<(SLOT3+8))) eg_out += add;
if (ct->pack & (1<<(SLOT2+8))) eg_out2 += add;
if (ct->pack & (1<<(SLOT4+8))) eg_out4 += add;
}
smp = update_algo_channel(ct, eg_out, eg_out2, eg_out4);
}
/* done calculating channel sample */
disabled:
/* update phase counters AFTER output calculations */
ct->phase1 += ct->incr1;
ct->phase2 += ct->incr2;
ct->phase3 += ct->incr3;
ct->phase4 += ct->incr4;
}
}
ct->vol_out1 = ct->CH->SLOT[SLOT1].vol_out;
ct->vol_out2 = ct->CH->SLOT[SLOT2].vol_out;
ct->vol_out3 = ct->CH->SLOT[SLOT3].vol_out;
ct->vol_out4 = ct->CH->SLOT[SLOT4].vol_out;
if (ct->pack & 4) goto disabled; /* output disabled */
if (ct->pack & 8) { /* LFO enabled ? (test Earthworm Jim in between demo 1 and 2) */
ct->pack = (ct->pack&0xffff) | (advance_lfo(ct->pack >> 16, ct->lfo_cnt, ct->lfo_cnt + ct->lfo_inc) << 16);
ct->lfo_cnt += ct->lfo_inc;
}
/* calculate channel sample */
eg_out = ct->vol_out1;
if ( (ct->pack & 8) && (ct->pack&(1<<(SLOT1+8))) )
eg_out += ct->pack >> (((ct->pack&0xc0)>>6)+24);
if( eg_out < ENV_QUIET ) /* SLOT 1 */
{
int out = 0;
if (ct->pack&0xf000) out = ((ct->op1_out + (ct->op1_out<<16))>>16) << ((ct->pack&0xf000)>>12); /* op1_out0 + op1_out1 */
ct->op1_out <<= 16;
ct->op1_out |= (unsigned short)op_calc1(ct->phase1, eg_out, out);
} else {
ct->op1_out <<= 16; /* op1_out0 = op1_out1; op1_out1 = 0; */
}
eg_out = ct->vol_out3; // volume_calc(&CH->SLOT[SLOT3]);
eg_out2 = ct->vol_out2; // volume_calc(&CH->SLOT[SLOT2]);
eg_out4 = ct->vol_out4; // volume_calc(&CH->SLOT[SLOT4]);
if (ct->pack & 8) {
unsigned int add = ct->pack >> (((ct->pack&0xc0)>>6)+24);
if (ct->pack & (1<<(SLOT3+8))) eg_out += add;
if (ct->pack & (1<<(SLOT2+8))) eg_out2 += add;
if (ct->pack & (1<<(SLOT4+8))) eg_out4 += add;
}
smp = update_algo_channel(ct, eg_out, eg_out2, eg_out4);
/* done calculating channel sample */
disabled:
/* update phase counters AFTER output calculations */
ct->phase1 += ct->incr1;
ct->phase2 += ct->incr2;
ct->phase3 += ct->incr3;
ct->phase4 += ct->incr4;
/* mix sample to output buffer */
if (smp) {
smp = clip(smp); /* saturate to 14 bit */
@ -1615,7 +1587,7 @@ static void OPNSetPres(int pres)
double freqbase = (ym2612.OPN.ST.rate) ? ((double)ym2612.OPN.ST.clock / ym2612.OPN.ST.rate) / pres : 0;
ym2612.OPN.eg_timer_add = (1<<EG_SH) * freqbase;
ym2612.OPN.ST.freqbase = 1.0; // freqbase
ym2612.OPN.ST.freqbase = freqbase;
/* make time tables */
init_timetables( dt_tab );

View file

@ -327,9 +327,6 @@
@ r0-r2=scratch, r3=sin_tab, r5=scratch, r6-r7=vol_out[4], r10=op1_out
.macro upd_algo0_m
cmp r8, #(1<<EG_SH)
bge 1f
@ SLOT3
make_eg_out SLOT3
cmp r1, #ENV_QUIET
@ -370,9 +367,6 @@
.macro upd_algo1_m
cmp r8, #(1<<EG_SH)
bge 1f
@ SLOT3
make_eg_out SLOT3
cmp r1, #ENV_QUIET
@ -413,9 +407,6 @@
.macro upd_algo2_m
cmp r8, #(1<<EG_SH)
bge 1f
@ SLOT3
make_eg_out SLOT3
cmp r1, #ENV_QUIET
@ -457,9 +448,6 @@
.macro upd_algo3_m
cmp r8, #(1<<EG_SH)
bge 1f
@ SLOT3
make_eg_out SLOT3
cmp r1, #ENV_QUIET
@ -501,9 +489,6 @@
.macro upd_algo4_m
cmp r8, #(1<<EG_SH)
bge 2f
@ SLOT3
make_eg_out SLOT3
cmp r1, #ENV_QUIET
@ -541,9 +526,6 @@
.macro upd_algo5_m
cmp r8, #(1<<EG_SH)
bge 2f
@ SLOT3
make_eg_out SLOT3
cmp r1, #ENV_QUIET
@ -584,9 +566,6 @@
.macro upd_algo6_m
cmp r8, #(1<<EG_SH)
bge 2f
@ SLOT3
make_eg_out SLOT3
cmp r1, #ENV_QUIET
@ -622,9 +601,6 @@
.macro upd_algo7_m
cmp r8, #(1<<EG_SH)
bge 2f
@ SLOT3
make_eg_out SLOT3
cmp r1, #ENV_QUIET
@ -709,53 +685,15 @@ crl_loop:
mov r0, #0
add r8, r8, r9
subs r8, r8, #(1<<EG_SH)
blt crl_smp_loop_end
blt eg_loop_done
cmp r8, #(2<<EG_SH) @ calculate only for operator memory, sample,
tstge r12, #0xf000 @ ...feedback
bne crl_smp_loop
@ -- LFO+PHASE UPDATE, FF --
mov r0, r8, lsr #EG_SH
sub r0, r0, #1
tst r12, #8 @ lfo?
beq lfo_done_ff
ldr r2, [lr, #0x34] @ lfo_inc
ldr r1, [lr, #0x30] @ lfo_cnt
mul r2, r0, r2
add r2, r2, r1
str r2, [lr, #0x30]
@ r12=lfo_ampm[31:16], r1=lfo_cnt_old, r2=lfo_cnt
advance_lfo_m
lfo_done_ff:
add lr, lr, #0x10
ldmia lr, {r1-r3,r5-r7}
mul r6, r0, r6
mul r7, r0, r7
add r1, r1, r6
add r2, r2, r7
ldr r6, [lr, #0x18]
ldr r7, [lr, #0x1c]
mul r6, r0, r6
mul r7, r0, r7
add r3, r3, r6
add r5, r5, r7
stmia lr, {r1-r3,r5}
sub lr, lr, #0x10
crl_smp_loop:
crl_eg_loop:
ldr r5, [lr, #0x40] @ CH
#if defined(SSG_EG)
tst r12, #0x02 @ ssg_enabled?
beq ssg_done
@ -- SSG --
ssg_loop:
mov r6, #4
ssg_upd_loop:
@ use lr as a pointer to the slot phases stored in the context
@ -808,9 +746,11 @@ eg_upd_loop:
sub r5, r5, #SLOT_STRUCT_SIZE*3
eg_done:
cmp r8, #(2<<EG_SH) @ calculate only for operator memory, sample,
tstge r12, #0xf000 @ ...feedback
beq crl_ff
subs r8, r8, #(1<<EG_SH)
bge crl_eg_loop
eg_loop_done:
add r8, r8, #(1<<EG_SH)
@ -- disabled? --
mov r0, #0
@ -847,9 +787,6 @@ lfo_done:
upd_slot1_m
@ -- SLOT2+ --
cmp r8, #(2<<EG_SH) @ op mem or sample?
bge crl_algo_done
and r0, r4, #7
PIC_XB(,r0, lsl #2)
nop
@ -915,13 +852,7 @@ crl_algo_done:
stmia lr, {r1-r3,r5}
sub lr, lr, #0x10
crl_ff:
subs r8, r8, #(1<<EG_SH)
bge crl_smp_loop
crl_smp_loop_end:
add r8, r8, #(1<<EG_SH)
@ -- WRITE SAMPLE --
tst r0, r0
beq ctl_sample_skip