aboutsummaryrefslogtreecommitdiff
path: root/src/chips/opl_chip_base.tcc
diff options
context:
space:
mode:
Diffstat (limited to 'src/chips/opl_chip_base.tcc')
-rw-r--r--src/chips/opl_chip_base.tcc84
1 files changed, 81 insertions, 3 deletions
diff --git a/src/chips/opl_chip_base.tcc b/src/chips/opl_chip_base.tcc
index 58145bc..48ad103 100644
--- a/src/chips/opl_chip_base.tcc
+++ b/src/chips/opl_chip_base.tcc
@@ -5,9 +5,22 @@
#include <zita-resampler/vresampler.h>
#endif
+#if !defined(LIKELY) && defined(__GNUC__)
+#define LIKELY(x) __builtin_expect((x), 1)
+#elif !defined(LIKELY)
+#define LIKELY(x) (x)
+#endif
+
+#if !defined(UNLIKELY) && defined(__GNUC__)
+#define UNLIKELY(x) __builtin_expect((x), 0)
+#elif !defined(UNLIKELY)
+#define UNLIKELY(x) (x)
+#endif
+
/* OPLChipBase */
inline OPLChipBase::OPLChipBase() :
+ m_id(0),
m_rate(44100)
{
}
@@ -20,7 +33,12 @@ inline OPLChipBase::~OPLChipBase()
template <class T>
OPLChipBaseT<T>::OPLChipBaseT()
- : OPLChipBase()
+ : OPLChipBase(),
+ m_runningAtPcmRate(false)
+#if defined(ADLMIDI_AUDIO_TICK_HANDLER)
+ ,
+ m_audioTickHandlerInstance(NULL)
+#endif
{
#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
m_resampler = new VResampler;
@@ -37,6 +55,33 @@ OPLChipBaseT<T>::~OPLChipBaseT()
}
template <class T>
+bool OPLChipBaseT<T>::isRunningAtPcmRate() const
+{
+ return m_runningAtPcmRate;
+}
+
+template <class T>
+bool OPLChipBaseT<T>::setRunningAtPcmRate(bool r)
+{
+ if(r != m_runningAtPcmRate)
+ {
+ if(r && !static_cast<T *>(this)->canRunAtPcmRate())
+ return false;
+ m_runningAtPcmRate = r;
+ static_cast<T *>(this)->setRate(m_rate);
+ }
+ return true;
+}
+
+#if defined(ADLMIDI_AUDIO_TICK_HANDLER)
+template <class T>
+void OPLChipBaseT<T>::setAudioTickHandlerInstance(void *instance)
+{
+ m_audioTickHandlerInstance = instance;
+}
+#endif
+
+template <class T>
void OPLChipBaseT<T>::setRate(uint32_t rate)
{
uint32_t oldRate = m_rate;
@@ -48,6 +93,12 @@ void OPLChipBaseT<T>::setRate(uint32_t rate)
}
template <class T>
+uint32_t OPLChipBaseT<T>::effectiveRate() const
+{
+ return m_runningAtPcmRate ? m_rate : (uint32_t)nativeRate;
+}
+
+template <class T>
void OPLChipBaseT<T>::reset()
{
resetResampler();
@@ -119,6 +170,15 @@ void OPLChipBaseT<T>::generateAndMix32(int32_t *output, size_t frames)
}
template <class T>
+void OPLChipBaseT<T>::nativeTick(int16_t *frame)
+{
+#if defined(ADLMIDI_AUDIO_TICK_HANDLER)
+ adl_audioTickHandler(m_audioTickHandlerInstance, m_id, effectiveRate());
+#endif
+ static_cast<T *>(this)->nativeGenerate(frame);
+}
+
+template <class T>
void OPLChipBaseT<T>::setupResampler(uint32_t rate)
{
#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER)
@@ -147,6 +207,15 @@ void OPLChipBaseT<T>::resetResampler()
template <class T>
void OPLChipBaseT<T>::resampledGenerate(int32_t *output)
{
+ if(UNLIKELY(m_runningAtPcmRate))
+ {
+ int16_t in[2];
+ static_cast<T *>(this)->nativeTick(in);
+ output[0] = (int32_t)in[0] * T::resamplerPreAmplify / T::resamplerPostAttenuate;
+ output[1] = (int32_t)in[1] * T::resamplerPreAmplify / T::resamplerPostAttenuate;
+ return;
+ }
+
VResampler *rsm = m_resampler;
float scale = (float)T::resamplerPreAmplify /
(float)T::resamplerPostAttenuate;
@@ -159,7 +228,7 @@ void OPLChipBaseT<T>::resampledGenerate(int32_t *output)
while(rsm->process(), rsm->out_count != 0)
{
int16_t in[2];
- static_cast<T *>(this)->nativeGenerate(in);
+ static_cast<T *>(this)->nativeTick(in);
f_in[0] = scale * (float)in[0];
f_in[1] = scale * (float)in[1];
rsm->inp_count = 1;
@@ -174,6 +243,15 @@ void OPLChipBaseT<T>::resampledGenerate(int32_t *output)
template <class T>
void OPLChipBaseT<T>::resampledGenerate(int32_t *output)
{
+ if(UNLIKELY(m_runningAtPcmRate))
+ {
+ int16_t in[2];
+ static_cast<T *>(this)->nativeTick(in);
+ output[0] = (int32_t)in[0] * T::resamplerPreAmplify / T::resamplerPostAttenuate;
+ output[1] = (int32_t)in[1] * T::resamplerPreAmplify / T::resamplerPostAttenuate;
+ return;
+ }
+
int32_t samplecnt = m_samplecnt;
const int32_t rateratio = m_rateratio;
while(samplecnt >= rateratio)
@@ -181,7 +259,7 @@ void OPLChipBaseT<T>::resampledGenerate(int32_t *output)
m_oldsamples[0] = m_samples[0];
m_oldsamples[1] = m_samples[1];
int16_t buffer[2];
- static_cast<T *>(this)->nativeGenerate(buffer);
+ static_cast<T *>(this)->nativeTick(buffer);
m_samples[0] = buffer[0] * T::resamplerPreAmplify;
m_samples[1] = buffer[1] * T::resamplerPreAmplify;
samplecnt -= rateratio;