Refactored sound code - slight speedup.

This commit is contained in:
TomW 2016-02-10 20:49:28 +00:00
commit 3a57341837
33 changed files with 706 additions and 535 deletions

View file

@ -258,6 +258,7 @@ void emu8k_outw(uint32_t addr, uint16_t val, void *p)
{
emu8k_t *emu8k = (emu8k_t *)p;
emu8k_update(emu8k);
/* pclog("emu8k_outw : addr=%08X reg=%i voice=%i val=%04X\n", addr, emu8k->cur_reg, emu8k->cur_voice, val);*/
//emu8k_outw : addr=00000A22 reg=3 voice=21 val=0265
addr -= 0x220;
@ -501,160 +502,172 @@ void emu8k_outb(uint32_t addr, uint8_t val, void *p)
emu8k_outw(addr, val, p);
}
void emu8k_poll(void *p)
void emu8k_update(emu8k_t *emu8k)
{
emu8k_t *emu8k = (emu8k_t *)p;
int c;
int32_t out_l = 0, out_r = 0;
emu8k->timer_count += (int)(TIMER_USEC * (1000000.0 / 44100.0));
for (c = 0; c < 32; c++)
int new_pos = (sound_pos_global * 44100) / 48000;
if (emu8k->pos < new_pos)
{
int32_t voice_l, voice_r;
int32_t dat;
int lfo1_vibrato, lfo2_vibrato;
int tremolo;
int32_t *buf;
int pos;
int c;
int32_t out_l = 0, out_r = 0;
buf = &emu8k->buffer[emu8k->pos*2];
tremolo = ((lfotable[(emu8k->voice[c].lfo1_count >> 8) & 4095] * emu8k->voice[c].lfo1_trem) * 4) >> 12;
for (pos = emu8k->pos; pos < new_pos; pos++)
emu8k->buffer[pos*2] = emu8k->buffer[pos*2 + 1] = 0;
if (freqtable[emu8k->voice[c].pitch] >> 32)
dat = EMU8K_READ(emu8k, emu8k->voice[c].addr >> 32);
else
dat = EMU8K_READ_INTERP(emu8k, emu8k->voice[c].addr >> 24);
dat = (dat * emu8k->voice[c].attenuation) >> 16;
dat = (dat * envtable[emu8k->voice[c].env_vol >> 9]) >> 16;
if ((emu8k->voice[c].ccca >> 28) || (emu8k->voice[c].cutoff != 0xff))
for (c = 0; c < 32; c++)
{
int cutoff = emu8k->voice[c].cutoff + ((emu8k->voice[c].menv_vol * emu8k->voice[c].fe_height) >> 20);
if (cutoff < 0)
cutoff = 0;
if (cutoff > 255)
cutoff = 255;
emu8k->voice[c].vhp = ((-emu8k->voice[c].vbp * emu8k->voice[c].q) >> 8) - emu8k->voice[c].vlp - dat;
emu8k->voice[c].vlp += (emu8k->voice[c].vbp * filt_w0[cutoff]) >> 8;
emu8k->voice[c].vbp += (emu8k->voice[c].vhp * filt_w0[cutoff]) >> 8;
if (emu8k->voice[c].vlp < -32767)
dat = -32767;
else if (emu8k->voice[c].vlp > 32767)
dat = 32767;
else
dat = (int16_t)emu8k->voice[c].vlp;
}
buf = &emu8k->buffer[emu8k->pos*2];
voice_l = (dat * emu8k->voice[c].vol_l) >> 7;
voice_r = (dat * emu8k->voice[c].vol_r) >> 7;
for (pos = emu8k->pos; pos < new_pos; pos++)
{
int32_t voice_l, voice_r;
int32_t dat;
int lfo1_vibrato, lfo2_vibrato;
int tremolo;
tremolo = ((lfotable[(emu8k->voice[c].lfo1_count >> 8) & 4095] * emu8k->voice[c].lfo1_trem) * 4) >> 12;
if (freqtable[emu8k->voice[c].pitch] >> 32)
dat = EMU8K_READ(emu8k, emu8k->voice[c].addr >> 32);
else
dat = EMU8K_READ_INTERP(emu8k, emu8k->voice[c].addr >> 24);
dat = (dat * emu8k->voice[c].attenuation) >> 16;
dat = (dat * envtable[emu8k->voice[c].env_vol >> 9]) >> 16;
out_l += voice_l * 8192;
out_r += voice_r * 8192;
if ((emu8k->voice[c].ccca >> 28) || (emu8k->voice[c].cutoff != 0xff))
{
int cutoff = emu8k->voice[c].cutoff + ((emu8k->voice[c].menv_vol * emu8k->voice[c].fe_height) >> 20);
if (cutoff < 0)
cutoff = 0;
if (cutoff > 255)
cutoff = 255;
switch (emu8k->voice[c].env_state)
{
case ENV_ATTACK:
emu8k->voice[c].env_vol += emu8k->voice[c].env_attack;
emu8k->voice[c].vtft |= 0xffff0000;
if (emu8k->voice[c].env_vol >= (1 << 21))
{
emu8k->voice[c].env_vol = 1 << 21;
emu8k->voice[c].env_state = ENV_DECAY;
}
break;
emu8k->voice[c].vhp = ((-emu8k->voice[c].vbp * emu8k->voice[c].q) >> 8) - emu8k->voice[c].vlp - dat;
emu8k->voice[c].vlp += (emu8k->voice[c].vbp * filt_w0[cutoff]) >> 8;
emu8k->voice[c].vbp += (emu8k->voice[c].vhp * filt_w0[cutoff]) >> 8;
if (emu8k->voice[c].vlp < -32767)
dat = -32767;
else if (emu8k->voice[c].vlp > 32767)
dat = 32767;
else
dat = (int16_t)emu8k->voice[c].vlp;
}
case ENV_DECAY:
emu8k->voice[c].env_vol -= emu8k->voice[c].env_decay;
emu8k->voice[c].vtft = (emu8k->voice[c].vtft & ~0xffff0000) | ((emu8k->voice[c].env_sustain >> 5) << 16);
if (emu8k->voice[c].env_vol <= emu8k->voice[c].env_sustain)
{
emu8k->voice[c].env_vol = emu8k->voice[c].env_sustain;
emu8k->voice[c].env_state = ENV_SUSTAIN;
}
break;
case ENV_RELEASE:
emu8k->voice[c].env_vol -= emu8k->voice[c].env_release;
emu8k->voice[c].vtft &= ~0xffff0000;
if (emu8k->voice[c].env_vol <= 0)
{
emu8k->voice[c].env_vol = 0;
emu8k->voice[c].env_state = ENV_STOPPED;
}
break;
}
if (emu8k->voice[c].env_vol >= (1 << 21))
emu8k->voice[c].cvcf &= ~0xffff0000;
else
emu8k->voice[c].cvcf = (emu8k->voice[c].cvcf & ~0xffff0000) | ((emu8k->voice[c].env_vol >> 5) << 16);
switch (emu8k->voice[c].menv_state)
{
case ENV_ATTACK:
emu8k->voice[c].menv_vol += emu8k->voice[c].menv_attack;
if (emu8k->voice[c].menv_vol >= (1 << 21))
{
emu8k->voice[c].menv_vol = 1 << 21;
emu8k->voice[c].menv_state = ENV_DECAY;
}
break;
voice_l = (dat * emu8k->voice[c].vol_l) >> 7;
voice_r = (dat * emu8k->voice[c].vol_r) >> 7;
case ENV_DECAY:
emu8k->voice[c].menv_vol -= emu8k->voice[c].menv_decay;
if (emu8k->voice[c].menv_vol <= emu8k->voice[c].menv_sustain)
{
emu8k->voice[c].menv_vol = emu8k->voice[c].menv_sustain;
emu8k->voice[c].menv_state = ENV_SUSTAIN;
}
break;
(*buf++) += voice_l * 8192;
(*buf++) += voice_r * 8192;
case ENV_RELEASE:
emu8k->voice[c].menv_vol -= emu8k->voice[c].menv_release;
if (emu8k->voice[c].menv_vol <= 0)
{
emu8k->voice[c].menv_vol = 0;
emu8k->voice[c].menv_state = ENV_STOPPED;
}
break;
}
switch (emu8k->voice[c].env_state)
{
case ENV_ATTACK:
emu8k->voice[c].env_vol += emu8k->voice[c].env_attack;
emu8k->voice[c].vtft |= 0xffff0000;
if (emu8k->voice[c].env_vol >= (1 << 21))
{
emu8k->voice[c].env_vol = 1 << 21;
emu8k->voice[c].env_state = ENV_DECAY;
}
break;
case ENV_DECAY:
emu8k->voice[c].env_vol -= emu8k->voice[c].env_decay;
emu8k->voice[c].vtft = (emu8k->voice[c].vtft & ~0xffff0000) | ((emu8k->voice[c].env_sustain >> 5) << 16);
if (emu8k->voice[c].env_vol <= emu8k->voice[c].env_sustain)
{
emu8k->voice[c].env_vol = emu8k->voice[c].env_sustain;
emu8k->voice[c].env_state = ENV_SUSTAIN;
}
break;
lfo1_vibrato = (lfotable[(emu8k->voice[c].lfo1_count >> 8) & 4095] * emu8k->voice[c].lfo1_fmmod) >> 9;
lfo2_vibrato = (lfotable[(emu8k->voice[c].lfo2_count >> 8) & 4095] * emu8k->voice[c].lfo2_fmmod) >> 9;
case ENV_RELEASE:
emu8k->voice[c].env_vol -= emu8k->voice[c].env_release;
emu8k->voice[c].vtft &= ~0xffff0000;
if (emu8k->voice[c].env_vol <= 0)
{
emu8k->voice[c].env_vol = 0;
emu8k->voice[c].env_state = ENV_STOPPED;
}
break;
}
if (emu8k->voice[c].env_vol >= (1 << 21))
emu8k->voice[c].cvcf &= ~0xffff0000;
else
emu8k->voice[c].cvcf = (emu8k->voice[c].cvcf & ~0xffff0000) | ((emu8k->voice[c].env_vol >> 5) << 16);
switch (emu8k->voice[c].menv_state)
{
case ENV_ATTACK:
emu8k->voice[c].menv_vol += emu8k->voice[c].menv_attack;
if (emu8k->voice[c].menv_vol >= (1 << 21))
{
emu8k->voice[c].menv_vol = 1 << 21;
emu8k->voice[c].menv_state = ENV_DECAY;
}
break;
case ENV_DECAY:
emu8k->voice[c].menv_vol -= emu8k->voice[c].menv_decay;
if (emu8k->voice[c].menv_vol <= emu8k->voice[c].menv_sustain)
{
emu8k->voice[c].menv_vol = emu8k->voice[c].menv_sustain;
emu8k->voice[c].menv_state = ENV_SUSTAIN;
}
break;
case ENV_RELEASE:
emu8k->voice[c].menv_vol -= emu8k->voice[c].menv_release;
if (emu8k->voice[c].menv_vol <= 0)
{
emu8k->voice[c].menv_vol = 0;
emu8k->voice[c].menv_state = ENV_STOPPED;
}
break;
}
lfo1_vibrato = (lfotable[(emu8k->voice[c].lfo1_count >> 8) & 4095] * emu8k->voice[c].lfo1_fmmod) >> 9;
lfo2_vibrato = (lfotable[(emu8k->voice[c].lfo2_count >> 8) & 4095] * emu8k->voice[c].lfo2_fmmod) >> 9;
emu8k->voice[c].addr += freqtable[(emu8k->voice[c].pitch + lfo1_vibrato + lfo2_vibrato) & 0xffff];
if (emu8k->voice[c].addr >= emu8k->voice[c].loop_end)
emu8k->voice[c].addr -= (emu8k->voice[c].loop_end - emu8k->voice[c].loop_start);
emu8k->voice[c].addr += freqtable[(emu8k->voice[c].pitch + lfo1_vibrato + lfo2_vibrato) & 0xffff];
if (emu8k->voice[c].addr >= emu8k->voice[c].loop_end)
emu8k->voice[c].addr -= (emu8k->voice[c].loop_end - emu8k->voice[c].loop_start);
emu8k->voice[c].lfo1_count += (emu8k->voice[c].tremfrq & 0xff);
emu8k->voice[c].lfo2_count += (emu8k->voice[c].fm2frq2 & 0xff);
}
out_l >>= 15;
out_r >>= 15;
if (out_l < -32768)
emu8k->out_l = -32768;
else if (out_l > 32767)
emu8k->out_l = 32767;
else
emu8k->out_l = out_l;
emu8k->voice[c].lfo1_count += (emu8k->voice[c].tremfrq & 0xff);
emu8k->voice[c].lfo2_count += (emu8k->voice[c].fm2frq2 & 0xff);
}
}
buf = &emu8k->buffer[emu8k->pos*2];
if (out_r < -32768)
emu8k->out_r = -32768;
else if (out_r > 32767)
emu8k->out_r = 32767;
else
emu8k->out_r = out_r;
for (pos = emu8k->pos; pos < new_pos; pos++)
{
buf[0] >>= 15;
buf[1] >>= 15;
emu8k->wc++;
}
if (buf[0] < -32768)
buf[0] = -32768;
else if (buf[0] > 32767)
buf[0] = 32767;
if (buf[1] < -32768)
buf[1] = -32768;
else if (buf[1] > 32767)
buf[1] = 32767;
buf += 2;
}
void emu8k_poll_getsamp(emu8k_t *emu8k, int16_t *l, int16_t *r)
{
*l = emu8k->out_l;
*r = emu8k->out_r;
emu8k->wc += (new_pos - emu8k->pos);
emu8k->pos = new_pos;
}
}
void emu8k_init(emu8k_t *emu8k, int onboard_ram)
@ -689,8 +702,6 @@ void emu8k_init(emu8k_t *emu8k, int onboard_ram)
io_sethandler(0x0a20, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k);
io_sethandler(0x0e20, 0x0004, emu8k_inb, emu8k_inw, NULL, emu8k_outb, emu8k_outw, NULL, emu8k);
timer_add(emu8k_poll, &emu8k->timer_count, TIMER_ALWAYS_ENABLED, emu8k);
/*Create frequency table*/
for (c = 0; c < 0x10000; c++)
{