mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
k005289.cpp: Minor cleanups, Use struct for voices (#9389)
This commit is contained in:
parent
f4b7a31631
commit
f29cd1988c
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user