es1373/es5503/es5506/esqpump: update to new stream callbacks

This commit is contained in:
Aaron Giles 2020-09-17 20:41:21 -07:00
parent 594d58d6a2
commit 54beaa97ff
8 changed files with 140 additions and 193 deletions

View File

@ -120,7 +120,7 @@ void es1373_device::device_start()
add_map(0x40, M_IO, FUNC(es1373_device::map)); add_map(0x40, M_IO, FUNC(es1373_device::map));
// create the stream // create the stream
m_stream = stream_alloc_legacy(0, 2, 44100/2); m_stream = stream_alloc(0, 2, 44100/2);
m_timer = timer_alloc(0, nullptr); m_timer = timer_alloc(0, nullptr);
m_timer->adjust(attotime::zero, 0, attotime::from_hz(44100/2/16)); m_timer->adjust(attotime::zero, 0, attotime::from_hz(44100/2/16));
@ -233,21 +233,24 @@ void es1373_device::device_timer(emu_timer &timer, device_timer_id tid, int para
// sound_stream_update_legacy - handle update requests for // sound_stream_update_legacy - handle update requests for
// our sound stream // our sound stream
//------------------------------------------------- //-------------------------------------------------
void es1373_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) void es1373_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{ {
if (m_dac1.enable) { if (m_dac1.enable) {
logerror("%s: sound_stream_update_legacy DAC1 not implemented yet\n", tag()); logerror("%s: sound_stream_update_legacy DAC1 not implemented yet\n", tag());
} }
if (m_dac2.enable) { if (m_dac2.enable) {
send_audio_out(m_dac2, ICSTATUS_DAC2_INT_MASK, outputs[0], outputs[1], samples); send_audio_out(m_dac2, ICSTATUS_DAC2_INT_MASK, outputs[0], outputs[1]);
} else {
outputs[0].fill(0);
outputs[1].fill(0);
} }
if (m_adc.enable) { if (m_adc.enable) {
if (m_adc.format!=SCTRL_16BIT_MONO) { if (m_adc.format!=SCTRL_16BIT_MONO) {
logerror("%s: sound_stream_update_legacy Only SCTRL_16BIT_MONO recorded supported\n", tag()); logerror("%s: sound_stream_update_legacy Only SCTRL_16BIT_MONO recorded supported\n", tag());
} else { } else {
for (int i=0; i<samples; i++) { for (int i=0; i<outputs[0].samples(); i++) {
if (m_adc.buf_count<=m_adc.buf_size) { if (m_adc.buf_count<=m_adc.buf_size) {
if (LOG_ES) if (LOG_ES)
logerror("%s: ADC buf_count: %i buf_size: %i buf_rptr: %i buf_wptr: %i\n", machine().describe_context(), logerror("%s: ADC buf_count: %i buf_size: %i buf_rptr: %i buf_wptr: %i\n", machine().describe_context(),
@ -292,7 +295,7 @@ void es1373_device::sound_stream_update_legacy(sound_stream &stream, stream_samp
//------------------------------------------------- //-------------------------------------------------
// send_audio_out - Sends channel audio output data // send_audio_out - Sends channel audio output data
//------------------------------------------------- //-------------------------------------------------
void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_sample_t *outL, stream_sample_t *outR, int samples) void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, write_stream_view &outL, write_stream_view &outR)
{ {
// Only transfer PCI data if bus mastering is enabled // Only transfer PCI data if bus mastering is enabled
// Fill initial half buffer // Fill initial half buffer
@ -303,8 +306,10 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s
//uint32_t sample_size = calc_size(chan.format); //uint32_t sample_size = calc_size(chan.format);
// Send data to sound stream // Send data to sound stream
bool buf_row_done; bool buf_row_done;
for (int i=0; i<samples; i++) { constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0;
for (int i=0; i<outL.samples(); i++) {
buf_row_done = false; buf_row_done = false;
int16_t lsamp = 0, rsamp = 0;
if (chan.buf_count<=chan.buf_size) { if (chan.buf_count<=chan.buf_size) {
// Only transfer PCI data if bus mastering is enabled // Only transfer PCI data if bus mastering is enabled
// Fill half-buffer when read pointer is at start of next half // Fill half-buffer when read pointer is at start of next half
@ -314,7 +319,7 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s
} }
if (LOG_ES && i==0) if (LOG_ES && i==0)
logerror("%s: chan: %X samples: %i buf_count: %X buf_size: %X buf_rptr: %X buf_wptr: %X\n", logerror("%s: chan: %X samples: %i buf_count: %X buf_size: %X buf_rptr: %X buf_wptr: %X\n",
machine().describe_context(), chan.number, samples, chan.buf_count, chan.buf_size, chan.buf_rptr, chan.buf_wptr); machine().describe_context(), chan.number, outL.samples(), chan.buf_count, chan.buf_size, chan.buf_rptr, chan.buf_wptr);
// Buffer is 4 bytes per location, need to switch on sample mode // Buffer is 4 bytes per location, need to switch on sample mode
switch (chan.format) { switch (chan.format) {
case SCTRL_8BIT_MONO: case SCTRL_8BIT_MONO:
@ -324,23 +329,23 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s
logerror("es1373_device::send_audio_out SCTRL_8BIT_STEREO not implemented yet\n"); logerror("es1373_device::send_audio_out SCTRL_8BIT_STEREO not implemented yet\n");
break; break;
case SCTRL_16BIT_MONO: case SCTRL_16BIT_MONO:
// The sound cache is 32 bit wide fifo, so each entry is two mono 16 bit samples // The sound cache is 32 bit wide fifo, so each entry is two mono 16 bit samples
if ((chan.buf_count&0x1)) { if ((chan.buf_count&0x1)) {
// Read high 16 bits // Read high 16 bits
outL[i] = outR[i] = (int16_t)(m_sound_cache[chan.buf_rptr]>>16); lsamp = rsamp = m_sound_cache[chan.buf_rptr]>>16;
chan.buf_rptr++;
buf_row_done = true;
} else {
// Read low 16 bits
outL[i] = outR[i] = (int16_t)(m_sound_cache[chan.buf_rptr]&0xffff);
}
break;
case SCTRL_16BIT_STEREO:
// The sound cache is 32 bit wide fifo, so each entry is one stereo 16 bit sample
outL[i] = (int16_t) m_sound_cache[chan.buf_rptr]&0xffff;
outR[i] = (int16_t) m_sound_cache[chan.buf_rptr]>>16;
chan.buf_rptr++; chan.buf_rptr++;
buf_row_done = true; buf_row_done = true;
} else {
// Read low 16 bits
lsamp = rsamp = m_sound_cache[chan.buf_rptr]&0xffff;
}
break;
case SCTRL_16BIT_STEREO:
// The sound cache is 32 bit wide fifo, so each entry is one stereo 16 bit sample
lsamp = m_sound_cache[chan.buf_rptr]&0xffff;
rsamp = m_sound_cache[chan.buf_rptr]>>16;
chan.buf_rptr++;
buf_row_done = true;
break; break;
} }
if (LOG_ES_FILE && m_tempCount<1000000) { if (LOG_ES_FILE && m_tempCount<1000000) {
@ -368,10 +373,9 @@ void es1373_device::send_audio_out(chan_info& chan, uint32_t intr_mask, stream_s
if (buf_row_done && !(chan.buf_rptr&0xf)) { if (buf_row_done && !(chan.buf_rptr&0xf)) {
chan.buf_rptr -= 0x10; chan.buf_rptr -= 0x10;
} }
} else {
// Send zeros?
outL[i] = outR[i] = 0;
} }
outL.put(i, stream_buffer::sample_t(lsamp) * sample_scale);
outR.put(i, stream_buffer::sample_t(rsamp) * sample_scale);
} }
} }

View File

@ -29,7 +29,7 @@ protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
virtual void device_add_mconfig(machine_config &config) override; virtual void device_add_mconfig(machine_config &config) override;
virtual void device_post_load() override; virtual void device_post_load() override;
virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
// Sound stream // Sound stream
sound_stream *m_stream; sound_stream *m_stream;
@ -55,7 +55,7 @@ private:
void transfer_pci_audio(chan_info& chan, int type); void transfer_pci_audio(chan_info& chan, int type);
uint32_t calc_size(const uint8_t &format); uint32_t calc_size(const uint8_t &format);
void send_audio_out(chan_info& chan, uint32_t intr_mask, stream_sample_t *outL, stream_sample_t *outR, int samples); void send_audio_out(chan_info& chan, uint32_t intr_mask, write_stream_view &outL, write_stream_view &outR);
uint32_t m_tempCount; uint32_t m_tempCount;
emu_timer *m_timer; emu_timer *m_timer;

View File

@ -128,18 +128,19 @@ void es5503_device::halt_osc(int onum, int type, uint32_t *accumulator, int ress
} }
} }
void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) void es5503_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{ {
static int32_t mix[(44100/60)*2*8];
int32_t *mixp; int32_t *mixp;
int osc, snum, i; int osc, snum, i;
uint32_t ramptr; uint32_t ramptr;
assert(samples < (44100/60)*2); if (m_mix_buffer.size() < outputs[0].samples())
memset(mix, 0, sizeof(mix)); m_mix_buffer.resize(outputs[0].samples());
for (int chan = 0; chan < output_channels; chan++) for (int chan = 0; chan < output_channels; chan++)
{ {
std::fill_n(&m_mix_buffer[0], outputs[0].samples(), 0);
for (osc = 0; osc < (oscsenabled+1); osc++) for (osc = 0; osc < (oscsenabled+1); osc++)
{ {
ES5503Osc *pOsc = &oscillators[osc]; ES5503Osc *pOsc = &oscillators[osc];
@ -155,9 +156,9 @@ void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_samp
int8_t data = -128; int8_t data = -128;
int resshift = resshifts[pOsc->resolution] - pOsc->wavetblsize; int resshift = resshifts[pOsc->resolution] - pOsc->wavetblsize;
uint32_t sizemask = accmasks[pOsc->wavetblsize]; uint32_t sizemask = accmasks[pOsc->wavetblsize];
mixp = &mix[0] + chan; mixp = &m_mix_buffer[0];
for (snum = 0; snum < samples; snum++) for (snum = 0; snum < outputs[0].samples(); snum++)
{ {
altram = acc >> resshift; altram = acc >> resshift;
ramptr = altram & sizemask; ramptr = altram & sizemask;
@ -175,7 +176,7 @@ void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_samp
else else
{ {
*mixp += data * vol; *mixp += data * vol;
mixp += output_channels; mixp++;
if (altram >= wtsize) if (altram >= wtsize)
{ {
@ -196,12 +197,12 @@ void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_samp
pOsc->data = data ^ 0x80; pOsc->data = data ^ 0x80;
} }
} }
}
mixp = &mix[0]; mixp = &m_mix_buffer[0];
for (i = 0; i < samples; i++) constexpr stream_buffer::sample_t sample_scale = 1.0 / (32768.0 * 8.0);
for (int chan = 0; chan < output_channels; chan++) for (i = 0; i < outputs[chan].samples(); i++)
outputs[chan][i] = (*mixp++)>>3; outputs[chan].put(i, stream_buffer::sample_t(*mixp++) * sample_scale);
}
} }
@ -224,7 +225,7 @@ void es5503_device::device_start()
save_pointer(STRUCT_MEMBER(oscillators, irqpend), 32); save_pointer(STRUCT_MEMBER(oscillators, irqpend), 32);
output_rate = (clock() / 8) / (2 + oscsenabled); output_rate = (clock() / 8) / (2 + oscsenabled);
m_stream = stream_alloc_legacy(0, output_channels, output_rate); m_stream = stream_alloc(0, output_channels, output_rate);
m_timer = timer_alloc(0, nullptr); m_timer = timer_alloc(0, nullptr);
attotime update_rate = output_rate ? attotime::from_hz(output_rate) : attotime::never; attotime update_rate = output_rate ? attotime::from_hz(output_rate) : attotime::never;

View File

@ -36,7 +36,7 @@ protected:
virtual void device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) override; virtual void device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) override;
// device_sound_interface overrides // device_sound_interface overrides
virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
// device_rom_interface overrides // device_rom_interface overrides
virtual void rom_bank_updated() override; virtual void rom_bank_updated() override;
@ -83,6 +83,7 @@ private:
uint32_t output_rate; uint32_t output_rate;
emu_timer *m_timer; emu_timer *m_timer;
std::vector<int32_t> m_mix_buffer;
void halt_osc(int onum, int type, uint32_t *accumulator, int resshift); void halt_osc(int onum, int type, uint32_t *accumulator, int resshift);
}; };

View File

@ -106,7 +106,6 @@ static constexpr u32 FINE_FILTER_BIT = 16;
static constexpr u32 FILTER_BIT = 12; static constexpr u32 FILTER_BIT = 12;
static constexpr u32 FILTER_SHIFT = FINE_FILTER_BIT - FILTER_BIT; static constexpr u32 FILTER_SHIFT = FINE_FILTER_BIT - FILTER_BIT;
static constexpr u32 MAX_SAMPLE_CHUNK = 10000;
static constexpr u32 ULAW_MAXBITS = 8; static constexpr u32 ULAW_MAXBITS = 8;
namespace { namespace {
@ -163,9 +162,6 @@ es550x_device::es550x_device(const machine_config &mconfig, device_type type, co
, m_mode(0) , m_mode(0)
, m_irqv(0x80) , m_irqv(0x80)
, m_voice_index(0) , m_voice_index(0)
, m_scratch(nullptr)
, m_ulaw_lookup(nullptr)
, m_volume_lookup(nullptr)
#if ES5506_MAKE_WAVS #if ES5506_MAKE_WAVS
, m_wavraw(nullptr) , m_wavraw(nullptr)
#endif #endif
@ -208,9 +204,6 @@ void es550x_device::device_start()
m_sample_rate_changed_cb.resolve(); m_sample_rate_changed_cb.resolve();
m_irqv = 0x80; m_irqv = 0x80;
// allocate memory
m_scratch = make_unique_clear<s32[]>(2 * MAX_SAMPLE_CHUNK);
// register save // register save
save_item(NAME(m_sample_rate)); save_item(NAME(m_sample_rate));
@ -220,8 +213,6 @@ void es550x_device::device_start()
save_item(NAME(m_irqv)); save_item(NAME(m_irqv));
save_item(NAME(m_voice_index)); save_item(NAME(m_voice_index));
save_pointer(NAME(m_scratch), 2 * MAX_SAMPLE_CHUNK);
save_item(STRUCT_MEMBER(m_voice, control)); save_item(STRUCT_MEMBER(m_voice, control));
save_item(STRUCT_MEMBER(m_voice, freqcount)); save_item(STRUCT_MEMBER(m_voice, freqcount));
save_item(STRUCT_MEMBER(m_voice, start)); save_item(STRUCT_MEMBER(m_voice, start));
@ -249,7 +240,7 @@ void es5506_device::device_start()
channels = m_channels; channels = m_channels;
// create the stream // create the stream
m_stream = stream_alloc_legacy(0, 2 * channels, clock() / (16*32)); m_stream = stream_alloc(0, 2 * channels, clock() / (16*32));
// initialize the regions // initialize the regions
if (m_region0 && !has_configured_map(0)) if (m_region0 && !has_configured_map(0))
@ -378,7 +369,7 @@ void es5505_device::device_start()
channels = m_channels; channels = m_channels;
// create the stream // create the stream
m_stream = stream_alloc_legacy(0, 2 * channels, clock() / (16*32)); m_stream = stream_alloc(0, 2 * channels, clock() / (16*32));
// initialize the regions // initialize the regions
if (m_region0 && !has_configured_map(0)) if (m_region0 && !has_configured_map(0))
@ -455,7 +446,7 @@ void es550x_device::update_internal_irq_state()
void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 mantissa_bit) void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 mantissa_bit)
{ {
// allocate ulaw lookup table // allocate ulaw lookup table
m_ulaw_lookup = make_unique_clear<s16[]>(1 << ULAW_MAXBITS); m_ulaw_lookup.resize(1 << ULAW_MAXBITS);
// generate ulaw lookup table // generate ulaw lookup table
for (int i = 0; i < (1 << ULAW_MAXBITS); i++) for (int i = 0; i < (1 << ULAW_MAXBITS); i++)
@ -465,11 +456,11 @@ void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 m
u32 mantissa = (rawval << 3) & 0xffff; u32 mantissa = (rawval << 3) & 0xffff;
if (exponent == 0) if (exponent == 0)
m_ulaw_lookup[i] = (s16)mantissa >> 7; m_ulaw_lookup[i] = s16(mantissa) >> 7;
else else
{ {
mantissa = (mantissa >> 1) | (~mantissa & 0x8000); mantissa = (mantissa >> 1) | (~mantissa & 0x8000);
m_ulaw_lookup[i] = (s16)mantissa >> (7 - exponent); m_ulaw_lookup[i] = s16(mantissa) >> (7 - exponent);
} }
} }
@ -477,7 +468,7 @@ void es550x_device::compute_tables(u32 total_volume_bit, u32 exponent_bit, u32 m
m_volume_shift = total_volume_bit - volume_bit; m_volume_shift = total_volume_bit - volume_bit;
const u32 volume_len = 1 << volume_bit; const u32 volume_len = 1 << volume_bit;
// allocate volume lookup table // allocate volume lookup table
m_volume_lookup = make_unique_clear<u32[]>(volume_len); m_volume_lookup.resize(volume_len);
// generate volume lookup table // generate volume lookup table
const u32 exponent_shift = 1 << exponent_bit; const u32 exponent_shift = 1 << exponent_bit;
@ -831,7 +822,7 @@ inline void es5505_device::check_for_end_reverse(es550x_voice *voice, u64 &accum
***********************************************************************************************/ ***********************************************************************************************/
void es550x_device::generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples) void es550x_device::generate_ulaw(es550x_voice *voice, s32 *dest)
{ {
const u32 freqcount = voice->freqcount; const u32 freqcount = voice->freqcount;
u64 accum = voice->accum & m_address_acc_mask; u64 accum = voice->accum & m_address_acc_mask;
@ -862,8 +853,8 @@ void es550x_device::generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffe
update_envelopes(voice); update_envelopes(voice);
// apply volumes and add // apply volumes and add
*lbuffer += get_sample(val1, voice->lvol); dest[0] += get_sample(val1, voice->lvol);
*rbuffer += get_sample(val1, voice->rvol); dest[1] += get_sample(val1, voice->rvol);
// check for loop end // check for loop end
check_for_end_forward(voice, accum); check_for_end_forward(voice, accum);
@ -892,8 +883,8 @@ void es550x_device::generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffe
update_envelopes(voice); update_envelopes(voice);
// apply volumes and add // apply volumes and add
*lbuffer += get_sample(val1, voice->lvol); dest[0] += get_sample(val1, voice->lvol);
*rbuffer += get_sample(val1, voice->rvol); dest[1] += get_sample(val1, voice->rvol);
// check for loop end // check for loop end
check_for_end_reverse(voice, accum); check_for_end_reverse(voice, accum);
@ -917,7 +908,7 @@ void es550x_device::generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffe
***********************************************************************************************/ ***********************************************************************************************/
void es550x_device::generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples) void es550x_device::generate_pcm(es550x_voice *voice, s32 *dest)
{ {
const u32 freqcount = voice->freqcount; const u32 freqcount = voice->freqcount;
u64 accum = voice->accum & m_address_acc_mask; u64 accum = voice->accum & m_address_acc_mask;
@ -944,8 +935,8 @@ void es550x_device::generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer
update_envelopes(voice); update_envelopes(voice);
// apply volumes and add // apply volumes and add
*lbuffer += get_sample(val1, voice->lvol); dest[0] += get_sample(val1, voice->lvol);
*rbuffer += get_sample(val1, voice->rvol); dest[1] += get_sample(val1, voice->rvol);
// check for loop end // check for loop end
check_for_end_forward(voice, accum); check_for_end_forward(voice, accum);
@ -970,8 +961,8 @@ void es550x_device::generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer
update_envelopes(voice); update_envelopes(voice);
// apply volumes and add // apply volumes and add
*lbuffer += get_sample(val1, voice->lvol); dest[0] += get_sample(val1, voice->lvol);
*rbuffer += get_sample(val1, voice->rvol); dest[1] += get_sample(val1, voice->rvol);
// check for loop end // check for loop end
check_for_end_reverse(voice, accum); check_for_end_reverse(voice, accum);
@ -1022,22 +1013,13 @@ inline void es550x_device::generate_irq(es550x_voice *voice, int v)
***********************************************************************************************/ ***********************************************************************************************/
void es5506_device::generate_samples(s32 * const *outputs, int offset, int samples) void es5506_device::generate_samples(std::vector<write_stream_view> &outputs)
{ {
// skip if nothing to do
if (!samples)
return;
// clear out the accumulators
for (int i = 0; i < m_channels << 1; i++)
{
memset(outputs[i] + offset, 0, sizeof(s32) * samples);
}
// loop while we still have samples to generate // loop while we still have samples to generate
while (samples) for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++)
{ {
// loop over voices // loop over voices
s32 cursample[12] = { 0 };
for (int v = 0; v <= m_active_voices; v++) for (int v = 0; v <= m_active_voices; v++)
{ {
es550x_voice *voice = &m_voice[v]; es550x_voice *voice = &m_voice[v];
@ -1049,40 +1031,30 @@ void es5506_device::generate_samples(s32 * const *outputs, int offset, int sampl
const int voice_channel = get_ca(voice->control); const int voice_channel = get_ca(voice->control);
const int channel = voice_channel % m_channels; const int channel = voice_channel % m_channels;
const int l = channel << 1; const int l = channel << 1;
const int r = l + 1;
s32 *left = outputs[l] + offset;
s32 *right = outputs[r] + offset;
// generate from the appropriate source // generate from the appropriate source
if (voice->control & CONTROL_CMPD) if (voice->control & CONTROL_CMPD)
generate_ulaw(voice, left, right, samples); generate_ulaw(voice, &cursample[l]);
else else
generate_pcm(voice, left, right, samples); generate_pcm(voice, &cursample[l]);
// does this voice have it's IRQ bit raised? // does this voice have it's IRQ bit raised?
generate_irq(voice, v); generate_irq(voice, v);
} }
offset++;
samples--; constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0;
for (int c = 0; c < outputs.size(); c++)
outputs[c].put(sampindex, stream_buffer::sample_t(cursample[c]) * sample_scale);
} }
} }
void es5505_device::generate_samples(s32 * const *outputs, int offset, int samples) void es5505_device::generate_samples(std::vector<write_stream_view> &outputs)
{ {
// skip if nothing to do
if (!samples)
return;
// clear out the accumulators
for (int i = 0; i < m_channels << 1; i++)
{
memset(outputs[i] + offset, 0, sizeof(s32) * samples);
}
// loop while we still have samples to generate // loop while we still have samples to generate
while (samples) for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++)
{ {
// loop over voices // loop over voices
s32 cursample[12] = { 0 };
for (int v = 0; v <= m_active_voices; v++) for (int v = 0; v <= m_active_voices; v++)
{ {
es550x_voice *voice = &m_voice[v]; es550x_voice *voice = &m_voice[v];
@ -1100,19 +1072,18 @@ void es5505_device::generate_samples(s32 * const *outputs, int offset, int sampl
const int voice_channel = get_ca(voice->control); const int voice_channel = get_ca(voice->control);
const int channel = voice_channel % m_channels; const int channel = voice_channel % m_channels;
const int l = channel << 1; const int l = channel << 1;
const int r = l + 1;
s32 *left = outputs[l] + offset;
s32 *right = outputs[r] + offset;
// generate from the appropriate source // generate from the appropriate source
// no compressed sample support // no compressed sample support
generate_pcm(voice, left, right, samples); generate_pcm(voice, &cursample[l]);
// does this voice have it's IRQ bit raised? // does this voice have it's IRQ bit raised?
generate_irq(voice, v); generate_irq(voice, v);
} }
offset++;
samples--; constexpr stream_buffer::sample_t sample_scale = 1.0 / 32768.0;
for (int c = 0; c < outputs.size(); c++)
outputs[c].put(sampindex, stream_buffer::sample_t(cursample[c]) * sample_scale);
} }
} }
@ -2126,7 +2097,7 @@ u16 es5505_device::read(offs_t offset)
// sound_stream_update_legacy - handle a stream update // sound_stream_update_legacy - handle a stream update
//------------------------------------------------- //-------------------------------------------------
void es550x_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) void es550x_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{ {
#if ES5506_MAKE_WAVS #if ES5506_MAKE_WAVS
// start the logging once we have a sample rate // start the logging once we have a sample rate
@ -2138,39 +2109,30 @@ void es550x_device::sound_stream_update_legacy(sound_stream &stream, stream_samp
#endif #endif
// loop until all samples are output // loop until all samples are output
int offset = 0; generate_samples(outputs);
while (samples)
{
int length = (samples > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : samples;
generate_samples(outputs, offset, length);
#if ES5506_MAKE_WAVS #if ES5506_MAKE_WAVS
// log the raw data // log the raw data
if (m_wavraw) if (m_wavraw)
{ {
// determine left/right source data // determine left/right source data
s32 *lsrc = m_scratch, *rsrc = m_scratch + length;
int channel;
memset(lsrc, 0, sizeof(s32) * length * 2);
// loop over the output channels
for (channel = 0; channel < m_channels; channel++)
{
s32 *l = outputs[(channel << 1)] + offset;
s32 *r = outputs[(channel << 1) + 1] + offset;
// add the current channel's samples to the WAV data
for (samp = 0; samp < length; samp++)
{
lsrc[samp] += l[samp];
rsrc[samp] += r[samp];
}
}
wav_add_data_32lr(m_wavraw, lsrc, rsrc, length, 4);
}
#endif
// account for these samples s32 *lsrc = m_scratch, *rsrc = m_scratch + length;
offset += length; int channel;
samples -= length; memset(lsrc, 0, sizeof(s32) * length * 2);
// loop over the output channels
for (channel = 0; channel < m_channels; channel++)
{
s32 *l = outputs[(channel << 1)] + sampindex;
s32 *r = outputs[(channel << 1) + 1] + sampindex;
// add the current channel's samples to the WAV data
for (samp = 0; samp < length; samp++)
{
lsrc[samp] += l[samp];
rsrc[samp] += r[samp];
}
}
wav_add_data_32lr(m_wavraw, lsrc, rsrc, length, 4);
} }
#endif
} }

View File

@ -84,7 +84,7 @@ protected:
virtual void device_reset() override; virtual void device_reset() override;
// sound stream update overrides // sound stream update overrides
virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
void update_irq_state(); void update_irq_state();
void update_internal_irq_state(); void update_internal_irq_state();
@ -111,10 +111,10 @@ protected:
virtual void update_envelopes(es550x_voice *voice) = 0; virtual void update_envelopes(es550x_voice *voice) = 0;
virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) = 0; virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) = 0;
virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) = 0; virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) = 0;
void generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples); void generate_ulaw(es550x_voice *voice, s32 *dest);
void generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples); void generate_pcm(es550x_voice *voice, s32 *dest);
inline void generate_irq(es550x_voice *voice, int v); inline void generate_irq(es550x_voice *voice, int v);
virtual void generate_samples(s32 * const *outputs, int offset, int samples) {}; virtual void generate_samples(std::vector<write_stream_view> &outputs) {};
inline void update_index(es550x_voice *voice) { m_voice_index = voice->index; } inline void update_index(es550x_voice *voice) { m_voice_index = voice->index; }
virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) { return 0; } virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) { return 0; }
@ -137,12 +137,11 @@ protected:
es550x_voice m_voice[32]; // the 32 voices es550x_voice m_voice[32]; // the 32 voices
std::unique_ptr<s32[]> m_scratch; std::vector<s16> m_ulaw_lookup;
std::vector<u32> m_volume_lookup;
std::unique_ptr<s16[]> m_ulaw_lookup;
std::unique_ptr<u32[]> m_volume_lookup;
#if ES5506_MAKE_WAVS #if ES5506_MAKE_WAVS
std::vector<s32> m_scratch;
void * m_wavraw; // raw waveform void * m_wavraw; // raw waveform
#endif #endif
@ -190,7 +189,7 @@ protected:
virtual void update_envelopes(es550x_voice *voice) override; virtual void update_envelopes(es550x_voice *voice) override;
virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) override; virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) override;
virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) override; virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) override;
virtual void generate_samples(s32 * const *outputs, int offset, int samples) override; virtual void generate_samples(std::vector<write_stream_view> &outputs) override;
virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) override { update_index(voice); return m_cache[get_bank(voice->control)].read_word(addr); } virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) override { update_index(voice); return m_cache[get_bank(voice->control)].read_word(addr); }
@ -244,7 +243,7 @@ protected:
virtual void update_envelopes(es550x_voice *voice) override; virtual void update_envelopes(es550x_voice *voice) override;
virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) override; virtual void check_for_end_forward(es550x_voice *voice, u64 &accum) override;
virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) override; virtual void check_for_end_reverse(es550x_voice *voice, u64 &accum) override;
virtual void generate_samples(s32 * const *outputs, int offset, int samples) override; virtual void generate_samples(std::vector<write_stream_view> &outputs) override;
virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) override { update_index(voice); return m_cache[get_bank(voice->control)].read_word(addr); } virtual inline u16 read_sample(es550x_voice *voice, offs_t addr) override { update_index(voice); return m_cache[get_bank(voice->control)].read_word(addr); }

View File

@ -17,7 +17,6 @@ esq_5505_5510_pump_device::esq_5505_5510_pump_device(const machine_config &mconf
: device_t(mconfig, ESQ_5505_5510_PUMP, tag, owner, clock) : device_t(mconfig, ESQ_5505_5510_PUMP, tag, owner, clock)
, device_sound_interface(mconfig, *this) , device_sound_interface(mconfig, *this)
, m_stream(nullptr) , m_stream(nullptr)
, m_timer(nullptr)
, m_esp(*this, finder_base::DUMMY_TAG) , m_esp(*this, finder_base::DUMMY_TAG)
, m_esp_halted(true) , m_esp_halted(true)
, ticks_spent_processing(0) , ticks_spent_processing(0)
@ -32,9 +31,7 @@ void esq_5505_5510_pump_device::device_start()
{ {
logerror("Clock = %d\n", clock()); logerror("Clock = %d\n", clock());
m_stream = stream_alloc_legacy(8, 2, clock()); m_stream = stream_alloc(8, 2, clock(), STREAM_SYNCHRONOUS);
m_timer = timer_alloc(0);
m_timer->enable(false);
#if PUMP_DETECT_SILENCE #if PUMP_DETECT_SILENCE
silent_for = 500; silent_for = 500;
@ -51,49 +48,37 @@ void esq_5505_5510_pump_device::device_start()
#endif #endif
#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM #if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
e = make_unique_clear<int16_t[]>(0x4000); e.resize(0x4000);
ei = 0; ei = 0;
#endif #endif
} }
void esq_5505_5510_pump_device::device_stop()
{
m_timer->enable(false);
}
void esq_5505_5510_pump_device::device_reset()
{
m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock()));
m_timer->enable(true);
}
void esq_5505_5510_pump_device::device_clock_changed() void esq_5505_5510_pump_device::device_clock_changed()
{ {
m_stream->set_sample_rate(clock()); m_stream->set_sample_rate(clock());
m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock()));
} }
void esq_5505_5510_pump_device::sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) void esq_5505_5510_pump_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
{ {
if (samples != 1) { sound_assert(outputs[0].samples() == 1);
logerror("Pump: request for %d samples\n", samples);
}
stream_sample_t *left = outputs[0], *right = outputs[1]; auto &left = outputs[0];
for (int i = 0; i < samples; i++) auto &right = outputs[1];
{
#define SAMPLE_SHIFT 4 #define SAMPLE_SHIFT 4
constexpr stream_buffer::sample_t input_scale = 32768.0 / (1 << SAMPLE_SHIFT);
for (int i = 0; i < left.samples(); i++)
{
// anything for the 'aux' output? // anything for the 'aux' output?
int16_t l = inputs[0][i] >> SAMPLE_SHIFT; stream_buffer::sample_t l = inputs[0].get(i) * (1.0 / (1 << SAMPLE_SHIFT));
int16_t r = inputs[1][i] >> SAMPLE_SHIFT; stream_buffer::sample_t r = inputs[1].get(i) * (1.0 / (1 << SAMPLE_SHIFT));
// push the samples into the ESP // push the samples into the ESP
m_esp->ser_w(0, inputs[2][i] >> SAMPLE_SHIFT); m_esp->ser_w(0, s32(inputs[2].get(i) * input_scale));
m_esp->ser_w(1, inputs[3][i] >> SAMPLE_SHIFT); m_esp->ser_w(1, s32(inputs[3].get(i) * input_scale));
m_esp->ser_w(2, inputs[4][i] >> SAMPLE_SHIFT); m_esp->ser_w(2, s32(inputs[4].get(i) * input_scale));
m_esp->ser_w(3, inputs[5][i] >> SAMPLE_SHIFT); m_esp->ser_w(3, s32(inputs[5].get(i) * input_scale));
m_esp->ser_w(4, inputs[6][i] >> SAMPLE_SHIFT); m_esp->ser_w(4, s32(inputs[6].get(i) * input_scale));
m_esp->ser_w(5, inputs[7][i] >> SAMPLE_SHIFT); m_esp->ser_w(5, s32(inputs[7].get(i) * input_scale));
#if PUMP_FAKE_ESP_PROCESSING #if PUMP_FAKE_ESP_PROCESSING
m_esp->ser_w(6, m_esp->ser_r(0) + m_esp->ser_r(2) + m_esp->ser_r(4)); m_esp->ser_w(6, m_esp->ser_r(0) + m_esp->ser_r(2) + m_esp->ser_r(4));
@ -110,32 +95,32 @@ void esq_5505_5510_pump_device::sound_stream_update_legacy(sound_stream &stream,
#endif #endif
// read the processed result from the ESP and add to the saved AUX data // read the processed result from the ESP and add to the saved AUX data
int16_t ll = m_esp->ser_r(6); stream_buffer::sample_t ll = stream_buffer::sample_t(m_esp->ser_r(6)) * (1.0 / 32768.0);
int16_t rr = m_esp->ser_r(7); stream_buffer::sample_t rr = stream_buffer::sample_t(m_esp->ser_r(7)) * (1.0 / 32768.0);
l += ll; l += ll;
r += rr; r += rr;
#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM #if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
// if we're processing the fake program through the ESP, the result should just be that of adding the inputs // if we're processing the fake program through the ESP, the result should just be that of adding the inputs
int32_t el = (inputs[2][i]) + (inputs[4][i]) + (inputs[6][i]); stream_buffer::sample_t el = (inputs[2].get(i)) + (inputs[4].get(i)) + (inputs[6].get(i));
int32_t er = (inputs[3][i]) + (inputs[5][i]) + (inputs[7][i]); stream_buffer::sample_t er = (inputs[3].get(i)) + (inputs[5].get(i)) + (inputs[7].get(i));
int32_t e_next = el + er; stream_buffer::sample_t e_next = el + er;
e[(ei + 0x1d0f) % 0x4000] = e_next; e[(ei + 0x1d0f) % 0x4000] = e_next;
if (l != e[ei]) { if (fabs(l - e[ei]) > 1e-5) {
util::stream_format(std::cerr, "expected (%d) but have (%d)\n", e[ei], l); util::stream_format(std::cerr, "expected (%d) but have (%d)\n", e[ei], l);
} }
ei = (ei + 1) % 0x4000; ei = (ei + 1) % 0x4000;
#endif #endif
// write the combined data to the output // write the combined data to the output
*left++ = l; left.put(i, l);
*right++ = r; right.put(i, r);
} }
#if PUMP_DETECT_SILENCE #if PUMP_DETECT_SILENCE
for (int i = 0; i < samples; i++) { for (int i = 0; i < left.samples(); i++) {
if (outputs[0][i] == 0 && outputs[1][i] == 0) { if (left.get(i) == 0 && right.get(i) == 0) {
silent_for++; silent_for++;
} else { } else {
silent_for = 0; silent_for = 0;

View File

@ -70,12 +70,10 @@ public:
protected: protected:
// device-level overrides // device-level overrides
virtual void device_start() override; virtual void device_start() override;
virtual void device_stop() override;
virtual void device_reset() override;
virtual void device_clock_changed() override; virtual void device_clock_changed() override;
// sound stream update overrides // sound stream update overrides
virtual void sound_stream_update_legacy(sound_stream &stream, stream_sample_t const * const *inputs, stream_sample_t * const *outputs, int samples) override; virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
// timer callback overrides // timer callback overrides
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
@ -85,9 +83,6 @@ private:
// sound stream // sound stream
sound_stream *m_stream; sound_stream *m_stream;
// per-sample timer
emu_timer *m_timer;
// ESP signal processor // ESP signal processor
required_device<es5510_device> m_esp; required_device<es5510_device> m_esp;