-
-
Save MooglyGuy/3f2499059e2b06a8e6a7b46d9514fe4b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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