diff options
Diffstat (limited to 'src/emu/sound/disc_inp.inc')
-rw-r--r-- | src/emu/sound/disc_inp.inc | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/src/emu/sound/disc_inp.inc b/src/emu/sound/disc_inp.inc new file mode 100644 index 00000000000..fa7f292ec67 --- /dev/null +++ b/src/emu/sound/disc_inp.inc @@ -0,0 +1,342 @@ +/************************************************************************ + * + * MAME - Discrete sound system emulation library + * + * Written by Keith Wilkins (mame@esplexo.co.uk) + * + * (c) K.Wilkins 2000 + * + *********************************************************************** + * + * DSS_ADJUSTMENT - UI Mapped adjustable input + * DSS_CONSTANT - Node based constant - Do we need this ??? + * DSS_INPUT_x - Input devices + * DSS_INPUT_STREAM - Connects external streams to the discrete system + * + ************************************************************************/ + + +#define DSS_INPUT__GAIN DISCRETE_INPUT(0) +#define DSS_INPUT__OFFSET DISCRETE_INPUT(1) +#define DSS_INPUT__INIT DISCRETE_INPUT(2) + +READ8_DEVICE_HANDLER(discrete_sound_r) +{ + discrete_device *disc_device = downcast<discrete_device *>(device); + return disc_device->read( space, offset, 0xff); +} + + +WRITE8_DEVICE_HANDLER(discrete_sound_w) +{ + discrete_device *disc_device = downcast<discrete_device *>(device); + disc_device->write(space, offset, data, 0xff); +} + +/************************************************************************ + * + * DSS_ADJUSTMENT - UI Adjustable constant node to emulate trimmers + * + * input[0] - Enable + * input[1] - Minimum value + * input[2] - Maximum value + * input[3] - Log/Linear 0=Linear !0=Log + * input[4] - Input Port number + * input[5] - + * input[6] - + * + ************************************************************************/ +#define DSS_ADJUSTMENT__MIN DISCRETE_INPUT(0) +#define DSS_ADJUSTMENT__MAX DISCRETE_INPUT(1) +#define DSS_ADJUSTMENT__LOG DISCRETE_INPUT(2) +#define DSS_ADJUSTMENT__PORT DISCRETE_INPUT(3) +#define DSS_ADJUSTMENT__PMIN DISCRETE_INPUT(4) +#define DSS_ADJUSTMENT__PMAX DISCRETE_INPUT(5) + +DISCRETE_STEP(dss_adjustment) +{ + INT32 rawportval = m_port->read(); + + /* only recompute if the value changed from last time */ + if (UNEXPECTED(rawportval != m_lastpval)) + { + double portval = (double)(rawportval - m_pmin) * m_pscale; + double scaledval = portval * m_scale + m_min; + + m_lastpval = rawportval; + if (DSS_ADJUSTMENT__LOG == 0) + set_output(0, scaledval); + else + set_output(0, pow(10, scaledval)); + } +} + +DISCRETE_RESET(dss_adjustment) +{ + double min, max; + + astring fulltag; + m_port = m_device->machine().root_device().ioport(m_device->siblingtag(fulltag, (const char *)this->custom_data()).cstr()); + if (m_port == NULL) + fatalerror("DISCRETE_ADJUSTMENT - NODE_%d has invalid tag\n", this->index()); + + m_lastpval = 0x7fffffff; + m_pmin = DSS_ADJUSTMENT__PMIN; + m_pscale = 1.0 / (double)(DSS_ADJUSTMENT__PMAX - DSS_ADJUSTMENT__PMIN); + + /* linear scale */ + if (DSS_ADJUSTMENT__LOG == 0) + { + m_min = DSS_ADJUSTMENT__MIN; + m_scale = DSS_ADJUSTMENT__MAX - DSS_ADJUSTMENT__MIN; + } + + /* logarithmic scale */ + else + { + /* force minimum and maximum to be > 0 */ + min = (DSS_ADJUSTMENT__MIN > 0) ? DSS_ADJUSTMENT__MIN : 1; + max = (DSS_ADJUSTMENT__MAX > 0) ? DSS_ADJUSTMENT__MAX : 1; + m_min = log10(min); + m_scale = log10(max) - log10(min); + } + + this->step(); +} + + +/************************************************************************ + * + * DSS_CONSTANT - This is a constant. + * + * input[0] - Constant value + * + ************************************************************************/ +#define DSS_CONSTANT__INIT DISCRETE_INPUT(0) + +DISCRETE_RESET(dss_constant) +{ + set_output(0, DSS_CONSTANT__INIT); +} + + +/************************************************************************ + * + * DSS_INPUT_x - Receives input from discrete_sound_w + * + * input[0] - Gain value + * input[1] - Offset value + * input[2] - Starting Position + * input[3] - Current data value + * + ************************************************************************/ + +DISCRETE_RESET(dss_input_data) +{ + m_gain = DSS_INPUT__GAIN; + m_offset = DSS_INPUT__OFFSET; + + m_data = DSS_INPUT__INIT; + set_output(0, m_data * m_gain + m_offset); +} + +void DISCRETE_CLASS_FUNC(dss_input_data, input_write)(int sub_node, UINT8 data ) +{ + UINT8 new_data = 0; + + new_data = data; + + if (m_data != new_data) + { + /* Bring the system up to now */ + m_device->update_to_current_time(); + + m_data = new_data; + + /* Update the node output here so we don't have to do it each step */ + set_output(0, m_data * m_gain + m_offset); + } +} + +DISCRETE_RESET(dss_input_logic) +{ + m_gain = DSS_INPUT__GAIN; + m_offset = DSS_INPUT__OFFSET; + + m_data = (DSS_INPUT__INIT == 0) ? 0 : 1; + set_output(0, m_data * m_gain + m_offset); +} + +void DISCRETE_CLASS_FUNC(dss_input_logic, input_write)(int sub_node, UINT8 data ) +{ + UINT8 new_data = 0; + + new_data = data ? 1 : 0; + + if (m_data != new_data) + { + /* Bring the system up to now */ + m_device->update_to_current_time(); + + m_data = new_data; + + /* Update the node output here so we don't have to do it each step */ + set_output(0, m_data * m_gain + m_offset); + } +} + +DISCRETE_RESET(dss_input_not) +{ + m_gain = DSS_INPUT__GAIN; + m_offset = DSS_INPUT__OFFSET; + + m_data = (DSS_INPUT__INIT == 0) ? 1 : 0; + set_output(0, m_data * m_gain + m_offset); +} + +void DISCRETE_CLASS_FUNC(dss_input_not, input_write)(int sub_node, UINT8 data ) +{ + UINT8 new_data = 0; + + new_data = data ? 0 : 1; + + if (m_data != new_data) + { + /* Bring the system up to now */ + m_device->update_to_current_time(); + + m_data = new_data; + + /* Update the node output here so we don't have to do it each step */ + set_output(0, m_data * m_gain + m_offset); + } +} + +DISCRETE_STEP(dss_input_pulse) +{ + /* Set a valid output */ + set_output(0, m_data); + /* Reset the input to default for the next cycle */ + /* node order is now important */ + m_data = DSS_INPUT__INIT; +} + +DISCRETE_RESET(dss_input_pulse) +{ + m_data = (DSS_INPUT__INIT == 0) ? 0 : 1; + set_output(0, m_data); +} + +void DISCRETE_CLASS_FUNC(dss_input_pulse, input_write)(int sub_node, UINT8 data ) +{ + UINT8 new_data = 0; + + new_data = data ? 1 : 0; + + if (m_data != new_data) + { + /* Bring the system up to now */ + m_device->update_to_current_time(); + m_data = new_data; + } +} + +/************************************************************************ + * + * DSS_INPUT_STREAM - Receives input from a routed stream + * + * input[0] - Input stream number + * input[1] - Gain value + * input[2] - Offset value + * + ************************************************************************/ +#define DSS_INPUT_STREAM__STREAM DISCRETE_INPUT(0) +#define DSS_INPUT_STREAM__GAIN DISCRETE_INPUT(1) +#define DSS_INPUT_STREAM__OFFSET DISCRETE_INPUT(2) + +STREAM_UPDATE( discrete_dss_input_stream_node::static_stream_generate ) +{ + reinterpret_cast<discrete_dss_input_stream_node *>(param)->stream_generate(inputs, outputs, samples); +} + +void discrete_dss_input_stream_node::stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + stream_sample_t *ptr = outputs[0]; + int samplenum = samples; + + while (samplenum-- > 0) + *(ptr++) = m_data; +} +DISCRETE_STEP(dss_input_stream) +{ + /* the context pointer is set to point to the current input stream data in discrete_stream_update */ + if (EXPECTED(m_ptr)) + { + set_output(0, (*m_ptr) * m_gain + m_offset); + m_ptr++; + } + else + set_output(0, 0); +} + +DISCRETE_RESET(dss_input_stream) +{ + m_ptr = NULL; + m_data = 0; +} + +void DISCRETE_CLASS_FUNC(dss_input_stream, input_write)(int sub_node, UINT8 data ) +{ + UINT8 new_data = 0; + + new_data = data; + + if (m_data != new_data) + { + if (m_is_buffered) + { + /* Bring the system up to now */ + m_buffer_stream->update(); + + m_data = new_data; + } + else + { + /* Bring the system up to now */ + m_device->update_to_current_time(); + + m_data = new_data; + + /* Update the node output here so we don't have to do it each step */ + set_output(0, new_data * m_gain + m_offset); + } + } +} + +DISCRETE_START(dss_input_stream) +{ + discrete_base_node::start(); + + /* Stream out number is set during start */ + m_stream_in_number = DSS_INPUT_STREAM__STREAM; + m_gain = DSS_INPUT_STREAM__GAIN; + m_offset = DSS_INPUT_STREAM__OFFSET; + m_ptr = NULL; + + m_is_buffered = is_buffered(); + m_buffer_stream = NULL; +} + +void DISCRETE_CLASS_NAME(dss_input_stream)::stream_start(void) +{ + if (m_is_buffered) + { + /* stream_buffered input only supported for sound devices */ + discrete_sound_device *snd_device = downcast<discrete_sound_device *>(m_device); + //assert(DSS_INPUT_STREAM__STREAM < snd_device->m_input_stream_list.count()); + + m_buffer_stream = m_device->machine().sound().stream_alloc(*snd_device, 0, 1, this->sample_rate(), this, static_stream_generate); + + snd_device->get_stream()->set_input(m_stream_in_number, m_buffer_stream); + } +} |