diff options
Diffstat (limited to 'src/chips/nuked_opl3.cpp')
-rw-r--r-- | src/chips/nuked_opl3.cpp | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/src/chips/nuked_opl3.cpp b/src/chips/nuked_opl3.cpp index 70fc525..fc6363d 100644 --- a/src/chips/nuked_opl3.cpp +++ b/src/chips/nuked_opl3.cpp @@ -1,26 +1,29 @@ #include "nuked_opl3.h" #include "nuked/nukedopl3.h" #include <cstring> +#include <cmath> + +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) +#include <zita-resampler/vresampler.h> +#endif NukedOPL3::NukedOPL3() : OPLChipBase() { m_chip = new opl3_chip; +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + m_resampler = new VResampler; +#endif reset(m_rate); } -NukedOPL3::NukedOPL3(const NukedOPL3 &c): - OPLChipBase(c) -{ - m_chip = new opl3_chip; - std::memset(m_chip, 0, sizeof(opl3_chip)); - reset(c.m_rate); -} - NukedOPL3::~NukedOPL3() { opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); delete chip_r; +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + delete m_resampler; +#endif } void NukedOPL3::setRate(uint32_t rate) @@ -29,6 +32,9 @@ void NukedOPL3::setRate(uint32_t rate) opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); std::memset(chip_r, 0, sizeof(opl3_chip)); OPL3_Reset(chip_r, rate); +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + m_resampler->setup(rate * (1.0 / 49716), 2, 48); +#endif } void NukedOPL3::reset() @@ -49,15 +55,34 @@ void NukedOPL3::writeReg(uint16_t addr, uint8_t data) int NukedOPL3::generate(int16_t *output, size_t frames) { +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + for(size_t i = 0; i < frames; ++i) + { + generateResampledHq(output); + output += 2; + } +#else opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); OPL3_GenerateStream(chip_r, output, (Bit32u)frames); +#endif return (int)frames; } int NukedOPL3::generateAndMix(int16_t *output, size_t frames) { +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + for(size_t i = 0; i < frames; ++i) + { + int16_t frame[2]; + generateResampledHq(frame); + output[0] += (int32_t)frame[0]; + output[1] += (int32_t)frame[1]; + output += 2; + } +#else opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); OPL3_GenerateStreamMix(chip_r, output, (Bit32u)frames); +#endif return (int)frames; } @@ -65,10 +90,15 @@ int NukedOPL3::generate32(int32_t *output, size_t frames) { opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); for(size_t i = 0; i < frames; ++i) { +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + (void)chip_r; + generateResampledHq32(output); +#else int16_t frame[2]; OPL3_GenerateResampled(chip_r, frame); output[0] = (int32_t)frame[0]; output[1] = (int32_t)frame[1]; +#endif output += 2; } return (int)frames; @@ -78,8 +108,14 @@ int NukedOPL3::generateAndMix32(int32_t *output, size_t frames) { opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); for(size_t i = 0; i < frames; ++i) { +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) + (void)chip_r; + int32_t frame[2]; + generateResampledHq32(frame); +#else int16_t frame[2]; OPL3_GenerateResampled(chip_r, frame); +#endif output[0] += (int32_t)frame[0]; output[1] += (int32_t)frame[1]; output += 2; @@ -87,6 +123,45 @@ int NukedOPL3::generateAndMix32(int32_t *output, size_t frames) return (int)frames; } +#if defined(ADLMIDI_ENABLE_HQ_RESAMPLER) +void NukedOPL3::generateResampledHq(int16_t *out) +{ + int32_t temps[2]; + generateResampledHq32(temps); + for(unsigned i = 0; i < 2; ++i) + { + int32_t temp = temps[i]; + temp = (temp > -32768) ? temp : -32768; + temp = (temp < 32767) ? temp : 32767; + out[i] = temp; + } +} + +void NukedOPL3::generateResampledHq32(int32_t *out) +{ + opl3_chip *chip_r = reinterpret_cast<opl3_chip*>(m_chip); + VResampler *rsm = m_resampler; + float f_in[2]; + float f_out[2]; + rsm->inp_count = 0; + rsm->inp_data = f_in; + rsm->out_count = 1; + rsm->out_data = f_out; + while(rsm->process(), rsm->out_count != 0) + { + int16_t in[2]; + OPL3_Generate(chip_r, in); + f_in[0] = (float)in[0], f_in[1] = (float)in[1]; + rsm->inp_count = 1; + rsm->inp_data = f_in; + rsm->out_count = 1; + rsm->out_data = f_out; + } + out[0] = std::lround(f_out[0]); + out[1] = std::lround(f_out[1]); +} +#endif + const char *NukedOPL3::emulatorName() { return "Nuked OPL3 (v 1.8)"; |