summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/okim6376.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/okim6376.cpp')
-rw-r--r--src/devices/sound/okim6376.cpp132
1 files changed, 70 insertions, 62 deletions
diff --git a/src/devices/sound/okim6376.cpp b/src/devices/sound/okim6376.cpp
index 2170bd5e898..7807a163e71 100644
--- a/src/devices/sound/okim6376.cpp
+++ b/src/devices/sound/okim6376.cpp
@@ -116,7 +116,7 @@ DEFINE_DEVICE_TYPE(OKIM6650, okim6650_device, "okim6650", "OKI MSM6650 ADPCM")
okim6376_device::okim6376_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int addrbits)
: device_t(mconfig, type, tag, owner, clock),
device_sound_interface(mconfig, *this),
- device_rom_interface(mconfig, *this, addrbits, ENDIANNESS_BIG, 8),
+ device_rom_interface(mconfig, *this),
//m_command[OKIM6376_VOICES],
m_latch(0),
//m_stage[OKIM6376_VOICES],
@@ -132,6 +132,7 @@ okim6376_device::okim6376_device(const machine_config &mconfig, device_type type
m_ch2_update(0),
m_st_update(0)
{
+ override_address_width(addrbits);
}
okim6376_device::okim6376_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -168,7 +169,7 @@ void okim6376_device::device_start()
m_ch2_update = 0;
m_st_pulses = 0;
/* generate the name and create the stream */
- m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / m_divisor);
+ m_stream = stream_alloc(0, 1, get_sample_rate());
/* initialize the voices */
for (voice = 0; voice < OKIM6376_VOICES; voice++)
@@ -195,8 +196,9 @@ void okim6376_device::device_reset()
}
-void okim6376_device::rom_bank_updated()
+void okim6376_device::rom_bank_pre_change()
{
+ m_stream->update();
}
@@ -251,6 +253,18 @@ offs_t okim6650_device::get_start_position(int channel)
}
+u32 okim6376_device::get_sample_rate()
+{
+ return clock() / m_divisor;
+}
+
+u32 okim6650_device::get_sample_rate()
+{
+ return clock() / 64 / m_divisor;
+}
+
+
+
void okim6376_device::oki_process(int channel, int command)
{
/* if a command is pending, process the second half */
@@ -266,51 +280,51 @@ void okim6376_device::oki_process(int channel, int command)
// determine the start position
offs_t start = get_start_position(channel);
- if (start == 0)
+ if (start == 0)
+ {
+ voice->playing = 0;
+ }
+ else
+ {
+ /* set up the voice to play this sample */
+ if (!voice->playing)
{
- voice->playing = 0;
+ voice->playing = 1;
+ voice->base_offset = start;
+ voice->sample = 0;
+ voice->count = 0;
+
+ /* also reset the ADPCM parameters */
+ voice->reset();
+ if (channel == 0)
+ {
+ /* We set channel 2's audio separately */
+ voice->volume = volume_table[0];
+ }
}
else
{
- /* set up the voice to play this sample */
- if (!voice->playing)
- {
- voice->playing = 1;
- voice->base_offset = start;
- voice->sample = 0;
- voice->count = 0;
-
- /* also reset the ADPCM parameters */
- voice->reset();
- if (channel == 0)
- {
- /* We set channel 2's audio separately */
- voice->volume = volume_table[0];
- }
- }
- else
+ if (((m_nar)&&(channel == 0))||(channel == 1))//Store the request, for later processing (channel 2 ignores NAR)
{
- if (((m_nar)&&(channel == 0))||(channel == 1))//Store the request, for later processing (channel 2 ignores NAR)
- {
- m_stage[channel] = 1;
- }
+ m_stage[channel] = 1;
}
}
}
}
- /* otherwise, see if this is a silence command */
- else
- {
- /* update the stream, then turn it off */
- m_stream->update();
+ }
+ /* otherwise, see if this is a silence command */
+ else
+ {
+ /* update the stream, then turn it off */
+ m_stream->update();
- if (command ==0)
+ if (command ==0)
+ {
+ int i;
+ for (i = 0; i < OKIM6376_VOICES; i++)
{
- int i;
- for (i = 0; i < OKIM6376_VOICES; i++)
- {
- struct ADPCMVoice *voice = &m_voice[i];
- voice->playing = 0;
+ struct ADPCMVoice *voice = &m_voice[i];
+ voice->playing = 0;
}
}
}
@@ -408,8 +422,7 @@ void okim6376_device::adpcm_state_save_register(struct ADPCMVoice *voice, int in
void okim6376_device::okim6376_state_save_register()
{
- int j;
- for (j = 0; j < OKIM6376_VOICES; j++)
+ for (int j = 0; j < OKIM6376_VOICES; j++)
{
adpcm_state_save_register(&m_voice[j], j);
}
@@ -432,12 +445,7 @@ void okim6376_device::okim6376_state_save_register()
void okim6376_device::device_clock_changed()
{
- m_stream->set_sample_rate(clock() / m_divisor);
-}
-
-void okim6650_device::device_clock_changed()
-{
- m_stream->set_sample_rate(clock() / 64 / m_divisor);
+ m_stream->set_sample_rate(get_sample_rate());
}
@@ -447,7 +455,7 @@ void okim6650_device::device_clock_changed()
***********************************************************************************************/
-READ_LINE_MEMBER( okim6376_device::busy_r )
+int okim6376_device::busy_r()
{
struct ADPCMVoice *voice0 = &m_voice[0];
struct ADPCMVoice *voice1 = &m_voice[1];
@@ -463,13 +471,13 @@ READ_LINE_MEMBER( okim6376_device::busy_r )
}
}
-READ_LINE_MEMBER( okim6376_device::nar_r )
+int okim6376_device::nar_r()
{
LOG("OKIM6376: NAR %x\n",m_nar);
return m_nar;
}
-WRITE_LINE_MEMBER( okim6376_device::ch2_w )
+void okim6376_device::ch2_w(int state)
{
m_ch2_update = 0;//Clear flag
LOG("OKIM6376: CH2 %x\n",state);
@@ -506,7 +514,7 @@ WRITE_LINE_MEMBER( okim6376_device::ch2_w )
}
-WRITE_LINE_MEMBER( okim6376_device::st_w )
+void okim6376_device::st_w(int state)
{
//As in STart, presumably, this triggers everything
@@ -548,7 +556,7 @@ WRITE_LINE_MEMBER( okim6376_device::st_w )
}
-WRITE_LINE_MEMBER( okim6650_device::cmd_w )
+void okim6650_device::cmd_w(int state)
{
// TODO
}
@@ -573,18 +581,15 @@ void okim6376_device::write(uint8_t data)
// sound_stream_update - handle a stream update
//-------------------------------------------------
-void okim6376_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void okim6376_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{
- int i;
-
- memset(outputs[0], 0, samples * sizeof(*outputs[0]));
+ outputs[0].fill(0);
- for (i = 0; i < OKIM6376_VOICES; i++)
+ for (int i = 0; i < OKIM6376_VOICES; i++)
{
struct ADPCMVoice *voice = &m_voice[i];
- stream_sample_t *buffer = outputs[0];
+ auto &buffer = outputs[0];
int16_t sample_data[MAX_SAMPLE_CHUNK];
- int remaining = samples;
if (i == 0) //channel 1 is the only channel to affect NAR
{
if (m_nartimer > 0)
@@ -598,16 +603,19 @@ void okim6376_device::sound_stream_update(sound_stream &stream, stream_sample_t
}
/* loop while we have samples remaining */
- while (remaining)
+ for (int sampindex = 0; sampindex < buffer.samples(); )
{
+ int remaining = buffer.samples() - sampindex;
int samples = (remaining > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : remaining;
- int samp;
generate_adpcm(voice, sample_data, samples,i);
- for (samp = 0; samp < samples; samp++)
- *buffer++ += sample_data[samp];
+ for (int samp = 0; samp < samples; samp++)
+ buffer.add_int(sampindex + samp, sample_data[samp], 32768);
- remaining -= samples;
+ sampindex += samples;
}
}
+
+ for (int i = 0; i < outputs[0].samples(); i++)
+ outputs[0].put(i, std::clamp(outputs[0].getraw(i), -1.0f, 1.0f));
}