k005289.cpp: Minor cleanups, Use struct for voices (#9389)

This commit is contained in:
cam900 2022-03-12 04:08:39 +09:00 committed by GitHub
parent f4b7a31631
commit f29cd1988c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 134 deletions

View File

@ -53,13 +53,11 @@ DEFINE_DEVICE_TYPE(K005289, k005289_device, "k005289", "K005289 SCC")
// k005289_device - constructor
//-------------------------------------------------
k005289_device::k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
k005289_device::k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, K005289, tag, owner, clock)
, device_sound_interface(mconfig, *this)
, m_sound_prom(*this, DEVICE_SELF)
, m_stream(nullptr)
, m_rate(0)
, m_mixer_lookup(nullptr)
{
}
@ -71,27 +69,19 @@ k005289_device::k005289_device(const machine_config &mconfig, const char *tag, d
void k005289_device::device_start()
{
/* get stream channels */
m_rate = clock() / CLOCK_DIVIDER;
m_stream = stream_alloc(0, 1, m_rate);
/* build the mixer table */
make_mixer_table(2);
m_stream = stream_alloc(0, 1, clock());
/* reset all the voices */
for (int i = 0; i < 2; i++)
for (auto & elem : m_voice)
{
m_counter[i] = 0;
m_frequency[i] = 0;
m_freq_latch[i] = 0;
m_waveform[i] = i * 0x100;
m_volume[i] = 0;
elem.reset();
}
save_item(NAME(m_counter));
save_item(NAME(m_frequency));
save_item(NAME(m_freq_latch));
save_item(NAME(m_waveform));
save_item(NAME(m_volume));
save_item(STRUCT_MEMBER(m_voice, counter));
save_item(STRUCT_MEMBER(m_voice, frequency));
save_item(STRUCT_MEMBER(m_voice, pitch));
save_item(STRUCT_MEMBER(m_voice, waveform));
save_item(STRUCT_MEMBER(m_voice, volume));
}
@ -101,137 +91,66 @@ void k005289_device::device_start()
void k005289_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{
auto &buffer = outputs[0];
short *mix;
int i,v,f;
/* zap the contents of the mixer buffer */
if (m_mixer_buffer.size() < buffer.samples())
m_mixer_buffer.resize(buffer.samples());
std::fill_n(&m_mixer_buffer[0], buffer.samples(), 0);
v=m_volume[0];
f=m_frequency[0];
if (v && f)
outputs[0].fill(0);
for (int sampid = 0; sampid < outputs[0].samples(); sampid++)
{
const unsigned char *w = &m_sound_prom[m_waveform[0]];
int c = m_counter[0];
mix = &m_mixer_buffer[0];
/* add our contribution */
for (i = 0; i < buffer.samples(); i++)
for (int i = 0; i < 2; i++)
{
int offs;
c += CLOCK_DIVIDER;
offs = (c / f) & 0x1f;
*mix++ += ((w[offs] & 0x0f) - 8) * v;
voice_t &v = m_voice[i];
if ((v.counter--) < 0)
{
v.waveform = (v.waveform & ~0x1f) | ((v.waveform + 1) & 0x1f);
v.counter = v.frequency;
}
outputs[0].add_int(sampid, ((m_sound_prom[((i & 1) << 8) | v.waveform] & 0xf) - 8) * v.volume, 512);
}
/* update the counter for this voice */
m_counter[0] = c % (f * 0x20);
}
v=m_volume[1];
f=m_frequency[1];
if (v && f)
{
const unsigned char *w = &m_sound_prom[m_waveform[1]];
int c = m_counter[1];
mix = &m_mixer_buffer[0];
/* add our contribution */
for (i = 0; i < buffer.samples(); i++)
{
int offs;
c += CLOCK_DIVIDER;
offs = (c / f) & 0x1f;
*mix++ += ((w[offs] & 0x0f) - 8) * v;
}
/* update the counter for this voice */
m_counter[1] = c % (f * 0x20);
}
/* mix it down */
mix = &m_mixer_buffer[0];
for (i = 0; i < buffer.samples(); i++)
buffer.put(i, m_mixer_lookup[*mix++]);
}
/********************************************************************************/
/* build a table to divide by the number of voices */
void k005289_device::make_mixer_table(int voices)
{
int count = voices * 128;
int gain = 16;
/* allocate memory */
m_mixer_table = std::make_unique<stream_buffer::sample_t []>(256 * voices);
/* find the middle of the table */
m_mixer_lookup = &m_mixer_table[128 * voices];
/* fill in the table - 16 bit case */
for (int i = 0; i < count; i++)
{
int val = i * gain * 16 / voices;
if (val > 32767) val = 32767;
stream_buffer::sample_t fval = stream_buffer::sample_t(val) / 32768.0;
m_mixer_lookup[ i] = fval;
m_mixer_lookup[-i] = -fval;
}
}
void k005289_device::control_A_w(uint8_t data)
void k005289_device::control_A_w(u8 data)
{
m_stream->update();
m_volume[0] = data & 0xf;
m_waveform[0] = data & 0xe0;
m_voice[0].volume = data & 0xf;
m_voice[0].waveform = (m_voice[0].waveform & ~0xe0) | (data & 0xe0);
}
void k005289_device::control_B_w(uint8_t data)
void k005289_device::control_B_w(u8 data)
{
m_stream->update();
m_volume[1] = data & 0xf;
m_waveform[1] = (data & 0xe0) + 0x100;
m_voice[1].volume = data & 0xf;
m_voice[1].waveform = (m_voice[1].waveform & ~0xe0) | (data & 0xe0);
}
void k005289_device::ld1_w(offs_t offset, uint8_t data)
void k005289_device::ld1_w(offs_t offset, u8 data)
{
m_freq_latch[0] = 0xfff - offset;
m_voice[0].pitch = 0xfff - offset;
}
void k005289_device::ld2_w(offs_t offset, uint8_t data)
void k005289_device::ld2_w(offs_t offset, u8 data)
{
m_freq_latch[1] = 0xfff - offset;
m_voice[1].pitch = 0xfff - offset;
}
void k005289_device::tg1_w(uint8_t data)
void k005289_device::tg1_w(u8 data)
{
m_stream->update();
m_frequency[0] = m_freq_latch[0];
m_voice[0].frequency = m_voice[0].pitch;
}
void k005289_device::tg2_w(uint8_t data)
void k005289_device::tg2_w(u8 data)
{
m_stream->update();
m_frequency[1] = m_freq_latch[1];
m_voice[1].frequency = m_voice[1].pitch;
}

View File

@ -12,14 +12,14 @@ class k005289_device : public device_t,
public device_sound_interface
{
public:
k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
k005289_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
void control_A_w(uint8_t data);
void control_B_w(uint8_t data);
void ld1_w(offs_t offset, uint8_t data);
void ld2_w(offs_t offset, uint8_t data);
void tg1_w(uint8_t data);
void tg2_w(uint8_t data);
void control_A_w(u8 data);
void control_B_w(u8 data);
void ld1_w(offs_t offset, u8 data);
void ld2_w(offs_t offset, u8 data);
void tg1_w(u8 data);
void tg2_w(u8 data);
protected:
// device-level overrides
@ -29,22 +29,27 @@ protected:
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
private:
void make_mixer_table(int voices);
required_region_ptr<uint8_t> m_sound_prom;
required_region_ptr<u8> m_sound_prom;
sound_stream *m_stream;
int m_rate;
/* mixer tables and internal buffers */
std::unique_ptr<stream_buffer::sample_t []> m_mixer_table;
stream_buffer::sample_t *m_mixer_lookup;
std::vector<short> m_mixer_buffer;
struct voice_t
{
void reset()
{
counter = 0;
frequency = 0;
pitch = 0;
waveform = 0;
volume = 0;
}
uint32_t m_counter[2];
uint16_t m_frequency[2];
uint16_t m_freq_latch[2];
uint16_t m_waveform[2];
uint8_t m_volume[2];
s16 counter = 0;
u16 frequency = 0;
u16 pitch = 0;
u16 waveform = 0;
u8 volume = 0;
};
voice_t m_voice[2];
};
DECLARE_DEVICE_TYPE(K005289, k005289_device)