mirror of
https://github.com/holub/mame
synced 2025-04-26 10:13:37 +03:00
Merge pull request #5842 from cam900/es5506_volume
es5506.cpp : Fix volume, Reduce unnecessary values
This commit is contained in:
commit
77ada54b65
@ -294,17 +294,8 @@ void es5506_device::device_start()
|
|||||||
m_sample_rate = m_master_clock / (16 * (m_active_voices + 1));
|
m_sample_rate = m_master_clock / (16 * (m_active_voices + 1));
|
||||||
m_stream->set_sample_rate(m_sample_rate);
|
m_stream->set_sample_rate(m_sample_rate);
|
||||||
|
|
||||||
/* init the voices */
|
|
||||||
// 21 bit integer and 11 bit fraction
|
// 21 bit integer and 11 bit fraction
|
||||||
get_accum_mask(ADDRESS_INTEGER_BIT_ES5506, ADDRESS_FRAC_BIT_ES5506);
|
get_accum_mask(ADDRESS_INTEGER_BIT_ES5506, ADDRESS_FRAC_BIT_ES5506);
|
||||||
for (int j = 0; j < 32; j++)
|
|
||||||
{
|
|
||||||
m_voice[j].index = j;
|
|
||||||
m_voice[j].control = CONTROL_STOPMASK;
|
|
||||||
m_voice[j].lvol = get_shifted_volume(0xffff); // 16 bit volume
|
|
||||||
m_voice[j].rvol = get_shifted_volume(0xffff);
|
|
||||||
m_voice[j].exbank = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register save */
|
/* register save */
|
||||||
save_item(NAME(m_write_latch));
|
save_item(NAME(m_write_latch));
|
||||||
@ -409,17 +400,8 @@ void es5505_device::device_start()
|
|||||||
/* initialize the rest of the structure */
|
/* initialize the rest of the structure */
|
||||||
m_channels = channels;
|
m_channels = channels;
|
||||||
|
|
||||||
/* init the voices */
|
|
||||||
// 20 bit integer and 9 bit fraction
|
// 20 bit integer and 9 bit fraction
|
||||||
get_accum_mask(ADDRESS_INTEGER_BIT_ES5505, ADDRESS_FRAC_BIT_ES5505);
|
get_accum_mask(ADDRESS_INTEGER_BIT_ES5505, ADDRESS_FRAC_BIT_ES5505);
|
||||||
for (int j = 0; j < 32; j++)
|
|
||||||
{
|
|
||||||
m_voice[j].index = j;
|
|
||||||
m_voice[j].control = CONTROL_STOPMASK;
|
|
||||||
m_voice[j].lvol = get_shifted_volume(0xff); // 8 bit volume
|
|
||||||
m_voice[j].rvol = get_shifted_volume(0xff);
|
|
||||||
m_voice[j].exbank = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
}
|
}
|
||||||
@ -484,8 +466,7 @@ void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 m
|
|||||||
}
|
}
|
||||||
|
|
||||||
const u32 volume_bit = (exponent_bit + mantissa_bit);
|
const u32 volume_bit = (exponent_bit + mantissa_bit);
|
||||||
m_volume_shift = FINE_VOLUME_BIT - total_volume_bit;
|
m_volume_shift = total_volume_bit - volume_bit;
|
||||||
m_volume_shift_int = FINE_VOLUME_BIT - volume_bit;
|
|
||||||
const u32 volume_len = 1 << volume_bit;
|
const u32 volume_len = 1 << volume_bit;
|
||||||
/* allocate volume lookup table */
|
/* allocate volume lookup table */
|
||||||
m_volume_lookup = make_unique_clear<u32[]>(volume_len);
|
m_volume_lookup = make_unique_clear<u32[]>(volume_len);
|
||||||
@ -506,6 +487,16 @@ void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 m
|
|||||||
m_volume_lookup[i] = (mantissa << mantissa_shift) >> (exponent_shift - exponent);
|
m_volume_lookup[i] = (mantissa << mantissa_shift) >> (exponent_shift - exponent);
|
||||||
}
|
}
|
||||||
m_volume_acc_shift = (16 + exponent_mask) - VOLUME_ACC_BIT;
|
m_volume_acc_shift = (16 + exponent_mask) - VOLUME_ACC_BIT;
|
||||||
|
|
||||||
|
/* init the voices */
|
||||||
|
for (int j = 0; j < 32; j++)
|
||||||
|
{
|
||||||
|
m_voice[j].index = j;
|
||||||
|
m_voice[j].control = CONTROL_STOPMASK;
|
||||||
|
m_voice[j].lvol = (1 << total_volume_bit - 1);
|
||||||
|
m_voice[j].rvol = (1 << total_volume_bit - 1);
|
||||||
|
m_voice[j].exbank = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
@ -639,21 +630,17 @@ inline void es5506_device::update_envelopes(es550x_voice *voice)
|
|||||||
/* ramp left volume */
|
/* ramp left volume */
|
||||||
if (voice->lvramp)
|
if (voice->lvramp)
|
||||||
{
|
{
|
||||||
voice->lvol = get_shifted_volume_res(voice->lvol);
|
|
||||||
voice->lvol += (int8_t)voice->lvramp;
|
voice->lvol += (int8_t)voice->lvramp;
|
||||||
if ((s32)voice->lvol < 0) voice->lvol = 0;
|
if ((s32)voice->lvol < 0) voice->lvol = 0;
|
||||||
else if (voice->lvol > volume_max) voice->lvol = volume_max;
|
else if (voice->lvol > volume_max) voice->lvol = volume_max;
|
||||||
voice->lvol = get_shifted_volume(voice->lvol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ramp right volume */
|
/* ramp right volume */
|
||||||
if (voice->rvramp)
|
if (voice->rvramp)
|
||||||
{
|
{
|
||||||
voice->rvol = get_shifted_volume_res(voice->rvol);
|
|
||||||
voice->rvol += (int8_t)voice->rvramp;
|
voice->rvol += (int8_t)voice->rvramp;
|
||||||
if ((s32)voice->rvol < 0) voice->rvol = 0;
|
if ((s32)voice->rvol < 0) voice->rvol = 0;
|
||||||
else if (voice->rvol > volume_max) voice->rvol = volume_max;
|
else if (voice->rvol > volume_max) voice->rvol = volume_max;
|
||||||
voice->rvol = get_shifted_volume(voice->rvol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ramp k1 filter constant */
|
/* ramp k1 filter constant */
|
||||||
@ -1218,8 +1205,8 @@ inline void es5506_device::reg_write_low(es550x_voice *voice, offs_t offset, u32
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10/8: /* LVOL */
|
case 0x10/8: /* LVOL */
|
||||||
voice->lvol = get_shifted_volume(data & 0xffff); // low 4 bit is used for finer envelope control
|
voice->lvol = data & 0xffff; // low 4 bit is used for finer envelope control
|
||||||
LOG("voice %d, left vol=%04x\n", m_current_page & 0x1f, get_shifted_volume_res(voice->lvol));
|
LOG("voice %d, left vol=%04x\n", m_current_page & 0x1f, voice->lvol);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x18/8: /* LVRAMP */
|
case 0x18/8: /* LVRAMP */
|
||||||
@ -1228,8 +1215,8 @@ inline void es5506_device::reg_write_low(es550x_voice *voice, offs_t offset, u32
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x20/8: /* RVOL */
|
case 0x20/8: /* RVOL */
|
||||||
voice->rvol = get_shifted_volume(data & 0xffff); // low 4 bit is used for finer envelope control
|
voice->rvol = data & 0xffff; // low 4 bit is used for finer envelope control
|
||||||
LOG("voice %d, right vol=%04x\n", m_current_page & 0x1f, get_shifted_volume_res(voice->rvol));
|
LOG("voice %d, right vol=%04x\n", m_current_page & 0x1f, voice->rvol);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x28/8: /* RVRAMP */
|
case 0x28/8: /* RVRAMP */
|
||||||
@ -1485,7 +1472,7 @@ inline u32 es5506_device::reg_read_low(es550x_voice *voice, offs_t offset)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10/8: /* LVOL */
|
case 0x10/8: /* LVOL */
|
||||||
result = get_shifted_volume_res(voice->lvol);
|
result = voice->lvol;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x18/8: /* LVRAMP */
|
case 0x18/8: /* LVRAMP */
|
||||||
@ -1493,7 +1480,7 @@ inline u32 es5506_device::reg_read_low(es550x_voice *voice, offs_t offset)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x20/8: /* RVOL */
|
case 0x20/8: /* RVOL */
|
||||||
result = get_shifted_volume_res(voice->rvol);
|
result = voice->rvol;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x28/8: /* RVRAMP */
|
case 0x28/8: /* RVRAMP */
|
||||||
@ -1771,14 +1758,14 @@ inline void es5505_device::reg_write_low(es550x_voice *voice, offs_t offset, u16
|
|||||||
|
|
||||||
case 0x08: /* LVOL */
|
case 0x08: /* LVOL */
|
||||||
if (ACCESSING_BITS_8_15)
|
if (ACCESSING_BITS_8_15)
|
||||||
voice->lvol = (voice->lvol & ~0xff00) | (data & 0xff00);
|
voice->lvol = (voice->lvol & ~0xff) | ((data & 0xff00) >> 8);
|
||||||
LOG("%s:voice %d, left vol=%02x\n", machine().describe_context(), m_current_page & 0x1f, get_shifted_volume_res(voice->lvol));
|
LOG("%s:voice %d, left vol=%02x\n", machine().describe_context(), m_current_page & 0x1f, voice->lvol);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x09: /* RVOL */
|
case 0x09: /* RVOL */
|
||||||
if (ACCESSING_BITS_8_15)
|
if (ACCESSING_BITS_8_15)
|
||||||
voice->rvol = (voice->rvol & ~0xff00) | (data & 0xff00);
|
voice->rvol = (voice->rvol & ~0xff) | ((data & 0xff00) >> 8);
|
||||||
LOG("%s:voice %d, right vol=%02x\n", machine().describe_context(), m_current_page & 0x1f, get_shifted_volume_res(voice->rvol));
|
LOG("%s:voice %d, right vol=%02x\n", machine().describe_context(), m_current_page & 0x1f, voice->rvol);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0a: /* ACC (hi) */
|
case 0x0a: /* ACC (hi) */
|
||||||
@ -2032,11 +2019,11 @@ inline u16 es5505_device::reg_read_low(es550x_voice *voice, offs_t offset)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x08: /* LVOL */
|
case 0x08: /* LVOL */
|
||||||
result = voice->lvol;
|
result = voice->lvol << 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x09: /* RVOL */
|
case 0x09: /* RVOL */
|
||||||
result = voice->rvol;
|
result = voice->rvol << 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0a: /* ACC (hi) */
|
case 0x0a: /* ACC (hi) */
|
||||||
|
@ -35,12 +35,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// constants for volumes
|
// constants for volumes
|
||||||
const u32 FINE_VOLUME_BIT = 16;
|
const s8 VOLUME_ACC_BIT = 20;
|
||||||
|
|
||||||
const u32 VOLUME_ACC_BIT = 20;
|
|
||||||
|
|
||||||
// constants for address
|
// constants for address
|
||||||
const u32 ADDRESS_FRAC_BIT = 11;
|
const s8 ADDRESS_FRAC_BIT = 11;
|
||||||
|
|
||||||
// struct describing a single playing voice
|
// struct describing a single playing voice
|
||||||
struct es550x_voice
|
struct es550x_voice
|
||||||
@ -98,9 +96,7 @@ protected:
|
|||||||
template<typename T, typename U> inline T lshift_signed(T val, U shift) { return (shift >= 0) ? val << shift : val >> (-shift); }
|
template<typename T, typename U> inline T lshift_signed(T val, U shift) { return (shift >= 0) ? val << shift : val >> (-shift); }
|
||||||
template<typename T, typename U> inline T rshift_signed(T val, U shift) { return (shift >= 0) ? val >> shift : val << (-shift); }
|
template<typename T, typename U> inline T rshift_signed(T val, U shift) { return (shift >= 0) ? val >> shift : val << (-shift); }
|
||||||
|
|
||||||
inline u64 get_shifted_volume_res(u64 volume) { return rshift_signed<u64, s8>(volume, m_volume_shift); }
|
inline u64 get_volume(u32 volume) { return m_volume_lookup[rshift_signed<u32, s8>(volume, m_volume_shift)]; }
|
||||||
inline u64 get_shifted_volume(u64 volume) { return lshift_signed<u64, s8>(volume, m_volume_shift); }
|
|
||||||
inline u64 get_volume(u32 volume) { return m_volume_lookup[rshift_signed<u32, s8>(volume, m_volume_shift_int)]; }
|
|
||||||
|
|
||||||
inline u64 get_address_acc_shifted_val(u64 val, int bias = 0) { return lshift_signed<u64, s8>(val, m_address_acc_shift - bias); }
|
inline u64 get_address_acc_shifted_val(u64 val, int bias = 0) { return lshift_signed<u64, s8>(val, m_address_acc_shift - bias); }
|
||||||
inline u64 get_address_acc_res(u64 val, int bias = 0) { return rshift_signed<u64, s8>(val, m_address_acc_shift - bias); }
|
inline u64 get_address_acc_res(u64 val, int bias = 0) { return rshift_signed<u64, s8>(val, m_address_acc_shift - bias); }
|
||||||
@ -128,7 +124,6 @@ protected:
|
|||||||
u64 m_address_acc_mask;
|
u64 m_address_acc_mask;
|
||||||
|
|
||||||
s8 m_volume_shift;
|
s8 m_volume_shift;
|
||||||
s8 m_volume_shift_int;
|
|
||||||
s64 m_volume_acc_shift;
|
s64 m_volume_acc_shift;
|
||||||
|
|
||||||
u8 m_current_page; /* current register page */
|
u8 m_current_page; /* current register page */
|
||||||
@ -173,9 +168,9 @@ protected:
|
|||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
|
|
||||||
const u32 VOLUME_BIT_ES5506 = 16;
|
const s8 VOLUME_BIT_ES5506 = 16;
|
||||||
const u32 ADDRESS_INTEGER_BIT_ES5506 = 21;
|
const s8 ADDRESS_INTEGER_BIT_ES5506 = 21;
|
||||||
const u32 ADDRESS_FRAC_BIT_ES5506 = 11;
|
const s8 ADDRESS_FRAC_BIT_ES5506 = 11;
|
||||||
|
|
||||||
virtual inline u32 get_bank(u32 control) override { return (control >> 14) & 3; }
|
virtual inline u32 get_bank(u32 control) override { return (control >> 14) & 3; }
|
||||||
virtual inline u32 get_ca(u32 control) override { return (control >> 10) & 7; }
|
virtual inline u32 get_ca(u32 control) override { return (control >> 10) & 7; }
|
||||||
@ -218,9 +213,9 @@ protected:
|
|||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
|
|
||||||
const u32 VOLUME_BIT_ES5505 = 8;
|
const s8 VOLUME_BIT_ES5505 = 8;
|
||||||
const u32 ADDRESS_INTEGER_BIT_ES5505 = 20;
|
const s8 ADDRESS_INTEGER_BIT_ES5505 = 20;
|
||||||
const u32 ADDRESS_FRAC_BIT_ES5505 = 9;
|
const s8 ADDRESS_FRAC_BIT_ES5505 = 9;
|
||||||
|
|
||||||
virtual inline u32 get_lp(u32 control) override { return (control >> 10) & LP_MASK; }
|
virtual inline u32 get_lp(u32 control) override { return (control >> 10) & LP_MASK; }
|
||||||
virtual inline u32 get_ca(u32 control) override { return (control >> 8) & 3; }
|
virtual inline u32 get_ca(u32 control) override { return (control >> 8) & 3; }
|
||||||
|
Loading…
Reference in New Issue
Block a user