summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2012-11-23 21:36:08 +0000
committer Olivier Galibert <galibert@pobox.com>2012-11-23 21:36:08 +0000
commitbcbec121dc0e97b4434a6fba39086bf2372ceee6 (patch)
tree0c498ea1b72ff390b6fab69979493d39f8cf8db3 /src/emu/sound
parent592df02da85adcc7aa1f78263e7e4f7995d5abd6 (diff)
es5503: Make the number of output channels configurable [O. Galibert]
Diffstat (limited to 'src/emu/sound')
-rw-r--r--src/emu/sound/es5503.c102
-rw-r--r--src/emu/sound/es5503.h13
2 files changed, 61 insertions, 54 deletions
diff --git a/src/emu/sound/es5503.c b/src/emu/sound/es5503.c
index 1296ff5ba36..390806bcd22 100644
--- a/src/emu/sound/es5503.c
+++ b/src/emu/sound/es5503.c
@@ -86,6 +86,12 @@ const address_space_config *es5503_device::memory_space_config(address_spacenum
// the IRQ callback
//-------------------------------------------------
+void es5503_device::static_set_channels(device_t &device, int channels)
+{
+ es5503_device &es5503 = downcast<es5503_device &>(device);
+ es5503.output_channels = channels;
+}
+
void es5503_device::static_set_irqf(device_t &device, void (*irqf)(device_t *device, int state))
{
es5503_device &es5503 = downcast<es5503_device &>(device);
@@ -160,7 +166,7 @@ void es5503_device::halt_osc(int onum, int type, UINT32 *accumulator, int resshi
void es5503_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
- static INT32 mix[(44100/60)*4];
+ static INT32 mix[(44100/60)*2*8];
INT32 *mixp;
int osc, snum, i;
UINT32 ramptr;
@@ -168,78 +174,70 @@ void es5503_device::sound_stream_update(sound_stream &stream, stream_sample_t **
assert(samples < (44100/60)*2);
memset(mix, 0, sizeof(mix));
- for (osc = 0; osc < (oscsenabled+1); osc++)
+ for (int chan = 0; chan < output_channels; chan++)
{
- ES5503Osc *pOsc = &oscillators[osc];
-
- mixp = &mix[0];
-
- if (!(pOsc->control & 1))
+ for (osc = 0; osc < (oscsenabled+1); osc++)
{
- UINT32 wtptr = pOsc->wavetblpointer & wavemasks[pOsc->wavetblsize], altram;
- UINT32 acc = pOsc->accumulator;
- UINT16 wtsize = pOsc->wtsize - 1;
- UINT8 ctrl = pOsc->control;
- UINT16 freq = pOsc->freq;
- INT16 vol = pOsc->vol;
- INT8 data = -128;
- int resshift = resshifts[pOsc->resolution] - pOsc->wavetblsize;
- UINT32 sizemask = accmasks[pOsc->wavetblsize];
-
- for (snum = 0; snum < samples; snum++)
+ ES5503Osc *pOsc = &oscillators[osc];
+
+ if (!(pOsc->control & 1) && ((pOsc->control >> 4) & (output_channels - 1)) == chan)
{
- altram = acc >> resshift;
- ramptr = altram & sizemask;
+ UINT32 wtptr = pOsc->wavetblpointer & wavemasks[pOsc->wavetblsize], altram;
+ UINT32 acc = pOsc->accumulator;
+ UINT16 wtsize = pOsc->wtsize - 1;
+ UINT8 ctrl = pOsc->control;
+ UINT16 freq = pOsc->freq;
+ INT16 vol = pOsc->vol;
+ INT8 data = -128;
+ int resshift = resshifts[pOsc->resolution] - pOsc->wavetblsize;
+ UINT32 sizemask = accmasks[pOsc->wavetblsize];
+ mixp = &mix[0] + chan;
+
+ for (snum = 0; snum < samples; snum++)
+ {
+ altram = acc >> resshift;
+ ramptr = altram & sizemask;
- acc += freq;
+ acc += freq;
- // channel strobe is always valid when reading; this allows potentially banking per voice
- m_channel_strobe = (ctrl>>4) & 0xf;
- data = (INT32)m_direct->read_raw_byte(ramptr + wtptr) ^ 0x80;
+ // channel strobe is always valid when reading; this allows potentially banking per voice
+ m_channel_strobe = (ctrl>>4) & 0xf;
+ data = (INT32)m_direct->read_raw_byte(ramptr + wtptr) ^ 0x80;
- if (m_direct->read_raw_byte(ramptr + wtptr) == 0x00)
- {
- halt_osc(osc, 1, &acc, resshift);
- }
- else
- {
- if (pOsc->control & 0x10)
+ if (m_direct->read_raw_byte(ramptr + wtptr) == 0x00)
{
- *mixp++ += (data * vol);
- mixp++;
+ halt_osc(osc, 1, &acc, resshift);
}
else
{
- mixp++;
- *mixp++ += (data * vol);
+ *mixp += data * vol;
+ mixp += output_channels;
+
+ if (altram >= wtsize)
+ {
+ halt_osc(osc, 0, &acc, resshift);
+ }
}
- if (altram >= wtsize)
+ // if oscillator halted, we've got no more samples to generate
+ if (pOsc->control & 1)
{
- halt_osc(osc, 0, &acc, resshift);
+ ctrl |= 1;
+ break;
}
}
- // if oscillator halted, we've got no more samples to generate
- if (pOsc->control & 1)
- {
- ctrl |= 1;
- break;
- }
+ pOsc->control = ctrl;
+ pOsc->accumulator = acc;
+ pOsc->data = data ^ 0x80;
}
-
- pOsc->control = ctrl;
- pOsc->accumulator = acc;
- pOsc->data = data ^ 0x80;
}
}
mixp = &mix[0];
for (i = 0; i < samples; i++)
- {
- outputs[0][i] = (*mixp++)>>1;
- outputs[1][i] = (*mixp++)>>1;
- }
+ for (int chan = 0; chan < output_channels; chan++)
+ outputs[chan][i] = (*mixp++)>>1;
}
@@ -267,7 +265,7 @@ void es5503_device::device_start()
}
output_rate = (clock()/8)/34; // (input clock / 8) / # of oscs. enabled + 2
- m_stream = machine().sound().stream_alloc(*this, 0, 2, output_rate, this);
+ m_stream = machine().sound().stream_alloc(*this, 0, output_channels, output_rate, this);
m_timer = timer_alloc(0, NULL);
m_timer->adjust(attotime::from_hz(output_rate), 0, attotime::from_hz(output_rate));
diff --git a/src/emu/sound/es5503.h b/src/emu/sound/es5503.h
index 1fa65378198..65f644dfedc 100644
--- a/src/emu/sound/es5503.h
+++ b/src/emu/sound/es5503.h
@@ -3,16 +3,23 @@
#ifndef __ES5503_H__
#define __ES5503_H__
-#define MCFG_ES5503_ADD(_tag, _clock, _irqf, _adcf) \
+// channels must be a power of two
+
+#define MCFG_ES5503_ADD(_tag, _clock, _channels, _irqf, _adcf) \
MCFG_DEVICE_ADD(_tag, ES5503, _clock) \
+ MCFG_ES5503_OUTPUT_CHANNELS(_channels) \
MCFG_ES5503_IRQ_FUNC(_irqf) \
MCFG_ES5503_ADC_FUNC(_adcf)
-#define MCFG_ES5503_REPLACE(_tag, _clock, _irqf, _adcf) \
+#define MCFG_ES5503_REPLACE(_tag, _clock, _channels, _irqf, _adcf) \
MCFG_DEVICE_REPLACE(_tag, ES5503, _clock) \
+ MCFG_ES5503_OUTPUT_CHANNELS(_channels) \
MCFG_ES5503_IRQ_FUNC(_irqf) \
MCFG_ES5503_ADC_FUNC(_adcf)
+#define MCFG_ES5503_OUTPUT_CHANNELS(_channels) \
+ es5503_device::static_set_channels(*device, _channels); \
+
#define MCFG_ES5503_IRQ_FUNC(_irqf) \
es5503_device::static_set_irqf(*device, _irqf); \
@@ -29,6 +36,7 @@ public:
// construction/destruction
es5503_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ static void static_set_channels(device_t &device, int channels);
static void static_set_irqf(device_t &device, void (*irqf)(device_t *device, int state));
static void static_set_adcf(device_t &device, UINT8 (*adcf)(device_t *device));
@@ -89,6 +97,7 @@ private:
UINT8 m_channel_strobe;
+ int output_channels;
UINT32 output_rate;
emu_timer *m_timer;