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));
// 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->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
// 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) {
logerror("%s: sound_stream_update_legacy DAC1 not implemented yet\n", tag());
}
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.format!=SCTRL_16BIT_MONO) {
logerror("%s: sound_stream_update_legacy Only SCTRL_16BIT_MONO recorded supported\n", tag());
} 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 (LOG_ES)
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
//-------------------------------------------------
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
// 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);
// Send data to sound stream
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;
int16_t lsamp = 0, rsamp = 0;
if (chan.buf_count<=chan.buf_size) {
// Only transfer PCI data if bus mastering is enabled
// 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)
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
switch (chan.format) {
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");
break;
case SCTRL_16BIT_MONO:
// The sound cache is 32 bit wide fifo, so each entry is two mono 16 bit samples
if ((chan.buf_count&0x1)) {
// Read high 16 bits
outL[i] = outR[i] = (int16_t)(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;
// The sound cache is 32 bit wide fifo, so each entry is two mono 16 bit samples
if ((chan.buf_count&0x1)) {
// Read high 16 bits
lsamp = rsamp = m_sound_cache[chan.buf_rptr]>>16;
chan.buf_rptr++;
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;
}
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)) {
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_add_mconfig(machine_config &config) 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 *m_stream;
@ -55,7 +55,7 @@ private:
void transfer_pci_audio(chan_info& chan, int type);
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;
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;
int osc, snum, i;
uint32_t ramptr;
assert(samples < (44100/60)*2);
memset(mix, 0, sizeof(mix));
if (m_mix_buffer.size() < outputs[0].samples())
m_mix_buffer.resize(outputs[0].samples());
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++)
{
ES5503Osc *pOsc = &oscillators[osc];
@ -155,9 +156,9 @@ void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_samp
int8_t data = -128;
int resshift = resshifts[pOsc->resolution] - 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;
ramptr = altram & sizemask;
@ -175,7 +176,7 @@ void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_samp
else
{
*mixp += data * vol;
mixp += output_channels;
mixp++;
if (altram >= wtsize)
{
@ -196,12 +197,12 @@ void es5503_device::sound_stream_update_legacy(sound_stream &stream, stream_samp
pOsc->data = data ^ 0x80;
}
}
}
mixp = &mix[0];
for (i = 0; i < samples; i++)
for (int chan = 0; chan < output_channels; chan++)
outputs[chan][i] = (*mixp++)>>3;
mixp = &m_mix_buffer[0];
constexpr stream_buffer::sample_t sample_scale = 1.0 / (32768.0 * 8.0);
for (i = 0; i < outputs[chan].samples(); i++)
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);
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);
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;
// 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
virtual void rom_bank_updated() override;
@ -83,6 +83,7 @@ private:
uint32_t output_rate;
emu_timer *m_timer;
std::vector<int32_t> m_mix_buffer;
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_SHIFT = FINE_FILTER_BIT - FILTER_BIT;
static constexpr u32 MAX_SAMPLE_CHUNK = 10000;
static constexpr u32 ULAW_MAXBITS = 8;
namespace {
@ -163,9 +162,6 @@ es550x_device::es550x_device(const machine_config &mconfig, device_type type, co
, m_mode(0)
, m_irqv(0x80)
, m_voice_index(0)
, m_scratch(nullptr)
, m_ulaw_lookup(nullptr)
, m_volume_lookup(nullptr)
#if ES5506_MAKE_WAVS
, m_wavraw(nullptr)
#endif
@ -208,9 +204,6 @@ void es550x_device::device_start()
m_sample_rate_changed_cb.resolve();
m_irqv = 0x80;
// allocate memory
m_scratch = make_unique_clear<s32[]>(2 * MAX_SAMPLE_CHUNK);
// register save
save_item(NAME(m_sample_rate));
@ -220,8 +213,6 @@ void es550x_device::device_start()
save_item(NAME(m_irqv));
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, freqcount));
save_item(STRUCT_MEMBER(m_voice, start));
@ -249,7 +240,7 @@ void es5506_device::device_start()
channels = m_channels;
// 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
if (m_region0 && !has_configured_map(0))
@ -378,7 +369,7 @@ void es5505_device::device_start()
channels = m_channels;
// 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
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)
{
// 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
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;
if (exponent == 0)
m_ulaw_lookup[i] = (s16)mantissa >> 7;
m_ulaw_lookup[i] = s16(mantissa) >> 7;
else
{
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;
const u32 volume_len = 1 << volume_bit;
// allocate volume lookup table
m_volume_lookup = make_unique_clear<u32[]>(volume_len);
m_volume_lookup.resize(volume_len);
// generate volume lookup table
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;
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);
// apply volumes and add
*lbuffer += get_sample(val1, voice->lvol);
*rbuffer += get_sample(val1, voice->rvol);
dest[0] += get_sample(val1, voice->lvol);
dest[1] += get_sample(val1, voice->rvol);
// check for loop end
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);
// apply volumes and add
*lbuffer += get_sample(val1, voice->lvol);
*rbuffer += get_sample(val1, voice->rvol);
dest[0] += get_sample(val1, voice->lvol);
dest[1] += get_sample(val1, voice->rvol);
// check for loop end
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;
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);
// apply volumes and add
*lbuffer += get_sample(val1, voice->lvol);
*rbuffer += get_sample(val1, voice->rvol);
dest[0] += get_sample(val1, voice->lvol);
dest[1] += get_sample(val1, voice->rvol);
// check for loop end
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);
// apply volumes and add
*lbuffer += get_sample(val1, voice->lvol);
*rbuffer += get_sample(val1, voice->rvol);
dest[0] += get_sample(val1, voice->lvol);
dest[1] += get_sample(val1, voice->rvol);
// check for loop end
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
while (samples)
for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++)
{
// loop over voices
s32 cursample[12] = { 0 };
for (int v = 0; v <= m_active_voices; 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 channel = voice_channel % m_channels;
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
if (voice->control & CONTROL_CMPD)
generate_ulaw(voice, left, right, samples);
generate_ulaw(voice, &cursample[l]);
else
generate_pcm(voice, left, right, samples);
generate_pcm(voice, &cursample[l]);
// does this voice have it's IRQ bit raised?
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
while (samples)
for (int sampindex = 0; sampindex < outputs[0].samples(); sampindex++)
{
// loop over voices
s32 cursample[12] = { 0 };
for (int v = 0; v <= m_active_voices; 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 channel = voice_channel % m_channels;
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
// no compressed sample support
generate_pcm(voice, left, right, samples);
generate_pcm(voice, &cursample[l]);
// does this voice have it's IRQ bit raised?
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
//-------------------------------------------------
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
// 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
// loop until all samples are output
int offset = 0;
while (samples)
{
int length = (samples > MAX_SAMPLE_CHUNK) ? MAX_SAMPLE_CHUNK : samples;
generate_samples(outputs, offset, length);
generate_samples(outputs);
#if ES5506_MAKE_WAVS
// log the raw data
if (m_wavraw)
{
// 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
// log the raw data
if (m_wavraw)
{
// determine left/right source data
// account for these samples
offset += length;
samples -= length;
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)] + 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;
// 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_internal_irq_state();
@ -111,10 +111,10 @@ protected:
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_reverse(es550x_voice *voice, u64 &accum) = 0;
void generate_ulaw(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples);
void generate_pcm(es550x_voice *voice, s32 *lbuffer, s32 *rbuffer, int samples);
void generate_ulaw(es550x_voice *voice, s32 *dest);
void generate_pcm(es550x_voice *voice, s32 *dest);
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; }
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
std::unique_ptr<s32[]> m_scratch;
std::unique_ptr<s16[]> m_ulaw_lookup;
std::unique_ptr<u32[]> m_volume_lookup;
std::vector<s16> m_ulaw_lookup;
std::vector<u32> m_volume_lookup;
#if ES5506_MAKE_WAVS
std::vector<s32> m_scratch;
void * m_wavraw; // raw waveform
#endif
@ -190,7 +189,7 @@ protected:
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_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); }
@ -244,7 +243,7 @@ protected:
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_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); }

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_sound_interface(mconfig, *this)
, m_stream(nullptr)
, m_timer(nullptr)
, m_esp(*this, finder_base::DUMMY_TAG)
, m_esp_halted(true)
, ticks_spent_processing(0)
@ -32,9 +31,7 @@ void esq_5505_5510_pump_device::device_start()
{
logerror("Clock = %d\n", clock());
m_stream = stream_alloc_legacy(8, 2, clock());
m_timer = timer_alloc(0);
m_timer->enable(false);
m_stream = stream_alloc(8, 2, clock(), STREAM_SYNCHRONOUS);
#if PUMP_DETECT_SILENCE
silent_for = 500;
@ -51,49 +48,37 @@ void esq_5505_5510_pump_device::device_start()
#endif
#if !PUMP_FAKE_ESP_PROCESSING && PUMP_REPLACE_ESP_PROGRAM
e = make_unique_clear<int16_t[]>(0x4000);
e.resize(0x4000);
ei = 0;
#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()
{
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) {
logerror("Pump: request for %d samples\n", samples);
}
sound_assert(outputs[0].samples() == 1);
stream_sample_t *left = outputs[0], *right = outputs[1];
for (int i = 0; i < samples; i++)
{
auto &left = outputs[0];
auto &right = outputs[1];
#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?
int16_t l = inputs[0][i] >> SAMPLE_SHIFT;
int16_t r = inputs[1][i] >> SAMPLE_SHIFT;
stream_buffer::sample_t l = inputs[0].get(i) * (1.0 / (1 << SAMPLE_SHIFT));
stream_buffer::sample_t r = inputs[1].get(i) * (1.0 / (1 << SAMPLE_SHIFT));
// push the samples into the ESP
m_esp->ser_w(0, inputs[2][i] >> SAMPLE_SHIFT);
m_esp->ser_w(1, inputs[3][i] >> SAMPLE_SHIFT);
m_esp->ser_w(2, inputs[4][i] >> SAMPLE_SHIFT);
m_esp->ser_w(3, inputs[5][i] >> SAMPLE_SHIFT);
m_esp->ser_w(4, inputs[6][i] >> SAMPLE_SHIFT);
m_esp->ser_w(5, inputs[7][i] >> SAMPLE_SHIFT);
m_esp->ser_w(0, s32(inputs[2].get(i) * input_scale));
m_esp->ser_w(1, s32(inputs[3].get(i) * input_scale));
m_esp->ser_w(2, s32(inputs[4].get(i) * input_scale));
m_esp->ser_w(3, s32(inputs[5].get(i) * input_scale));
m_esp->ser_w(4, s32(inputs[6].get(i) * input_scale));
m_esp->ser_w(5, s32(inputs[7].get(i) * input_scale));
#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));
@ -110,32 +95,32 @@ void esq_5505_5510_pump_device::sound_stream_update_legacy(sound_stream &stream,
#endif
// read the processed result from the ESP and add to the saved AUX data
int16_t ll = m_esp->ser_r(6);
int16_t rr = m_esp->ser_r(7);
stream_buffer::sample_t ll = stream_buffer::sample_t(m_esp->ser_r(6)) * (1.0 / 32768.0);
stream_buffer::sample_t rr = stream_buffer::sample_t(m_esp->ser_r(7)) * (1.0 / 32768.0);
l += ll;
r += rr;
#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
int32_t el = (inputs[2][i]) + (inputs[4][i]) + (inputs[6][i]);
int32_t er = (inputs[3][i]) + (inputs[5][i]) + (inputs[7][i]);
int32_t e_next = el + er;
stream_buffer::sample_t el = (inputs[2].get(i)) + (inputs[4].get(i)) + (inputs[6].get(i));
stream_buffer::sample_t er = (inputs[3].get(i)) + (inputs[5].get(i)) + (inputs[7].get(i));
stream_buffer::sample_t e_next = el + er;
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);
}
ei = (ei + 1) % 0x4000;
#endif
// write the combined data to the output
*left++ = l;
*right++ = r;
left.put(i, l);
right.put(i, r);
}
#if PUMP_DETECT_SILENCE
for (int i = 0; i < samples; i++) {
if (outputs[0][i] == 0 && outputs[1][i] == 0) {
for (int i = 0; i < left.samples(); i++) {
if (left.get(i) == 0 && right.get(i) == 0) {
silent_for++;
} else {
silent_for = 0;

View File

@ -70,12 +70,10 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_stop() override;
virtual void device_reset() override;
virtual void device_clock_changed() override;
// 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
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 *m_stream;
// per-sample timer
emu_timer *m_timer;
// ESP signal processor
required_device<es5510_device> m_esp;