Skip to content

Commit

Permalink
Updated libOPNMIDI
Browse files Browse the repository at this point in the history
  • Loading branch information
Wohlstand committed Jul 10, 2023
1 parent febe4e7 commit b8c11aa
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 21 deletions.
4 changes: 4 additions & 0 deletions OPNMIDI-Player/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ if(MSVC)
if(COMPILER_SUPPORTS_CXX14)
set(FLAG_CPP14 "/std:c++14")
endif()
if(MSVC_VERSION LESS 1910)
unset(COMPILER_SUPPORTS_CXX14) # MSVC older than 2017 fails to build YMFM
endif()
else()
check_cxx_compiler_flag("-std=c++14" COMPILER_SUPPORTS_CXX14)
if(COMPILER_SUPPORTS_CXX14)
Expand Down Expand Up @@ -228,6 +231,7 @@ file(GLOB libOPNMIDI_HEADERS
${libOPNMIDI_SOURCE_DIR}/src/chips/nuked/*.h
${libOPNMIDI_SOURCE_DIR}/src/chips/pmdwin/*.h
${libOPNMIDI_SOURCE_DIR}/src/chips/ymfm/*.h
${libOPNMIDI_SOURCE_DIR}/src/chips/ymfm/*.hpp
)
list(APPEND libOPNMIDI_SOURCES ${libOPNMIDI_HEADERS})

Expand Down
3 changes: 2 additions & 1 deletion OPNMIDI-Player/src/main/cpp/src/chips/gens_opn2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ void GensOPN2::nativeGenerateN(int16_t *output, size_t frames)
//TODO
// chip->updateDacAndTimers(bufL, bufR, frames);

for (size_t i = 0; i < 2 * frames; ++i) {
for (size_t i = 0; i < 2 * frames; ++i)
{
int32_t sample = ((i & 1) ? bufR : bufL)[i / 2];
sample /= 4; // has too high volume, attenuation needed
sample = (sample < INT16_MIN) ? INT16_MIN : sample;
Expand Down
2 changes: 1 addition & 1 deletion OPNMIDI-Player/src/main/cpp/src/chips/ymfm/ymfm_adpcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class adpcm_a_registers
void save_restore(ymfm_saved_state &state);

// map channel number to register offset
static constexpr uint32_t channel_offset(uint32_t chnum)
static inline uint32_t channel_offset(uint32_t chnum)
{
assert(chnum < CHANNELS);
return chnum;
Expand Down
18 changes: 16 additions & 2 deletions OPNMIDI-Player/src/main/cpp/src/chips/ymfm/ymfm_fm.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,14 @@ class fm_registers_base
protected:
// helper to encode four operator numbers into a 32-bit value in the
// operator maps for each register class
static constexpr uint32_t operator_list(uint8_t o1 = 0xff, uint8_t o2 = 0xff, uint8_t o3 = 0xff, uint8_t o4 = 0xff)
static inline uint32_t operator_list(uint8_t o1 = 0xff, uint8_t o2 = 0xff, uint8_t o3 = 0xff, uint8_t o4 = 0xff)
{
return o1 | (o2 << 8) | (o3 << 16) | (o4 << 24);
}

// helper to apply KSR to the raw ADSR rate, ignoring ksr if the
// raw value is 0, and clamping to 63
static constexpr uint32_t effective_rate(uint32_t rawrate, uint32_t ksr)
static inline uint32_t effective_rate(uint32_t rawrate, uint32_t ksr)
{
return (rawrate == 0) ? 0 : std::min<uint32_t>(rawrate + ksr, 63);
}
Expand Down Expand Up @@ -282,6 +282,11 @@ class fm_channel
// master clocking function
void clock(uint32_t env_counter, int32_t lfo_raw_pm);

// EXTRA: Write the panning value for a simulated full-panning
void write_pan(int32_t data);
int32_t panL() const { return m_panVolumeL; }
int32_t panR() const { return m_panVolumeR; }

// specific 2-operator and 4-operator output handlers
void output_2op(output_data &output, uint32_t rshift, int32_t clipmax) const;
void output_4op(output_data &output, uint32_t rshift, int32_t clipmax) const;
Expand Down Expand Up @@ -333,6 +338,9 @@ class fm_channel
fm_operator<RegisterType> *m_op[4]; // up to 4 operators
RegisterType &m_regs; // direct reference to registers
fm_engine_base<RegisterType> &m_owner; // reference to the owning engine
// EXTRA:
int32_t m_panVolumeL; // Left PCM output channel volume
int32_t m_panVolumeR; // Right PCM output channel volume
};


Expand Down Expand Up @@ -378,6 +386,12 @@ class fm_engine_base : public ymfm_engine_callbacks
// write to the OPN registers
void write(uint16_t regnum, uint8_t data);

// EXTRA: Write panning value to the output channel
void write_pan(uint16_t chan, uint8_t data);

int32_t get_pan_l(uint16_t chan);
int32_t get_pan_r(uint16_t chan);

// return the current status
uint8_t status() const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,32 @@
namespace ymfm
{

/*
* Pan law table
*/
static const unsigned short panlawtable[] =
{
65535, 65529, 65514, 65489, 65454, 65409, 65354, 65289,
65214, 65129, 65034, 64929, 64814, 64689, 64554, 64410,
64255, 64091, 63917, 63733, 63540, 63336, 63123, 62901,
62668, 62426, 62175, 61914, 61644, 61364, 61075, 60776,
60468, 60151, 59825, 59489, 59145, 58791, 58428, 58057,
57676, 57287, 56889, 56482, 56067, 55643, 55211, 54770,
54320, 53863, 53397, 52923, 52441, 51951, 51453, 50947,
50433, 49912, 49383, 48846, 48302, 47750, 47191,
46340, /* Center left */
46340, /* Center right */
45472, 44885, 44291, 43690, 43083, 42469, 41848, 41221,
40588, 39948, 39303, 38651, 37994, 37330, 36661, 35986,
35306, 34621, 33930, 33234, 32533, 31827, 31116, 30400,
29680, 28955, 28225, 27492, 26754, 26012, 25266, 24516,
23762, 23005, 22244, 21480, 20713, 19942, 19169, 18392,
17613, 16831, 16046, 15259, 14469, 13678, 12884, 12088,
11291, 10492, 9691, 8888, 8085, 7280, 6473, 5666,
4858, 4050, 3240, 2431, 1620, 810, 0
};


//*********************************************************
// GLOBAL TABLE LOOKUPS
//*********************************************************
Expand Down Expand Up @@ -801,7 +827,9 @@ fm_channel<RegisterType>::fm_channel(fm_engine_base<RegisterType> &owner, uint32
m_feedback_in(0),
m_op{ nullptr, nullptr, nullptr, nullptr },
m_regs(owner.regs()),
m_owner(owner)
m_owner(owner),
m_panVolumeL(46340),
m_panVolumeR(46340)
{
}

Expand Down Expand Up @@ -903,6 +931,14 @@ printf(" -- ");
}


template<class RegisterType>
void fm_channel<RegisterType>::write_pan(int32_t data)
{
m_panVolumeL = panlawtable[data & 0x7F];
m_panVolumeR = panlawtable[0x7F - (data & 0x7F)];
}


//-------------------------------------------------
// output_2op - combine 4 operators according to
// the specified algorithm, returning a sum
Expand Down Expand Up @@ -1434,6 +1470,25 @@ void fm_engine_base<RegisterType>::write(uint16_t regnum, uint8_t data)
}


template<class RegisterType>
void fm_engine_base<RegisterType>::write_pan(uint16_t chan, uint8_t data)
{
m_channel[chan]->write_pan(data);
}

template<class RegisterType>
int32_t fm_engine_base<RegisterType>::get_pan_l(uint16_t chan)
{
return m_channel[chan]->panL();
}

template<class RegisterType>
int32_t fm_engine_base<RegisterType>::get_pan_r(uint16_t chan)
{
return m_channel[chan]->panR();
}


//-------------------------------------------------
// status - return the current state of the
// status flags
Expand Down
16 changes: 13 additions & 3 deletions OPNMIDI-Player/src/main/cpp/src/chips/ymfm/ymfm_opn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "ymfm_opn.h"
#include "ymfm_fm.ipp"
#include "ymfm_fm.hpp"

namespace ymfm
{
Expand Down Expand Up @@ -1287,6 +1287,11 @@ void ym2608::write(uint32_t offset, uint8_t data)
}
}

void ym2608::write_pan(uint16_t chan, uint8_t data)
{
m_fm.write_pan(chan, data);
}


//-------------------------------------------------
// generate - generate one sample of sound
Expand Down Expand Up @@ -2377,6 +2382,11 @@ void ym2612::write(uint32_t offset, uint8_t data)
}
}

void ym2612::write_pan(uint16_t chan, uint8_t data)
{
m_fm.write_pan(chan, data);
}


//-------------------------------------------------
// generate - generate one sample of sound
Expand All @@ -2398,8 +2408,8 @@ void ym2612::generate(output_data *output, uint32_t numsamples)
for (int chan = 0; chan < last_fm_channel; chan++)
{
m_fm.output(temp.clear(), 5, 256, 1 << chan);
output->data[0] += dac_discontinuity(temp.data[0]);
output->data[1] += dac_discontinuity(temp.data[1]);
output->data[0] += (dac_discontinuity(temp.data[0]) * m_fm.get_pan_l(chan) / 65535);
output->data[1] += (dac_discontinuity(temp.data[1]) * m_fm.get_pan_r(chan) / 65535);
}

// add in DAC
Expand Down
11 changes: 8 additions & 3 deletions OPNMIDI-Player/src/main/cpp/src/chips/ymfm/ymfm_opn.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class opn_registers_base : public fm_registers_base
void save_restore(ymfm_saved_state &state);

// map channel number to register offset
static constexpr uint32_t channel_offset(uint32_t chnum)
static inline uint32_t channel_offset(uint32_t chnum)
{
assert(chnum < CHANNELS);
if (!IsOpnA)
Expand All @@ -149,7 +149,7 @@ class opn_registers_base : public fm_registers_base
}

// map operator number to register offset
static constexpr uint32_t operator_offset(uint32_t opnum)
static inline uint32_t operator_offset(uint32_t opnum)
{
assert(opnum < OPERATORS);
if (!IsOpnA)
Expand Down Expand Up @@ -543,6 +543,8 @@ class ym2608
void write_data_hi(uint8_t data);
void write(uint32_t offset, uint8_t data);

void write_pan(uint16_t chan, uint8_t data);

// generate one sample of sound
void generate(output_data *output, uint32_t numsamples = 1);

Expand Down Expand Up @@ -758,12 +760,15 @@ class ym2612
void write_data_hi(uint8_t data);
void write(uint32_t offset, uint8_t data);

void write_pan(uint16_t chan, uint8_t data);

// generate one sample of sound
void generate(output_data *output, uint32_t numsamples = 1);

protected:
// simulate the DAC discontinuity
constexpr int32_t dac_discontinuity(int32_t value) const { return (value < 0) ? (value - 3) : (value + 4); }
static inline int32_t dac_discontinuity(int32_t value) { return (value < 0) ? (value - 3) : (value + 4); }
// constexpr int32_t dac_discontinuity(int32_t value) const { return (value < 0) ? (value - 3) : (value + 4); }

// internal state
uint16_t m_address; // address register
Expand Down
2 changes: 1 addition & 1 deletion OPNMIDI-Player/src/main/cpp/src/chips/ymfm/ymfm_pcm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#include "ymfm_pcm.h"
#include "ymfm_fm.h"
#include "ymfm_fm.ipp"
#include "ymfm_fm.hpp"

namespace ymfm
{
Expand Down
10 changes: 5 additions & 5 deletions OPNMIDI-Player/src/main/cpp/src/chips/ymfm_opn2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ void YmFmOPN2::writeReg(uint32_t port, uint16_t addr, uint8_t data)
++m_queueCount;
}

void YmFmOPN2::writePan(uint16_t /*addr*/, uint8_t /*data*/)
void YmFmOPN2::writePan(uint16_t addr, uint8_t data)
{
// ymfm::ym2612 *chip_r = reinterpret_cast<ymfm::ym2612*>(m_chip);
// OPL3_WritePan(chip_r, addr, data);
ymfm::ym2612 *chip_r = reinterpret_cast<ymfm::ym2612*>(m_chip);
chip_r->write_pan(addr, data);
}

void YmFmOPN2::nativeGenerate(int16_t *frame)
Expand Down Expand Up @@ -105,8 +105,8 @@ void YmFmOPN2::nativeGenerate(int16_t *frame)
}

chip_r->generate(&frames_i);
frame[0] = static_cast<int16_t>(ymfm::clamp(frames_i.data[0] / 2, -32768, 32767));
frame[1] = static_cast<int16_t>(ymfm::clamp(frames_i.data[1] / 2, -32768, 32767));
frame[0] = static_cast<int16_t>(ymfm::clamp(static_cast<int32_t>(frames_i.data[0] * 0.8f), -32768, 32767));
frame[1] = static_cast<int16_t>(ymfm::clamp(static_cast<int32_t>(frames_i.data[1] * 0.8f), -32768, 32767));
}

const char *YmFmOPN2::emulatorName()
Expand Down
4 changes: 2 additions & 2 deletions OPNMIDI-Player/src/main/cpp/src/chips/ymfm_opna.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ void YmFmOPNA_Private::nativeGenerate(int16_t *frame, void *m_chip, void *m_outp
int32_t o1 = output_r->data[1 % ymfm::ym2608::OUTPUTS];
int32_t o2 = output_r->data[2 % ymfm::ym2608::OUTPUTS];

frame[0] = static_cast<int16_t>(ymfm::clamp((o0 + o2) / 2, -32768, 32767));
frame[1] = static_cast<int16_t>(ymfm::clamp((o1 + o2) / 2, -32768, 32767));
frame[0] = static_cast<int16_t>(ymfm::clamp(static_cast<int32_t>((o0 + o2) * 0.8f), -32768, 32767));
frame[1] = static_cast<int16_t>(ymfm::clamp(static_cast<int32_t>((o1 + o2) * 0.8f), -32768, 32767));

m_pos = (m_pos % m_out_step);
}
Expand Down
4 changes: 2 additions & 2 deletions OPNMIDI-Player/src/main/cpp/src/opnmidi_opn2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,8 @@ void OPN2::setPan(size_t c, uint8_t value)
else
{
int panning = 0;
if(value < 64 + 32) panning |= OPN_PANNING_LEFT;
if(value >= 64 - 32) panning |= OPN_PANNING_RIGHT;
if(value < 64 + 16) panning |= OPN_PANNING_LEFT;
if(value >= 64 - 16) panning |= OPN_PANNING_RIGHT;
val = (panning & 0xC0) | (adli.lfosens & 0x3F);
writePan(chip, c % 6, 64);
writeRegI(chip, port, 0xB4 + cc, val);
Expand Down

0 comments on commit b8c11aa

Please sign in to comment.