summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound/disc_inp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/sound/disc_inp.c')
-rw-r--r--src/emu/sound/disc_inp.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/emu/sound/disc_inp.c b/src/emu/sound/disc_inp.c
new file mode 100644
index 00000000000..856e8077544
--- /dev/null
+++ b/src/emu/sound/disc_inp.c
@@ -0,0 +1,261 @@
+/************************************************************************
+ *
+ * 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 (*(node->input[0]))
+#define DSS_INPUT__OFFSET (*(node->input[1]))
+#define DSS_INPUT__INIT (*(node->input[2]))
+
+
+struct dss_adjustment_context
+{
+ INT32 port;
+ INT32 lastpval;
+ INT32 pmin;
+ double pscale;
+ double min;
+ double scale;
+};
+
+
+READ8_HANDLER(discrete_sound_r)
+{
+ discrete_info *info = sndti_token(SOUND_DISCRETE, 0);
+ node_description *node = discrete_find_node(info, offset);
+ UINT8 data = 0;
+
+ /* Read the node input value if allowed */
+ if (node)
+ {
+ UINT8 *node_data = node->context;
+
+ if ((node->module.type >= DSS_INPUT_DATA) && (node->module.type <= DSS_INPUT_PULSE))
+ {
+ data = *node_data;
+ }
+ }
+ else
+ discrete_log("discrete_sound_r read from non-existent NODE_%02d\n", offset-NODE_00);
+
+ return data;
+}
+
+WRITE8_HANDLER(discrete_sound_w)
+{
+ discrete_info *info = sndti_token(SOUND_DISCRETE, 0);
+ node_description *node = discrete_find_node(info, offset);
+
+ /* Update the node input value if it's a proper input node */
+ if (node)
+ {
+ UINT8 *node_data = node->context;
+ UINT8 last_data = *node_data;
+
+ switch (node->module.type)
+ {
+ case DSS_INPUT_DATA:
+ *node_data = data;
+ break;
+ case DSS_INPUT_LOGIC:
+ case DSS_INPUT_PULSE:
+ *node_data = data ? 1 : 0;
+ break;
+ case DSS_INPUT_NOT:
+ *node_data = data ? 0 : 1;
+ break;
+ }
+
+ /* Bring the system up to now */
+ if (last_data != *node_data)
+ stream_update(info->discrete_stream);
+ }
+ else
+ {
+ discrete_log("discrete_sound_w write to non-existent NODE_%02d\n", offset-NODE_00);
+ }
+}
+
+
+/************************************************************************
+ *
+ * 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__ENABLE (*(node->input[0]))
+#define DSS_ADJUSTMENT__MIN (*(node->input[1]))
+#define DSS_ADJUSTMENT__MAX (*(node->input[2]))
+#define DSS_ADJUSTMENT__LOG (*(node->input[3]))
+#define DSS_ADJUSTMENT__PORT (*(node->input[4]))
+#define DSS_ADJUSTMENT__PMIN (*(node->input[5]))
+#define DSS_ADJUSTMENT__PMAX (*(node->input[6]))
+
+void dss_adjustment_step(node_description *node)
+{
+ if (DSS_ADJUSTMENT__ENABLE)
+ {
+ struct dss_adjustment_context *context = node->context;
+ INT32 rawportval = readinputport(context->port);
+
+ /* only recompute if the value changed from last time */
+ if (rawportval != context->lastpval)
+ {
+ double portval = (double)(rawportval - context->pmin) * context->pscale;
+ double scaledval = portval * context->scale + context->min;
+
+ context->lastpval = rawportval;
+ if (DSS_ADJUSTMENT__LOG == 0)
+ node->output = scaledval;
+ else
+ node->output = pow(10, scaledval);
+ }
+ }
+ else
+ {
+ node->output = 0;
+ }
+}
+
+void dss_adjustment_reset(node_description *node)
+{
+ struct dss_adjustment_context *context = node->context;
+ double min, max;
+
+ if (node->custom)
+ {
+ context->port = port_tag_to_index(node->custom);
+ if (context->port == -1)
+ fatalerror("DISCRETE_ADJUSTMENT_TAG - NODE_%d has invalid tag", node->node-NODE_00);
+ }
+ else
+ context->port = DSS_ADJUSTMENT__PORT;
+
+ context->lastpval = 0x7fffffff;
+ context->pmin = DSS_ADJUSTMENT__PMIN;
+ context->pscale = 1.0 / (double)(DSS_ADJUSTMENT__PMAX - DSS_ADJUSTMENT__PMIN);
+
+ /* linear scale */
+ if (DSS_ADJUSTMENT__LOG == 0)
+ {
+ context->min = DSS_ADJUSTMENT__MIN;
+ context->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;
+ context->min = log10(min);
+ context->scale = log10(max) - log10(min);
+ }
+
+ dss_adjustment_step(node);
+}
+
+
+/************************************************************************
+ *
+ * DSS_CONSTANT - This is a constant.
+ *
+ * input[0] - Constant value
+ *
+ ************************************************************************/
+#define DSS_CONSTANT__INIT (*(node->input[0]))
+
+void dss_constant_step(node_description *node)
+{
+ node->output= 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
+ *
+ ************************************************************************/
+void dss_input_step(node_description *node)
+{
+ UINT8 *node_data = node->context;
+
+ node->output = *node_data * DSS_INPUT__GAIN + DSS_INPUT__OFFSET;
+}
+
+void dss_input_reset(node_description *node)
+{
+ UINT8 *node_data = node->context;
+
+ switch (node->module.type)
+ {
+ case DSS_INPUT_DATA:
+ *node_data = DSS_INPUT__INIT;
+ break;
+ case DSS_INPUT_LOGIC:
+ case DSS_INPUT_PULSE:
+ *node_data = (DSS_INPUT__INIT == 0) ? 0 : 1;
+ break;
+ case DSS_INPUT_NOT:
+ *node_data = (DSS_INPUT__INIT == 0) ? 1 : 0;
+ break;
+ }
+ dss_input_step(node);
+}
+
+void dss_input_pulse_step(node_description *node)
+{
+ UINT8 *node_data = node->context;
+
+ /* Set a valid output */
+ node->output = *node_data;
+ /* Reset the input to default for the next cycle */
+ /* node order is now important */
+ *node_data = DSS_INPUT__INIT;
+}
+
+
+/************************************************************************
+ *
+ * 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 (*(node->input[0]))
+#define DSS_INPUT_STREAM__GAIN (*(node->input[1]))
+#define DSS_INPUT_STREAM__OFFSET (*(node->input[2]))
+
+void dss_input_stream_step(node_description *node)
+{
+ // the context pointer is set to point to the current input stream data in discrete_stream_update
+ stream_sample_t *data = node->context;
+
+ node->output = data ? *data++ * DSS_INPUT_STREAM__GAIN + DSS_INPUT_STREAM__OFFSET : 0;
+}