summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound
diff options
context:
space:
mode:
author cam900 <dbtlrchl@naver.com>2018-09-03 11:31:52 +0900
committer ajrhacker <ajrhacker@users.noreply.github.com>2018-09-02 22:31:52 -0400
commitb8c8f9423aac5ea785f5e67df996c97392db2509 (patch)
tree8e1721d113aa74d3f92647fdb36f17831c84e35a /src/devices/sound
parent8029c10d4f13e0606bb933af7d4a3c27ee553a5b (diff)
huc6230.cpp : Fix PSG, Timer'd ADPCM update, Implement CD-DA Volume (#3919)
huc6272.cpp : Make CD-DA Playable
Diffstat (limited to 'src/devices/sound')
-rw-r--r--src/devices/sound/huc6230.cpp88
-rw-r--r--src/devices/sound/huc6230.h6
2 files changed, 67 insertions, 27 deletions
diff --git a/src/devices/sound/huc6230.cpp b/src/devices/sound/huc6230.cpp
index 9b77d1f83c0..ce5ee4b3e2e 100644
--- a/src/devices/sound/huc6230.cpp
+++ b/src/devices/sound/huc6230.cpp
@@ -18,17 +18,11 @@ constexpr int clamp(int val, int min, int max) { return std::min(max, std::max(m
void huc6230_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
- int frq = (1 << m_adpcm_freq);
for (int i = 0; i < samples; i++)
{
outputs[0][i] = inputs[0][i];
outputs[1][i] = inputs[1][i];
- int cdda_l = inputs[2][i];
- int cdda_r = inputs[3][i];
- outputs[0][i] = clamp(outputs[0][i] + ((cdda_l * m_cdda_lvol) >> 6), -32768, 32767);
- outputs[1][i] = clamp(outputs[1][i] + ((cdda_r * m_cdda_rvol) >> 6), -32768, 32767);
-
for (int adpcm = 0; adpcm < 2; adpcm++)
{
adpcm_channel *channel = &m_adpcm_channel[adpcm];
@@ -36,25 +30,8 @@ void huc6230_device::sound_stream_update(sound_stream &stream, stream_sample_t *
if (!channel->m_playing)
continue;
- int32_t sample;
-
- channel->m_pos++;
- channel->m_input = m_adpcm_update_cb[adpcm]();
-
- if (channel->m_pos > frq)
- {
- channel->m_pos = 0;
- channel->m_prev_sample = channel->m_curr_sample;
- channel->m_curr_sample = channel->m_adpcm.clock(channel->m_input & 0xf);
- }
- if (!channel->m_interpolate)
- sample = channel->m_curr_sample;
- else
- sample = ((channel->m_prev_sample * (frq - channel->m_pos)) +
- (channel->m_curr_sample * channel->m_pos)) >> m_adpcm_freq;
-
- outputs[0][i] = clamp(outputs[0][i] + ((sample * channel->m_lvol) >> 2), -32768, 32767);
- outputs[1][i] = clamp(outputs[1][i] + ((sample * channel->m_rvol) >> 2), -32768, 32767);
+ outputs[0][i] = clamp(outputs[0][i] + ((channel->m_output * channel->m_lvol) >> 2), -32768, 32767);
+ outputs[1][i] = clamp(outputs[1][i] + ((channel->m_output * channel->m_rvol) >> 2), -32768, 32767);
}
}
}
@@ -84,6 +61,7 @@ WRITE8_MEMBER( huc6230_device::write )
m_adpcm_channel[i].m_playing = 0;
m_adpcm_channel[i].m_prev_sample = 0;
m_adpcm_channel[i].m_curr_sample = 0;
+ m_adpcm_channel[i].m_output = 0;
m_adpcm_channel[i].m_pos = 0;
}
else
@@ -101,9 +79,57 @@ WRITE8_MEMBER( huc6230_device::write )
m_adpcm_channel[offset >> 1].m_rvol = data & 0x3f;
}
else if (offset < 0x16)
+ {
m_cdda_lvol = data & 0x3f;
+ m_cdda_cb(0, m_cdda_lvol);
+ }
else if (offset < 0x17)
+ {
m_cdda_rvol = data & 0x3f;
+ m_cdda_cb(1, m_cdda_rvol);
+ }
+}
+
+TIMER_CALLBACK_MEMBER(huc6230_device::adpcm_timer)
+{
+ int frq = (1 << m_adpcm_freq);
+ for (int adpcm = 0; adpcm < 2; adpcm++)
+ {
+ adpcm_channel *channel = &m_adpcm_channel[adpcm];
+
+ if (!channel->m_playing)
+ {
+ if (channel->m_output != 0)
+ {
+ m_stream->update();
+ channel->m_output = 0;
+ }
+ continue;
+ }
+
+ channel->m_pos++;
+ channel->m_input = m_adpcm_update_cb[adpcm]();
+
+ if (channel->m_pos > frq)
+ {
+ channel->m_pos = 0;
+ channel->m_prev_sample = channel->m_curr_sample;
+ channel->m_curr_sample = channel->m_adpcm.clock(channel->m_input & 0xf);
+ }
+
+ int32_t new_output;
+ if (!channel->m_interpolate)
+ new_output = channel->m_curr_sample;
+ else
+ new_output = ((channel->m_prev_sample * (frq - channel->m_pos)) +
+ (channel->m_curr_sample * channel->m_pos)) >> m_adpcm_freq;
+
+ if (channel->m_output != new_output)
+ {
+ m_stream->update();
+ channel->m_output = new_output;
+ }
+ }
}
DEFINE_DEVICE_TYPE(HuC6230, huc6230_device, "huc6230", "Hudson Soft HuC6230 SoundBox")
@@ -117,6 +143,7 @@ huc6230_device::huc6230_device(const machine_config &mconfig, const char *tag, d
, m_cdda_lvol(0)
, m_cdda_rvol(0)
, m_adpcm_update_cb{{*this}, {*this}}
+ , m_cdda_cb(*this)
{
}
@@ -139,13 +166,17 @@ void huc6230_device::device_start()
for (auto &cb : m_adpcm_update_cb)
cb.resolve_safe(0);
- m_stream = machine().sound().stream_alloc(*this, 4, 2, clock() / 682); // or /672?
+ m_cdda_cb.resolve_safe();
+
+ m_stream = machine().sound().stream_alloc(*this, 2, 2, clock() / 96);
+ m_adpcm_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(huc6230_device::adpcm_timer),this));
for (int i = 0; i < 2; i++)
{
m_adpcm_channel[i].m_playing = 0;
m_adpcm_channel[i].m_prev_sample = 0;
m_adpcm_channel[i].m_curr_sample = 0;
+ m_adpcm_channel[i].m_output = 0;
m_adpcm_channel[i].m_pos = 0;
m_adpcm_channel[i].m_input = 0;
@@ -157,6 +188,7 @@ void huc6230_device::device_start()
save_item(NAME(m_adpcm_channel[i].m_playing), i);
save_item(NAME(m_adpcm_channel[i].m_prev_sample), i);
save_item(NAME(m_adpcm_channel[i].m_curr_sample), i);
+ save_item(NAME(m_adpcm_channel[i].m_output), i);
save_item(NAME(m_adpcm_channel[i].m_pos), i);
save_item(NAME(m_adpcm_channel[i].m_input), i);
}
@@ -167,5 +199,7 @@ void huc6230_device::device_start()
void huc6230_device::device_clock_changed()
{
- m_stream->set_sample_rate(clock() / 682);
+ m_stream->set_sample_rate(clock() / 96);
+ attotime adpcm_period = clocks_to_attotime(682);
+ m_adpcm_timer->adjust(adpcm_period, 0, adpcm_period);
}
diff --git a/src/devices/sound/huc6230.h b/src/devices/sound/huc6230.h
index 632dbee80de..6cd26955191 100644
--- a/src/devices/sound/huc6230.h
+++ b/src/devices/sound/huc6230.h
@@ -14,6 +14,7 @@ public:
huc6230_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template <unsigned N> auto adpcm_update_cb() { return m_adpcm_update_cb[N].bind(); }
+ auto cdda_cb() { return m_cdda_cb.bind(); }
// write only
DECLARE_WRITE8_MEMBER( write );
@@ -36,19 +37,24 @@ private:
uint8_t m_playing;
int32_t m_prev_sample;
int32_t m_curr_sample;
+ int32_t m_output;
uint32_t m_pos;
uint8_t m_input;
};
// internal state
sound_stream *m_stream;
+ emu_timer *m_adpcm_timer;
required_device<c6280_device> m_psg;
adpcm_channel m_adpcm_channel[2];
uint32_t m_adpcm_freq;
uint32_t m_cdda_lvol;
uint32_t m_cdda_rvol;
+ TIMER_CALLBACK_MEMBER(adpcm_timer);
+
devcb_read8 m_adpcm_update_cb[2];
+ devcb_write8 m_cdda_cb;
};
DECLARE_DEVICE_TYPE(HuC6230, huc6230_device)