mirror of
https://github.com/holub/mame
synced 2025-04-24 01:11:11 +03:00
ymfm: Improve LFO noise behavior. Add logging (under verbose) when LFO noise sounds are played to help ID cases for further study. This will be removed prior to release.
This commit is contained in:
parent
0633a88c19
commit
76f7ddca50
@ -4,7 +4,7 @@
|
||||
#include "emu.h"
|
||||
#include "ymfm.h"
|
||||
|
||||
//#define VERBOSE 1
|
||||
#define VERBOSE 1
|
||||
#define LOG_OUTPUT_FUNC osd_printf_verbose
|
||||
#include "logmacro.h"
|
||||
|
||||
@ -640,31 +640,34 @@ void ymfm_operator<RegisterType>::start_attack(u8 keycode)
|
||||
if (effective_rate(m_regs.attack_rate(), keycode) >= 62)
|
||||
m_env_attenuation = 0;
|
||||
|
||||
// log keys
|
||||
LOG("KeyOn %d.%d: freq=%04X dt2=%d fb=%d alg=%d dt=%d mul=%X tl=%02X ksr=%d adsr=%02X/%02X/%02X/%X sl=%X pan=%c%c",
|
||||
m_regs.chnum(), m_regs.opnum(),
|
||||
m_regs.block_freq(),
|
||||
m_regs.detune2(),
|
||||
m_regs.feedback(),
|
||||
m_regs.algorithm(),
|
||||
m_regs.detune(),
|
||||
m_regs.multiple(),
|
||||
m_regs.total_level(),
|
||||
m_regs.ksr(),
|
||||
m_regs.attack_rate(),
|
||||
m_regs.decay_rate(),
|
||||
m_regs.sustain_rate(),
|
||||
m_regs.release_rate(),
|
||||
m_regs.sustain_level(),
|
||||
m_regs.pan_left() ? 'L' : '-',
|
||||
m_regs.pan_right() ? 'R' : '-');
|
||||
if (m_regs.ssg_eg_enabled())
|
||||
LOG(" ssg=%X", m_regs.ssg_eg_mode());
|
||||
if (m_regs.lfo_enabled() && ((m_regs.lfo_am_enabled() && m_regs.lfo_am_sensitivity() != 0) || m_regs.lfo_pm_sensitivity() != 0))
|
||||
LOG(" am=%d pm=%d w=%d", m_regs.lfo_am_enabled() ? m_regs.lfo_am_sensitivity() : 0, m_regs.lfo_pm_sensitivity(), m_regs.lfo_waveform());
|
||||
if (m_regs.noise_enabled() && m_regs.opnum() == 3 && m_regs.chnum() == 7)
|
||||
LOG(" noise=1");
|
||||
LOG("\n");
|
||||
// log key on events under certain conditions
|
||||
if (m_regs.lfo_waveform() == 3 && m_regs.lfo_enabled() && ((m_regs.lfo_am_enabled() && m_regs.lfo_am_sensitivity() != 0) || m_regs.lfo_pm_sensitivity() != 0))
|
||||
{
|
||||
LOG("KeyOn %d.%d: freq=%04X dt2=%d fb=%d alg=%d dt=%d mul=%X tl=%02X ksr=%d adsr=%02X/%02X/%02X/%X sl=%X pan=%c%c",
|
||||
m_regs.chnum(), m_regs.opnum(),
|
||||
m_regs.block_freq(),
|
||||
m_regs.detune2(),
|
||||
m_regs.feedback(),
|
||||
m_regs.algorithm(),
|
||||
m_regs.detune(),
|
||||
m_regs.multiple(),
|
||||
m_regs.total_level(),
|
||||
m_regs.ksr(),
|
||||
m_regs.attack_rate(),
|
||||
m_regs.decay_rate(),
|
||||
m_regs.sustain_rate(),
|
||||
m_regs.release_rate(),
|
||||
m_regs.sustain_level(),
|
||||
m_regs.pan_left() ? 'L' : '-',
|
||||
m_regs.pan_right() ? 'R' : '-');
|
||||
if (m_regs.ssg_eg_enabled())
|
||||
LOG(" ssg=%X", m_regs.ssg_eg_mode());
|
||||
if (m_regs.lfo_enabled() && ((m_regs.lfo_am_enabled() && m_regs.lfo_am_sensitivity() != 0) || m_regs.lfo_pm_sensitivity() != 0))
|
||||
LOG(" am=%d pm=%d w=%d", m_regs.lfo_am_enabled() ? m_regs.lfo_am_sensitivity() : 0, m_regs.lfo_pm_sensitivity(), m_regs.lfo_waveform());
|
||||
if (m_regs.noise_enabled() && m_regs.opnum() == 3 && m_regs.chnum() == 7)
|
||||
LOG(" noise=1");
|
||||
LOG("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1255,6 +1258,8 @@ ymfm_engine_base<RegisterType>::ymfm_engine_base(device_t &device) :
|
||||
m_lfo_counter(0),
|
||||
m_noise_lfsr(0),
|
||||
m_noise_counter(0),
|
||||
m_noise_state(0),
|
||||
m_noise_lfo(0),
|
||||
m_lfo_am(0),
|
||||
m_status(0),
|
||||
m_clock_prescale(RegisterType::DEFAULT_PRESCALE),
|
||||
@ -1291,6 +1296,8 @@ void ymfm_engine_base<RegisterType>::save(device_t &device)
|
||||
device.save_item(YMFM_NAME(m_lfo_counter));
|
||||
device.save_item(YMFM_NAME(m_noise_lfsr));
|
||||
device.save_item(YMFM_NAME(m_noise_counter));
|
||||
device.save_item(YMFM_NAME(m_noise_state));
|
||||
device.save_item(YMFM_NAME(m_noise_lfo));
|
||||
device.save_item(YMFM_NAME(m_lfo_am));
|
||||
device.save_item(YMFM_NAME(m_status));
|
||||
device.save_item(YMFM_NAME(m_clock_prescale));
|
||||
@ -1375,7 +1382,7 @@ void ymfm_engine_base<RegisterType>::output(s32 &lsum, s32 &rsum, u8 rshift, s16
|
||||
{
|
||||
// noise must be non-zero to use noise on OP4, so if it is enabled,
|
||||
// OR with 2 (since only the LSB is actually checked for the noise state)
|
||||
u8 noise = (chnum == 7 && m_regs.noise_enabled()) ? (m_noise_lfsr | 2) : 0;
|
||||
u8 noise = (chnum == 7 && m_regs.noise_enabled()) ? (m_noise_state | 2) : 0;
|
||||
m_channel[chnum]->output(m_lfo_am, noise, lsum, rsum, rshift, clipmax);
|
||||
}
|
||||
}
|
||||
@ -1439,6 +1446,7 @@ s8 ymfm_engine_base<ymopm_registers>::clock_lfo()
|
||||
// leading 1; this matches exactly the frequencies in the application
|
||||
// manual, though it might not be implemented exactly this way on chip
|
||||
u8 rate = m_regs.lfo_rate();
|
||||
u32 prev_counter = m_lfo_counter;
|
||||
m_lfo_counter += (0x10 | BIT(rate, 0, 4)) << BIT(rate, 4, 4);
|
||||
u8 lfo = BIT(m_lfo_counter, 22, 8);
|
||||
|
||||
@ -1470,11 +1478,12 @@ s8 ymfm_engine_base<ymopm_registers>::clock_lfo()
|
||||
|
||||
// noise:
|
||||
case 3:
|
||||
// QUESTION: totally random guess here; does the LFO counter
|
||||
// play into this? Is there a separate LFSR for the LFO noise?
|
||||
// Do we sample & hold the noise at a certain point based on
|
||||
// the LFO counter?
|
||||
am = BIT(m_noise_lfsr, 0) ? 0xff : 0;
|
||||
// QUESTION: this behavior is surmised but not yet verified:
|
||||
// LFO noise value is accumulated over 8 bits of LFSR and
|
||||
// clocked as the LFO value transitions
|
||||
if (BIT(m_lfo_counter ^ prev_counter, 22, 8) != 0)
|
||||
m_noise_lfo = m_noise_lfsr & 0xff;
|
||||
am = m_noise_lfo;
|
||||
pm = am ^ 0x80;
|
||||
break;
|
||||
}
|
||||
@ -1537,18 +1546,22 @@ void ymfm_engine_base<ymopm_registers>::clock_noise()
|
||||
{
|
||||
// base noise frequency is measured at 2x 1/2 FM frequency; this means
|
||||
// each tick counts as two steps against the noise counter
|
||||
m_noise_counter += 2;
|
||||
|
||||
// compare against the frequency
|
||||
u8 freq = m_regs.noise_frequency() + 1;
|
||||
while (m_noise_counter >= freq)
|
||||
u8 freq = m_regs.noise_frequency();
|
||||
for (int rep = 0; rep < 2; rep++)
|
||||
{
|
||||
m_noise_counter -= freq;
|
||||
|
||||
// note that the LFSR here contains the output bit in bit 0, with
|
||||
// the current LFSR state in bits 1-17
|
||||
// evidence seems to suggest the LFSR is clocked continually and just
|
||||
// sampled at the noise frequency for output purposes; clock it here
|
||||
// twice; note that the low 8 bits are the most recent 8 bits of history
|
||||
// while bits 8-24 contain the 17 bit LFSR state
|
||||
m_noise_lfsr >>= 1;
|
||||
m_noise_lfsr |= (BIT(m_noise_lfsr, 0) ^ BIT(m_noise_lfsr, 3) ^ 1) << 17;
|
||||
m_noise_lfsr |= (BIT(m_noise_lfsr, 7) ^ BIT(m_noise_lfsr, 10) ^ 1) << 24;
|
||||
|
||||
// compare against the frequency and latch when we exceed it
|
||||
if (m_noise_counter++ >= freq)
|
||||
{
|
||||
m_noise_counter = 0;
|
||||
m_noise_state = BIT(m_noise_lfsr, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,6 +799,8 @@ private:
|
||||
u32 m_lfo_counter; // LFO counter
|
||||
u32 m_noise_lfsr; // noise LFSR state
|
||||
u8 m_noise_counter; // noise counter
|
||||
u8 m_noise_state; // latched noise state
|
||||
u8 m_noise_lfo; // latched LFO noise value
|
||||
u8 m_lfo_am; // current LFO AM value
|
||||
u8 m_status; // current status register
|
||||
u8 m_clock_prescale; // prescale factor (2/3/6)
|
||||
|
Loading…
Reference in New Issue
Block a user