Skip to content

Instantly share code, notes, and snippets.

@MooglyGuy
Created May 14, 2023 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MooglyGuy/3f2499059e2b06a8e6a7b46d9514fe4b to your computer and use it in GitHub Desktop.
Save MooglyGuy/3f2499059e2b06a8e6a7b46d9514fe4b to your computer and use it in GitHub Desktop.
diff --git a/src/devices/sound/es5506.cpp b/src/devices/sound/es5506.cpp
index df690dde132..770cc3b5ebf 100644
--- a/src/devices/sound/es5506.cpp
+++ b/src/devices/sound/es5506.cpp
@@ -513,6 +513,56 @@ void es550x_device::get_accum_mask(u32 address_integer, u32 address_frac)
m_address_acc_mask |= ((1 << m_address_acc_shift) - 1);
}
+/**********************************************************************************************
+
+ helper functions
+
+***********************************************************************************************/
+
+template<typename ValueType, typename ShiftType>
+inline ValueType es550x_device::lshift_signed(ValueType val, ShiftType shift)
+{
+ return (shift >= 0) ? val << shift : val >> (-shift);
+}
+
+template<typename ValueType, typename ShiftType>
+inline ValueType es550x_device::rshift_signed(ValueType val, ShiftType shift)
+{
+ return (shift >= 0) ? val >> shift : val << (-shift);
+}
+
+inline u64 es550x_device::get_volume(u32 volume)
+{
+ return m_volume_lookup[rshift_signed<u32, s8>(volume, m_volume_shift)];
+}
+
+inline u64 es550x_device::get_address_acc_shifted_val(u64 val, int bias)
+{
+ return lshift_signed<u64, s8>(val, m_address_acc_shift - bias);
+}
+
+inline u64 es550x_device::get_address_acc_res(u64 val, int bias)
+{
+ return rshift_signed<u64, s8>(val, m_address_acc_shift - bias);
+}
+
+inline u64 es550x_device::get_integer_addr(u64 accum, s32 bias)
+{
+ return ((accum + (bias << ADDRESS_FRAC_BIT)) & m_address_acc_mask) >> ADDRESS_FRAC_BIT;
+}
+
+inline u64 es550x_device::get_integer_addr_clamped(es550x_voice *voice, u64 accum, s32 bias)
+{
+ u64 advanced_accum = accum + (bias << ADDRESS_FRAC_BIT);
+ if (advanced_accum > voice->end)
+ advanced_accum = accum;
+ return (advanced_accum & m_address_acc_mask) >> ADDRESS_FRAC_BIT;
+}
+
+inline s64 es550x_device::get_sample(s32 sample, u32 volume)
+{
+ return rshift_signed<s64, s8>(sample * get_volume(volume), m_volume_acc_shift);
+}
/**********************************************************************************************
@@ -837,7 +887,7 @@ void es550x_device::generate_ulaw(es550x_voice *voice, s32 *dest)
{
// fetch two samples
s32 val1 = read_sample(voice, get_integer_addr(accum));
- s32 val2 = read_sample(voice, get_integer_addr(accum, 1));
+ s32 val2 = read_sample(voice, get_integer_addr_clamped(voice, accum, 1));
// decompress u-law
val1 = m_ulaw_lookup[val1 >> (16 - ULAW_MAXBITS)];
@@ -867,7 +917,7 @@ void es550x_device::generate_ulaw(es550x_voice *voice, s32 *dest)
{
// fetch two samples
s32 val1 = read_sample(voice, get_integer_addr(accum));
- s32 val2 = read_sample(voice, get_integer_addr(accum, 1));
+ s32 val2 = read_sample(voice, get_integer_addr_clamped(voice, accum, 1));
// decompress u-law
val1 = m_ulaw_lookup[val1 >> (16 - ULAW_MAXBITS)];
@@ -923,7 +973,7 @@ void es550x_device::generate_pcm(es550x_voice *voice, s32 *dest)
{
// fetch two samples
s32 val1 = (s16)read_sample(voice, get_integer_addr(accum));
- s32 val2 = (s16)read_sample(voice, get_integer_addr(accum, 1));
+ s32 val2 = (s16)read_sample(voice, get_integer_addr_clamped(voice, accum, 1));
// interpolate
val1 = interpolate(val1, val2, accum);
@@ -949,7 +999,7 @@ void es550x_device::generate_pcm(es550x_voice *voice, s32 *dest)
{
// fetch two samples
s32 val1 = (s16)read_sample(voice, get_integer_addr(accum));
- s32 val2 = (s16)read_sample(voice, get_integer_addr(accum, 1));
+ s32 val2 = (s16)read_sample(voice, get_integer_addr_clamped(voice, accum, 1));
// interpolate
val1 = interpolate(val1, val2, accum);
diff --git a/src/devices/sound/es5506.h b/src/devices/sound/es5506.h
index 73f5c0a3c8f..5c2b8201a03 100644
--- a/src/devices/sound/es5506.h
+++ b/src/devices/sound/es5506.h
@@ -95,16 +95,17 @@ protected:
virtual inline u32 get_ca(u32 control) { return 0; }
virtual inline u32 get_lp(u32 control) { return 0; }
- 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 ValueType, typename ShiftType> inline ValueType lshift_signed(ValueType val, ShiftType shift);
+ template<typename ValueType, typename ShiftType> inline ValueType rshift_signed(ValueType val, ShiftType shift);
- inline u64 get_volume(u32 volume) { return m_volume_lookup[rshift_signed<u32, s8>(volume, m_volume_shift)]; }
+ inline u64 get_volume(u32 volume);
- 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_integer_addr(u64 accum, s32 bias = 0) { return ((accum + (bias << ADDRESS_FRAC_BIT)) & m_address_acc_mask) >> ADDRESS_FRAC_BIT; }
+ inline u64 get_address_acc_shifted_val(u64 val, int bias = 0);
+ inline u64 get_address_acc_res(u64 val, int bias = 0);
+ inline u64 get_integer_addr(u64 accum, s32 bias = 0);
+ inline u64 get_integer_addr_clamped(es550x_voice *voice, u64 accum, s32 bias = 0);
- inline s64 get_sample(s32 sample, u32 volume) { return rshift_signed<s64, s8>(sample * get_volume(volume), m_volume_acc_shift); }
+ inline s64 get_sample(s32 sample, u32 volume);
inline s32 interpolate(s32 sample1, s32 sample2, u64 accum);
inline void apply_filters(es550x_voice *voice, s32 &sample);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment