diff options
Diffstat (limited to 'src/devices/sound/ym2151.cpp')
-rw-r--r-- | src/devices/sound/ym2151.cpp | 91 |
1 files changed, 23 insertions, 68 deletions
diff --git a/src/devices/sound/ym2151.cpp b/src/devices/sound/ym2151.cpp index b4769341425..a8e0bf4ab7a 100644 --- a/src/devices/sound/ym2151.cpp +++ b/src/devices/sound/ym2151.cpp @@ -11,51 +11,6 @@ DEFINE_DEVICE_TYPE(YM2414, ym2414_device, "ym2414", "YM2414 OPZ") //********************************************************* -// INLINE HELPERS -//********************************************************* - -//------------------------------------------------- -// linear_to_fp - given a 32-bit signed input -// value, convert it to a signed 10.3 floating- -// point value -//------------------------------------------------- - -inline s16 linear_to_fp(s32 value) -{ - // start with the absolute value - s32 avalue = std::abs(value); - - // compute shift to fit in 9 bits (bit 10 is the sign) - int shift = (32 - 9) - count_leading_zeros(avalue); - - // if out of range, just return maximum; note that YM3012 DAC does - // not support a shift count of 7, so we clamp at 6 - if (shift >= 7) - shift = 6, avalue = 0x1ff; - else if (shift > 0) - avalue >>= shift; - else - shift = 0; - - // encode with shift in low 3 bits and signed mantissa in upper - return shift | (((value < 0) ? -avalue : avalue) << 3); -} - - -//------------------------------------------------- -// fp_to_linear - given a 10.3 floating-point -// value, convert it to a signed 16-bit value, -// clamping -//------------------------------------------------- - -inline s32 fp_to_linear(s16 value) -{ - return (value >> 3) << BIT(value, 0, 3); -} - - - -//********************************************************* // YM2151 DEVICE //********************************************************* @@ -66,10 +21,10 @@ inline s32 fp_to_linear(s16 value) ym2151_device::ym2151_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, device_type type) : device_t(mconfig, type, tag, owner, clock), device_sound_interface(mconfig, *this), - m_opm(*this), + m_fm(*this), m_stream(nullptr), m_port_w(*this), - m_busy_duration(m_opm.compute_busy_duration()), + m_busy_duration(m_fm.compute_busy_duration()), m_address(0), m_reset_state(1) { @@ -89,8 +44,8 @@ u8 ym2151_device::read(offs_t offset) logerror("Unexpected read from YM2151 offset %d\n", offset & 3); break; - case 1: // status port, YM2203 compatible - result = m_opm.status(); + case 1: // status port, YM2203 compatible + result = m_fm.status(); break; } return result; @@ -119,14 +74,14 @@ void ym2151_device::write(offs_t offset, u8 value) // force an update m_stream->update(); - // write to OPM - m_opm.write(m_address, value); + // write to FM + m_fm.write(m_address, value); // special cases if (m_address == 0x01 && BIT(value, 1)) { // writes to the test register can reset the LFO - m_opm.reset_lfo(); + m_fm.reset_lfo(); } else if (m_address == 0x1b) { @@ -135,7 +90,7 @@ void ym2151_device::write(offs_t offset, u8 value) } // mark busy for a bit - m_opm.set_busy_end(machine().time() + m_busy_duration); + m_fm.set_busy_end(machine().time() + m_busy_duration); break; } } @@ -161,7 +116,7 @@ WRITE_LINE_MEMBER(ym2151_device::reset_w) void ym2151_device::device_start() { // create our stream - m_stream = stream_alloc(0, 2, clock() / (2 * 4 * 8)); + m_stream = stream_alloc(0, fm_engine::OUTPUTS, m_fm.sample_rate(clock())); // resolve the write callback m_port_w.resolve_safe(); @@ -174,7 +129,7 @@ void ym2151_device::device_start() save_item(YMFM_NAME(m_reset_state)); // save the engines - m_opm.save(*this); + m_fm.save(*this); } @@ -185,7 +140,7 @@ void ym2151_device::device_start() void ym2151_device::device_reset() { // reset the engines - m_opm.reset(); + m_fm.reset(); } @@ -195,8 +150,8 @@ void ym2151_device::device_reset() void ym2151_device::device_clock_changed() { - m_stream->set_sample_rate(clock() / (2 * 4 * 8)); - m_busy_duration = m_opm.compute_busy_duration(); + m_stream->set_sample_rate(m_fm.sample_rate(clock())); + m_busy_duration = m_fm.compute_busy_duration(); } @@ -210,16 +165,16 @@ void ym2151_device::sound_stream_update(sound_stream &stream, std::vector<read_s for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++) { // clock the system - m_opm.clock(0xff); + m_fm.clock(fm_engine::ALL_CHANNELS); - // update the OPM content; OPM is full 14-bit with no intermediate clipping - s32 lsum = 0, rsum = 0; - m_opm.output(lsum, rsum, 0, 32767, 0xff); + // update the FM content; YM2151 is full 14-bit with no intermediate clipping + s32 sums[fm_engine::OUTPUTS] = { 0 }; + m_fm.output(sums, 0, 32767, fm_engine::ALL_CHANNELS); // convert to 10.3 floating point value for the DAC and back - // OPM is stereo - outputs[0].put_int_clamp(sampindex, fp_to_linear(linear_to_fp(lsum)), 32768); - outputs[1].put_int_clamp(sampindex, fp_to_linear(linear_to_fp(rsum)), 32768); + // YM2151 is stereo + for (int index = 0; index < fm_engine::OUTPUTS; index++) + outputs[index].put_int(sampindex, ymfm_roundtrip_fp(sums[index]), 32768); } } @@ -260,15 +215,15 @@ void ym2164_device::write(offs_t offset, u8 value) // force an update m_stream->update(); - // write to OPM - m_opm.write(m_address, value); + // write to FM + m_fm.write(m_address, value); // writes to register 0x1B send the upper 2 bits to the output lines if (m_address == 0x1b) m_port_w(0, value >> 6, 0xff); // mark busy for a bit - m_opm.set_busy_end(machine().time() + m_busy_duration); + m_fm.set_busy_end(machine().time() + m_busy_duration); break; } } |