summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Couriersud <couriersud@users.noreply.github.com>2009-08-25 23:29:31 +0000
committer Couriersud <couriersud@users.noreply.github.com>2009-08-25 23:29:31 +0000
commitdd836ed4d551eb354b47aa7b1539de6ca75ac342 (patch)
tree7a20255836edc815736b29f6cee95e54cbf67c2c
parent05730aa0a1211ea4a8a6c55e5f0b27a9f1d983a3 (diff)
Discrete sound parallel tasks
Introduced DISCRETE_TASK_START, DISCRETE_TASK_END DISCRETE_TASK_START - Start a new task. A task is a set of nodes which only depend on input nodes and nodes in the set DISCRETE_TASK_END(task_output_node) - Marks the end of the task. task_output_node is the node whose output over time should be preserved. This node can be accessed by nodes in the main thread. Order of execution: a) All tasks in parallel b) All nodes not part of a task. These may only refer to nodes listed in DISCRETE_TASK_END Illustrated the concept in the dkong discrete emulation. This also has been enhanced to buffer DAC output. Further changes: - DISCRETE_OUTPUT now is a stepping node. - DISCRETE_STREAM_INPUT now advances input pointer in step. - More linked_list usage. I estimate that the rework without tasks leads to a 5% performance gain. For dkong, the usage of tasks adds another 15%. There are some features missing: - Multiple nodes in DISCRETE_TASK_END - More task consistency checks - Task identifiers for tasks
-rw-r--r--src/emu/sound/disc_flt.c31
-rw-r--r--src/emu/sound/disc_inp.c16
-rw-r--r--src/emu/sound/discrete.c248
-rw-r--r--src/emu/sound/discrete.h54
-rw-r--r--src/mame/audio/dkong.c36
-rw-r--r--src/mame/audio/galaxian.c33
6 files changed, 287 insertions, 131 deletions
diff --git a/src/emu/sound/disc_flt.c b/src/emu/sound/disc_flt.c
index c284939a47c..8d40dad1b94 100644
--- a/src/emu/sound/disc_flt.c
+++ b/src/emu/sound/disc_flt.c
@@ -1070,6 +1070,8 @@ static DISCRETE_STEP(dst_rcfilter_sw)
int i,j ;
int bits = (int)DST_RCFILTER_SW__SWITCH;
double us = 0, rs = 0;
+ double vd;
+ double rt;
if (DST_RCFILTER_SW__ENABLE)
{
@@ -1086,18 +1088,43 @@ static DISCRETE_STEP(dst_rcfilter_sw)
context->vCap[1] += (DST_RCFILTER_SW__VIN - context->vCap[1]) * context->exp1;
node->output[0] = context->vCap[1] + (DST_RCFILTER_SW__VIN - context->vCap[1]) * context->factor;
break;
+ case 3:
+ rs = 2 * DST_RCFILTER_SW__R;
+ vd = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES) * DST_RCFILTER_SW__VIN;
+ rt = DST_RCFILTER_SW__R / (CD4066_ON_RES + rs);
+
+ for (j = 0; j < DST_RCFILTER_SW_ITERATIONS; j++)
+ {
+ node->output[0] = vd + rt * (context->vCap[0] + context->vCap[1]);
+ context->vCap[0] += (node->output[0] - context->vCap[0]) * context->exp[0];
+ context->vCap[1] += (node->output[0] - context->vCap[1]) * context->exp[1];
+ }
+ break;
default:
+ rs = 0;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (( bits & (1 << i)) != 0)
+ {
+ rs += DST_RCFILTER_SW__R;
+ }
+ }
+
+ vd = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES) * DST_RCFILTER_SW__VIN;
+ rt = DST_RCFILTER_SW__R / (CD4066_ON_RES + rs);
+
for (j = 0; j < DST_RCFILTER_SW_ITERATIONS; j++)
{
+ us = 0;
for (i = 0; i < 4; i++)
{
if (( bits & (1 << i)) != 0)
{
us += context->vCap[i];
- rs += DST_RCFILTER_SW__R;
}
}
- node->output[0] = RES_VOLTAGE_DIVIDER(rs, CD4066_ON_RES) * DST_RCFILTER_SW__VIN + DST_RCFILTER_SW__R / (CD4066_ON_RES + rs) * us;
+ node->output[0] = vd + rt * us;
for (i = 0; i < 4; i++)
{
if (( bits & (1 << i)) != 0)
diff --git a/src/emu/sound/disc_inp.c b/src/emu/sound/disc_inp.c
index 54d9f71116d..52882a8d8fc 100644
--- a/src/emu/sound/disc_inp.c
+++ b/src/emu/sound/disc_inp.c
@@ -15,7 +15,6 @@
*
************************************************************************/
-#define EXPERIMENTAL_STREAM_PARALLEL (0)
#define DSS_INPUT__GAIN (*(node->input[0]))
#define DSS_INPUT__OFFSET (*(node->input[1]))
@@ -67,14 +66,6 @@ READ8_DEVICE_HANDLER(discrete_sound_r)
return data;
}
-#if EXPERIMENTAL_STREAM_PARALLEL
-static STREAM_BACKGROUND_CALLBACK( disc_cb )
-{
- node_description *node = (node_description *) ptr;
-
- node->output[0] = param * DSS_INPUT__GAIN + DSS_INPUT__OFFSET;
-}
-#endif
WRITE8_DEVICE_HANDLER(discrete_sound_w)
{
@@ -104,7 +95,6 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
if (last_data != new_data)
{
-#if !EXPERIMENTAL_STREAM_PARALLEL
/* Bring the system up to now */
stream_update(info->discrete_stream);
@@ -112,12 +102,6 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
/* Update the node output here so we don't have to do it each step */
node->output[0] = *node_data * DSS_INPUT__GAIN + DSS_INPUT__OFFSET;
-#else
- *node_data = new_data;
- /* Bring the system up to now */
- stream_update_background(info->discrete_stream, disc_cb, (void *) node, *node_data);
-
-#endif
}
}
else
diff --git a/src/emu/sound/discrete.c b/src/emu/sound/discrete.c
index e1130a9c817..47b31fd4e5f 100644
--- a/src/emu/sound/discrete.c
+++ b/src/emu/sound/discrete.c
@@ -38,6 +38,7 @@
#include "inptport.h"
#include "wavwrite.h"
#include "discrete.h"
+#include "eminline.h"
/*************************************
@@ -65,11 +66,10 @@
static void init_nodes(discrete_info *info, linked_list_entry *block_list, const device_config *device);
static void find_input_nodes(discrete_info *info);
-static void setup_output_nodes(const device_config *device, discrete_info *info);
static void setup_disc_logs(discrete_info *info);
static node_description *discrete_find_node(const discrete_info *info, int node);
static DEVICE_RESET( discrete );
-
+static STREAM_UPDATE( discrete_stream_update );
/*************************************
@@ -95,7 +95,79 @@ static void CLIB_DECL ATTR_PRINTF(2,3) discrete_log(const discrete_info *disc_in
}
}
+typedef struct _task_info task_info;
+
+struct _task_info
+{
+ discrete_task_context *context;
+ int samples;
+};
+
+INLINE void step_nodes_in_list(linked_list_entry **list)
+{
+ linked_list_entry *entry;
+ for (entry = *list; entry != NULL; entry = entry->next)
+ {
+ node_description *node = (node_description *) entry->ptr;
+
+ /* Now step the node */
+ if (DISCRETE_PROFILING)
+ node->run_time -= osd_profiling_ticks();
+
+ (*node->module->step)(node);
+ //bigselect(info->device, node);
+
+ if (DISCRETE_PROFILING)
+ node->run_time += osd_profiling_ticks();
+ }
+}
+
+static void *task_callback(void *param, int threadid)
+{
+ task_info *ti = (task_info *) param;
+ int samples;
+
+ /* set up task buffer */
+ ti->context->ptr = &ti->context->node_buf[0];
+ samples = ti->samples;
+ while (samples-- > 0)
+ {
+ step_nodes_in_list(&ti->context->list);
+ }
+ /* reset ptr */
+ ti->context->ptr = &ti->context->node_buf[0];
+
+ free(param);
+ return NULL;
+}
+
+static DISCRETE_STEP( dso_task )
+{
+ discrete_task_context *ctx = (discrete_task_context *) node->context;
+ *(ctx->ptr++) = (double) *(node->input[0]);
+}
+
+static DISCRETE_RESET( dso_task )
+{
+ /* nothing to do - just avoid being stepped */
+}
+
+static DISCRETE_STEP( dso_output )
+{
+ stream_sample_t **output = (stream_sample_t **) &node->context;
+ double val;
+
+ /* Add gain to the output and put into the buffers */
+ /* Clipping will be handled by the main sound system */
+ val = (*node->input[0]) * (*node->input[1]);
+ **output = val;
+ (*output)++;
+}
+static DISCRETE_RESET( dso_output )
+{
+ /* nothing to do - just avoid being stepped */
+}
/*************************************
*
@@ -119,13 +191,18 @@ static void CLIB_DECL ATTR_PRINTF(2,3) discrete_log(const discrete_info *disc_in
static const discrete_module module_list[] =
{
- { DSO_OUTPUT ,"DSO_OUTPUT" , 0 ,0 ,NULL ,NULL },
+ { DSO_OUTPUT ,"DSO_OUTPUT" , 0 ,sizeof(0) ,dso_output_reset ,dso_output_step },
{ DSO_CSVLOG ,"DSO_CSVLOG" , 0 ,0 ,NULL ,NULL },
{ DSO_WAVELOG ,"DSO_WAVELOG" , 0 ,0 ,NULL ,NULL },
{ DSO_IMPORT ,"DSO_IMPORT" , 0 ,0 ,NULL ,NULL },
+ /* parallel modules */
+ { DSO_TASK_START ,"DSO_TASK_START" , 0 ,0 ,NULL ,NULL },
+ { DSO_TASK_END ,"DSO_TASK_END" , 0 ,0 ,dso_task_reset ,dso_task_step },
+ { DSO_TASK_SYNC ,"DSO_TASK_SYNC" , 0 ,0 ,NULL ,NULL },
+
/* nop */
- { DSS_NOP ,"DSS_NOP" , 0 ,0 ,NULL ,NULL },
+ { DSS_NOP ,"DSS_NOP" , 0 ,0 ,NULL ,NULL },
/* from disc_inp.c */
{ DSS_ADJUSTMENT ,"DSS_ADJUSTMENT" , 1 ,sizeof(struct dss_adjustment_context) ,dss_adjustment_reset ,dss_adjustment_step },
@@ -298,11 +375,8 @@ static void discrete_build_list(discrete_info *info, discrete_sound_block *intf,
}
else if (intf[node_count].type == DSO_DELETE)
{
- int p,deleted;
linked_list_entry *entry, *last;
- p = 0;
- deleted = 0;
last = NULL;
for (entry = info->block_list; entry != NULL; last = entry, entry = entry->next)
{
@@ -419,8 +493,13 @@ static DEVICE_START( discrete )
find_input_nodes(info);
/* then set up the output nodes */
- setup_output_nodes(device, info);
+ /* initialize the stream(s) */
+ info->discrete_stream = stream_create(device, info->discrete_input_streams, info->discrete_outputs, info->sample_rate, info, discrete_stream_update);
+ /* allocate a queue */
+
+ info->queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ);
+
setup_disc_logs(info);
}
@@ -437,6 +516,8 @@ static DEVICE_STOP( discrete )
discrete_info *info = get_safe_token(device);
int log_num;
+ osd_work_queue_free(info->queue);
+
if (DISCRETE_PROFILING)
{
int count = 0;
@@ -646,50 +727,39 @@ INLINE void discrete_stream_update_wave(discrete_info *info)
}
}
-INLINE void discrete_stream_update_nodes(discrete_info *info, stream_sample_t **outputs)
+INLINE void discrete_stream_update_nodes(discrete_info *info)
{
- int outputnum;
- double val;
- linked_list_entry *entry;
+ linked_list_entry *entry;
if (DISCRETE_PROFILING)
info->total_samples++;
- /* loop over all nodes */
- for (entry = info->step_list; entry != NULL; entry = entry->next)
+ /* update task nodes */
+ for (entry = info->task_list; entry != 0; entry = entry->next)
{
- node_description *node = (node_description *) entry->ptr;
-
- /* Now step the node */
- if (DISCRETE_PROFILING)
- node->run_time -= osd_profiling_ticks();
-
- (*node->module->step)(node);
- //bigselect(info->device, node);
-
- if (DISCRETE_PROFILING)
- node->run_time += osd_profiling_ticks();
-
+ discrete_task_context *task = (discrete_task_context *) entry->ptr;
+ **task->dest = *task->ptr++;
}
- /* Add gain to the output and put into the buffers */
- /* Clipping will be handled by the main sound system */
- for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++)
- {
- val = (*info->output_node[outputnum]->input[0]) * (*info->output_node[outputnum]->input[1]);
- *(outputs[outputnum]++) = val;
- }
+ /* loop over all nodes */
+ step_nodes_in_list(&info->step_list);
}
static STREAM_UPDATE( discrete_stream_update )
{
discrete_info *info = (discrete_info *)param;
- stream_sample_t *outptr[DISCRETE_MAX_OUTPUTS];
+ linked_list_entry *entry;
int samplenum, nodenum, outputnum;
+ //int j; int left; int run;
+ if (samples == 0)
+ return;
+
/* Setup any output streams */
for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++)
- outptr[outputnum] = outputs[outputnum];
+ {
+ info->output_node[outputnum]->context = (void *) outputs[outputnum];
+ }
/* Setup any input streams */
for (nodenum = 0; nodenum < info->discrete_input_streams; nodenum++)
@@ -697,20 +767,32 @@ static STREAM_UPDATE( discrete_stream_update )
info->input_stream_data[nodenum] = inputs[nodenum];
}
- if ((info->num_csvlogs > 0) || (info->num_wavelogs > 0))
+ for (entry = info->task_list; entry != 0; entry = entry->next)
+ {
+ task_info *ti = malloc(sizeof(task_info));
+ discrete_task_context *task = (discrete_task_context *) entry->ptr;
+
+ /* Fire task */
+ ti->context = task;
+ ti->samples = samples;
+ osd_work_item_queue(info->queue, task_callback, (void *) ti, WORK_ITEM_FLAG_AUTO_RELEASE);
+ }
+
+ /* and wait for them */
+ osd_work_queue_wait(info->queue, osd_ticks_per_second()*10);
+
+ if ((info->num_csvlogs == 0) && (info->num_wavelogs == 0))
{
/* Now we must do samples iterations of the node list, one output for each step */
for (samplenum = 0; samplenum < samples; samplenum++)
- {
- discrete_stream_update_nodes(info, outptr);
- }
+ discrete_stream_update_nodes(info);
}
else
{
/* Now we must do samples iterations of the node list, one output for each step */
for (samplenum = 0; samplenum < samples; samplenum++)
{
- discrete_stream_update_nodes(info, outptr);
+ discrete_stream_update_nodes(info);
discrete_stream_update_csv(info);
discrete_stream_update_wave(info);
@@ -732,12 +814,16 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
{
linked_list_entry **step_list = &info->step_list;
linked_list_entry **node_list = &info->node_list;
+ linked_list_entry **task_list = &info->task_list;
+ linked_list_entry **cur_task_node = NULL;
linked_list_entry *entry;
-
+ discrete_task_context *task;
+
/* start with no outputs or input streams */
+
info->discrete_outputs = 0;
info->discrete_input_streams = 0;
-
+
/* loop over all nodes */
for (entry = block_list; entry != NULL; entry = entry->next)
{
@@ -745,6 +831,22 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
node_description *node = auto_alloc_clear(info->device->machine, node_description);
int inputnum, modulenum;
+ /* find the requested module */
+ for (modulenum = 0; module_list[modulenum].type != DSS_NULL; modulenum++)
+ if (module_list[modulenum].type == block->type)
+ break;
+ if (module_list[modulenum].type != block->type)
+ fatalerror("init_nodes() - Unable to find discrete module type %d for NODE_%02d", block->type, NODE_INDEX(block->node));
+
+ /* static inits */
+ node->context = NULL;
+ node->info = info;
+ node->node = block->node;
+ node->module = &module_list[modulenum];
+ node->output[0] = 0.0;
+ node->block = block;
+ node->custom = block->custom;
+
/* keep track of special nodes */
if (block->node == NODE_SPECIAL)
{
@@ -771,6 +873,23 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
info->wavelog_node[info->num_wavelogs++] = node;
break;
+ /* Task processing */
+ case DSO_TASK_START:
+ if (cur_task_node != NULL)
+ fatalerror("init_nodes() - Nested DISCRETE_START_TASK.");
+ task = auto_alloc_clear(info->device->machine, discrete_task_context);
+ add_list(info, &task_list, task);
+ cur_task_node = &task->list;
+ break;
+
+ case DSO_TASK_END:
+ if (cur_task_node == NULL)
+ fatalerror("init_nodes() - NO DISCRETE_START_TASK.");
+ node->context = task;
+ task->dest = (double **) &node->input[0];
+ task = NULL;
+ break;
+
default:
fatalerror("init_nodes() - Failed, trying to create unknown special discrete node.");
}
@@ -784,29 +903,12 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
info->indexed_node[NODE_INDEX(block->node)] = node;
}
- /* find the requested module */
- for (modulenum = 0; module_list[modulenum].type != DSS_NULL; modulenum++)
- if (module_list[modulenum].type == block->type)
- break;
- if (module_list[modulenum].type != block->type)
- fatalerror("init_nodes() - Unable to find discrete module type %d for NODE_%02d", block->type, NODE_INDEX(block->node));
-
- /* static inits */
- node->info = info;
- node->node = block->node;
- node->module = &module_list[modulenum];
- node->output[0] = 0.0;
- node->block = block;
-
node->active_inputs = block->active_inputs;
for (inputnum = 0; inputnum < DISCRETE_MAX_INPUTS; inputnum++)
{
node->input[inputnum] = &(block->initial[inputnum]);
}
- node->context = NULL;
- node->custom = block->custom;
-
/* setup module if custom */
if (block->type == DST_CUSTOM)
{
@@ -835,7 +937,18 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
/* our running order just follows the order specified */
/* does the node step ? */
if (node->module->step != NULL)
- add_list(info, &step_list, node);
+ {
+ /* do we belong to a task? */
+ if (cur_task_node == NULL)
+ add_list(info, &step_list, node);
+ else
+ add_list(info, &cur_task_node, node);
+ }
+
+ if (block->type == DSO_TASK_END)
+ {
+ cur_task_node = NULL;
+ }
/* and register save state */
if (node->node != NODE_SPECIAL)
@@ -899,21 +1012,6 @@ static void find_input_nodes(discrete_info *info)
}
-
-/*************************************
- *
- * Set up the output nodes
- *
- *************************************/
-
-static void setup_output_nodes(const device_config *device, discrete_info *info)
-{
- /* initialize the stream(s) */
- info->discrete_stream = stream_create(device, info->discrete_input_streams, info->discrete_outputs, info->sample_rate, info, discrete_stream_update);
-}
-
-
-
/*************************************
*
* Set up the logs
diff --git a/src/emu/sound/discrete.h b/src/emu/sound/discrete.h
index c4dbad7c179..4f629ee5dff 100644
--- a/src/emu/sound/discrete.h
+++ b/src/emu/sound/discrete.h
@@ -3659,6 +3659,17 @@ struct _linked_list_entry
linked_list_entry *next;
};
+typedef struct _discrete_task_context discrete_task_context;
+struct _discrete_task_context
+{
+ linked_list_entry *list;
+
+ double *ptr;
+ double node_buf[2048];
+ double **dest;
+ volatile INT32 active;
+};
+
struct _discrete_info
{
const device_config *device;
@@ -3679,6 +3690,9 @@ struct _discrete_info
/* list of discrete blocks after prescan (IMPORT, DELETE, REPLACE) */
linked_list_entry *block_list; /* discrete_sound_block * */
+
+ /* tasks */
+ linked_list_entry *task_list; /* discrete_task_context * */
/* the input streams */
int discrete_input_streams;
@@ -3705,6 +3719,10 @@ struct _discrete_info
wav_file *disc_wav_file[DISCRETE_MAX_WAVELOGS];
node_description *wavelog_node[DISCRETE_MAX_WAVELOGS];
+ /* parallel tasks */
+
+ osd_work_queue *queue;
+
/* profiling */
int total_samples;
};
@@ -4190,6 +4208,11 @@ enum
DSO_CSVLOG, /* Dump nodes as csv file */
DSO_WAVELOG, /* Dump nodes as wav file */
+ /* Parallel execution */
+ DSO_TASK_START, /* start of parallel task */
+ DSO_TASK_END, /* end of parallel task */
+ DSO_TASK_SYNC, /* wait for all parallel tasks to finish */
+
/* Output Node -- this must be the last entry in this enum! */
DSO_OUTPUT, /* The final output node */
@@ -4198,12 +4221,6 @@ enum
DSO_REPLACE, /* replace next node */
DSO_DELETE, /* delete nodes */
- /* Parallel execution */
-
- DSO_TASK_START, /* start of parallel task */
- DSO_TASK_END, /* end of parallel task */
- DSO_TASK_SYNC, /* wait for all parallel tasks to finish */
-
/* Marks end of this enum -- must be last entry ! */
DSO_LAST
};
@@ -4375,19 +4392,24 @@ enum
#define DISCRETE_NOP(NODE) { NODE, DSS_NOP , 0, { 0 }, { 0 }, NULL, "DISCRETE_NOP" },
/* logging */
-#define DISCRETE_CSVLOG1(NODE1) { NODE_SPECIAL, DSO_CSVLOG , 1, { NODE1 }, { NODE1 }, NULL, "DISCRETE_CSVLOG1" },
-#define DISCRETE_CSVLOG2(NODE1,NODE2) { NODE_SPECIAL, DSO_CSVLOG , 2, { NODE1,NODE2 }, { NODE1,NODE2 }, NULL, "DISCRETE_CSVLOG2" },
-#define DISCRETE_CSVLOG3(NODE1,NODE2,NODE3) { NODE_SPECIAL, DSO_CSVLOG , 3, { NODE1,NODE2,NODE3 }, { NODE1,NODE2,NODE3 }, NULL, "DISCRETE_CSVLOG3" },
-#define DISCRETE_CSVLOG4(NODE1,NODE2,NODE3,NODE4) { NODE_SPECIAL, DSO_CSVLOG , 4, { NODE1,NODE2,NODE3,NODE4 }, { NODE1,NODE2,NODE3,NODE4 }, NULL, "DISCRETE_CSVLOG4" },
-#define DISCRETE_CSVLOG5(NODE1,NODE2,NODE3,NODE4,NODE5) { NODE_SPECIAL, DSO_CSVLOG , 5, { NODE1,NODE2,NODE3,NODE4,NODE5 }, { NODE1,NODE2,NODE3,NODE4,NODE5 }, NULL, "DISCRETE_CSVLOG5" },
-#define DISCRETE_WAVELOG1(NODE1,GAIN1) { NODE_SPECIAL, DSO_WAVELOG , 2, { NODE1,NODE_NC }, { NODE1,GAIN1 }, NULL, "DISCRETE_WAVELOG1" },
-#define DISCRETE_WAVELOG2(NODE1,GAIN1,NODE2,GAIN2) { NODE_SPECIAL, DSO_WAVELOG , 4, { NODE1,NODE_NC,NODE2,NODE_NC }, { NODE1,GAIN1,NODE2,GAIN2 }, NULL, "DISCRETE_WAVELOG2" },
+#define DISCRETE_CSVLOG1(NODE1) { NODE_SPECIAL, DSO_CSVLOG , 1, { NODE1 }, { NODE1 }, NULL, "DISCRETE_CSVLOG1" },
+#define DISCRETE_CSVLOG2(NODE1,NODE2) { NODE_SPECIAL, DSO_CSVLOG , 2, { NODE1,NODE2 }, { NODE1,NODE2 }, NULL, "DISCRETE_CSVLOG2" },
+#define DISCRETE_CSVLOG3(NODE1,NODE2,NODE3) { NODE_SPECIAL, DSO_CSVLOG , 3, { NODE1,NODE2,NODE3 }, { NODE1,NODE2,NODE3 }, NULL, "DISCRETE_CSVLOG3" },
+#define DISCRETE_CSVLOG4(NODE1,NODE2,NODE3,NODE4) { NODE_SPECIAL, DSO_CSVLOG , 4, { NODE1,NODE2,NODE3,NODE4 }, { NODE1,NODE2,NODE3,NODE4 }, NULL, "DISCRETE_CSVLOG4" },
+#define DISCRETE_CSVLOG5(NODE1,NODE2,NODE3,NODE4,NODE5) { NODE_SPECIAL, DSO_CSVLOG , 5, { NODE1,NODE2,NODE3,NODE4,NODE5 }, { NODE1,NODE2,NODE3,NODE4,NODE5 }, NULL, "DISCRETE_CSVLOG5" },
+#define DISCRETE_WAVELOG1(NODE1,GAIN1) { NODE_SPECIAL, DSO_WAVELOG , 2, { NODE1,NODE_NC }, { NODE1,GAIN1 }, NULL, "DISCRETE_WAVELOG1" },
+#define DISCRETE_WAVELOG2(NODE1,GAIN1,NODE2,GAIN2) { NODE_SPECIAL, DSO_WAVELOG , 4, { NODE1,NODE_NC,NODE2,NODE_NC }, { NODE1,GAIN1,NODE2,GAIN2 }, NULL, "DISCRETE_WAVELOG2" },
/* import */
-#define DISCRETE_IMPORT(INFO) { NODE_SPECIAL, DSO_IMPORT , 0, { 0 }, { 0 }, &(INFO##_discrete_interface), "DISCRETE_IMPORT" },
-#define DISCRETE_DELETE(NODE_FROM, NODE_TO) { NODE_SPECIAL, DSO_DELETE , 2, { NODE_FROM, NODE_TO }, { NODE_FROM, NODE_TO }, NULL, "DISCRETE_DELETE" },
-#define DISCRETE_REPLACE { NODE_SPECIAL, DSO_REPLACE , 0, { 0 }, { 0 }, NULL, "DISCRETE_REPLACE" },
+#define DISCRETE_IMPORT(INFO) { NODE_SPECIAL, DSO_IMPORT , 0, { 0 }, { 0 }, &(INFO##_discrete_interface), "DISCRETE_IMPORT" },
+#define DISCRETE_DELETE(NODE_FROM, NODE_TO) { NODE_SPECIAL, DSO_DELETE , 2, { NODE_FROM, NODE_TO }, { NODE_FROM, NODE_TO }, NULL, "DISCRETE_DELETE" },
+#define DISCRETE_REPLACE { NODE_SPECIAL, DSO_REPLACE , 0, { 0 }, { 0 }, NULL, "DISCRETE_REPLACE" },
+
+/* parallel tasks */
+#define DISCRETE_TASK_START() { NODE_SPECIAL, DSO_TASK_START, 0, { 0 }, { 0 }, NULL, "DISCRETE_TASK_START" },
+#define DISCRETE_TASK_END(BUF_NODE) { NODE_SPECIAL, DSO_TASK_END , 1, { BUF_NODE }, { BUF_NODE }, NULL, "DISCRETE_TASK_END" },
+//#define DISCRETE_TASK_SYNC() { NODE_SPECIAL, DSO_TASK_SYNC, 0, { 0 }, { 0 }, NULL, "DISCRETE_TASK_SYNC" },
/* output */
#define DISCRETE_OUTPUT(OPNODE,GAIN) { NODE_SPECIAL, DSO_OUTPUT , 2, { OPNODE,NODE_NC }, { 0,GAIN }, NULL, "DISCRETE_OUTPUT" },
diff --git a/src/mame/audio/dkong.c b/src/mame/audio/dkong.c
index 8fa045269d0..576e6e6325a 100644
--- a/src/mame/audio/dkong.c
+++ b/src/mame/audio/dkong.c
@@ -348,6 +348,12 @@ static const discrete_custom_info dkong_custom_mixer_info =
};
#endif
+
+static DISCRETE_SOUND_START(dkong2b_dac)
+ DISCRETE_INPUT_DATA(DS_DAC)
+ DISCRETE_OUTPUT(DS_DAC, 1)
+DISCRETE_SOUND_END
+
static DISCRETE_SOUND_START(dkong2b)
/************************************************/
@@ -359,7 +365,8 @@ static DISCRETE_SOUND_START(dkong2b)
DISCRETE_INPUT_NOT(DS_SOUND1_INV) /* IC 6J, pin 12 */
DISCRETE_INPUT_NOT(DS_SOUND0_INV) /* IC 6J, pin 2 */
DISCRETE_INPUT_NOT(DS_DISCHARGE_INV)
- DISCRETE_INPUT_DATA(DS_DAC)
+ //DISCRETE_INPUT_DATA(DS_DAC)
+
/* Mixing - DAC */
DISCRETE_ADJUSTMENT_TAG(DS_ADJ_DAC, 0, 1, DISC_LINADJ, "VR2")
@@ -367,6 +374,7 @@ static DISCRETE_SOUND_START(dkong2b)
/* Stomp */
/************************************************/
/* Noise */
+ DISCRETE_TASK_START()
DISCRETE_LFSR_NOISE(NODE_11, 1, 1, CLOCK_2VF, 1.0, 0, 0.5, &dkong_lfsr)
DISCRETE_COUNTER(NODE_12, 1, 0, NODE_11, 7, DISC_COUNT_UP, 0, DISC_CLK_ON_R_EDGE) /* LS161, IC 3J */
DISCRETE_TRANSFORM3(NODE_13,NODE_12,3,DK_SUP_V,"01>2*")
@@ -382,12 +390,14 @@ static DISCRETE_SOUND_START(dkong2b)
DISCRETE_RCINTEGRATE(NODE_22,NODE_20,DK_R5, RES_2_PARALLEL(DK_R4+DK_R3,DK_R6),0,DK_C19,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1)
DISCRETE_MULTIPLY(DS_OUT_SOUND0,1,NODE_22,DK_R3/R_SERIES(DK_R3,DK_R4))
-
+ DISCRETE_TASK_END(DS_OUT_SOUND0)
+
/************************************************/
/* Jump */
/************************************************/
-/* tt */
+ /* tt */
/* 4049B Inverter Oscillator build from 3 inverters */
+ DISCRETE_TASK_START()
DISCRETE_INVERTER_OSC(NODE_25,1,0,DK_R38,DK_R39,DK_C26,0,&dkong_inverter_osc_desc_jump)
#if DK_USE_CUSTOM
@@ -414,10 +424,12 @@ static DISCRETE_SOUND_START(dkong2b)
DISCRETE_RCINTEGRATE(NODE_39,NODE_38,DK_R27, RES_2_PARALLEL(DK_R28,DK_R26+DK_R25),0,DK_C16,DK_SUP_V,DISC_RC_INTEGRATE_TYPE1)
DISCRETE_MULTIPLY(DS_OUT_SOUND1,1,NODE_39,DK_R25/(DK_R26+DK_R25))
+ DISCRETE_TASK_END(DS_OUT_SOUND1)
/************************************************/
/* Walk */
/************************************************/
+ DISCRETE_TASK_START()
DISCRETE_INVERTER_OSC(NODE_51,1,0,DK_R47,DK_R48,DK_C30,0,&dkong_inverter_osc_desc_walk)
#if DK_USE_CUSTOM
@@ -438,11 +450,14 @@ static DISCRETE_SOUND_START(dkong2b)
/* Filter and divide - omitted C22 */
DISCRETE_CRFILTER(NODE_61, 1, NODE_60, DK_R15+DK_R16, DK_C23)
DISCRETE_MULTIPLY(DS_OUT_SOUND2, 1, NODE_61, DK_R15/(DK_R15+DK_R16))
+ DISCRETE_TASK_END(DS_OUT_SOUND2)
/************************************************/
/* DAC */
/************************************************/
+ DISCRETE_TASK_START()
+ DISCRETE_INPUTX_STREAM(DS_DAC, 0, 1.0, 0)
/* Signal decay circuit Q7, R20, C32 */
DISCRETE_RCDISC(NODE_70, DS_DISCHARGE_INV, 1, DK_R20, DK_C32)
DISCRETE_TRANSFORM4(NODE_71, DS_DAC, DK_SUP_V/256.0, NODE_70, DS_DISCHARGE_INV, "01*3!2+*")
@@ -463,6 +478,7 @@ static DISCRETE_SOUND_START(dkong2b)
#else
DISCRETE_MULTIPLY(DS_OUT_DAC, 1, NODE_73, DS_ADJ_DAC)
#endif
+ DISCRETE_TASK_END(DS_OUT_DAC)
/************************************************/
/* Amplifier */
@@ -621,7 +637,10 @@ static DISCRETE_SOUND_START(radarscp)
DISCRETE_INPUT_NOT(DS_SOUND6_INV)
DISCRETE_INPUT_NOT(DS_SOUND7_INV)
DISCRETE_INPUT_NOT(DS_DISCHARGE_INV)
- DISCRETE_INPUT_DATA(DS_DAC)
+
+ /* Must be in task if tasks added */
+ DISCRETE_INPUTX_STREAM(DS_DAC, 0, 1.0, 0)
+ //DISCRETE_INPUT_DATA(DS_DAC)
/* Mixing - DAC */
DISCRETE_ADJUSTMENT_TAG(DS_ADJ_DAC, 0, 1, DISC_LINADJ, "VR2")
@@ -1152,7 +1171,7 @@ static ADDRESS_MAP_START( dkong_sound_io_map, ADDRESS_SPACE_IO, 8 )
AM_WRITE(dkong_voice_w)
AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_DEVREAD("ls175.3d", dkong_tune_r)
AM_WRITE(dkong_voice_w)
- AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_DEVWRITE("discrete", dkong_p1_w) /* only write to dac */
+ AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_DEVWRITE("discdac", dkong_p1_w) /* only write to dac */
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_LATCH8_READWRITE("virtual_p2")
AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_LATCH8_READBIT("ls259.6h", 5)
AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_LATCH8_READBIT("ls259.6h", 4)
@@ -1168,7 +1187,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( radarsc1_sound_io_map, ADDRESS_SPACE_IO, 8 )
AM_RANGE(0x00, 0x00) AM_MIRROR(0xff) AM_DEVREAD("ls175.3d", latch8_r)
- AM_RANGE(0x00, 0xff) AM_DEVWRITE("discrete", dkong_p1_w) /* DAC here */
+ AM_RANGE(0x00, 0xff) AM_DEVWRITE("discdac", dkong_p1_w) /* DAC here */
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_LATCH8_READ("virtual_p1")
AM_DEVWRITE("tms", M58817_command_w)
AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_LATCH8_WRITE("virtual_p2")
@@ -1243,6 +1262,11 @@ MACHINE_DRIVER_START( dkong2b_audio )
MDRV_CPU_IO_MAP(dkong_sound_io_map)
MDRV_SPEAKER_STANDARD_MONO("mono")
+
+ MDRV_SOUND_ADD("discdac", DISCRETE, 0)
+ MDRV_SOUND_CONFIG_DISCRETE(dkong2b_dac)
+ MDRV_SOUND_ROUTE_EX(0, "discrete", 1.0, 0)
+
MDRV_SOUND_ADD("discrete", DISCRETE, 0)
MDRV_SOUND_CONFIG_DISCRETE(dkong2b)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
diff --git a/src/mame/audio/galaxian.c b/src/mame/audio/galaxian.c
index 0bb8a45d4ae..e5bbbfb0d2c 100644
--- a/src/mame/audio/galaxian.c
+++ b/src/mame/audio/galaxian.c
@@ -314,7 +314,7 @@ static DISCRETE_SOUND_START(galaxian)
/* since only a sample of the LFSR is latched @V2 we let the lfsr
* run at a lower speed
*/
- DISCRETE_LFSR_NOISE(NODE_150, 1, 1, RNG_RATE/100, 1.0, 0, 0.5, &galaxian_lfsr)
+ DISCRETE_LFSR_NOISE(NODE_150, 1, 1, RNG_RATE/100, 1.0, 0, 0.5, &galaxian_lfsr)
DISCRETE_SQUAREWFIX(NODE_151,1,60*264/2,1.0,50,0.5,0) /* 2V signal */
DISCRETE_LOGIC_DFLIPFLOP(NODE_152,1,1,1,NODE_151,NODE_150)
@@ -323,34 +323,35 @@ static DISCRETE_SOUND_START(galaxian)
* this is not emulated */
DISCRETE_RCDISC5(NODE_155, NODE_152, GAL_INP_HIT, (GAL_R35 + GAL_R36), GAL_C21)
DISCRETE_OP_AMP_FILTER(NODE_157, 1, NODE_155, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &galaxian_bandpass_desc)
-
+
/************************************************/
/* FIRE */
/************************************************/
- DISCRETE_LOGIC_INVERT(NODE_160, 1, GAL_INP_FIRE)
- DISCRETE_MULTIPLY(NODE_161, 1, TTL_OUT, GAL_INP_FIRE)
- DISCRETE_MULTIPLY(NODE_162, 1, TTL_OUT, NODE_160) // inverted
- DISCRETE_RCFILTER(NODE_163, 1, NODE_162, GAL_R47, GAL_C28)
+
+ DISCRETE_LOGIC_INVERT(NODE_170, 1, GAL_INP_FIRE)
+ DISCRETE_MULTIPLY(NODE_171, 1, TTL_OUT, GAL_INP_FIRE)
+ DISCRETE_MULTIPLY(NODE_172, 1, TTL_OUT, NODE_170) // inverted
+ DISCRETE_RCFILTER(NODE_173, 1, NODE_172, GAL_R47, GAL_C28)
/* Mix noise and 163 */
- DISCRETE_TRANSFORM5(NODE_167, NODE_152, TTL_OUT, 1.0/GAL_R46, NODE_163, 1.0/GAL_R48,
+ DISCRETE_TRANSFORM5(NODE_177, NODE_152, TTL_OUT, 1.0/GAL_R46, NODE_173, 1.0/GAL_R48,
"01*2*34*+" )
- //DISCRETE_MULTIPLY(NODE_164, 1, TTL_OUT, NODE_152)
- //DISCRETE_MULTIPLY(NODE_165, 1, 1.0/GAL_R46, NODE_164)
- //DISCRETE_MULTIPLY(NODE_166, 1, 1.0/GAL_R48, NODE_163)
- //DISCRETE_ADDER2(NODE_167, 1, NODE_165, NODE_166)
- DISCRETE_MULTIPLY(NODE_168, 1, RES_2_PARALLEL(GAL_R46, GAL_R48), NODE_167)
+ //DISCRETE_MULTIPLY(NODE_174, 1, TTL_OUT, NODE_152)
+ //DISCRETE_MULTIPLY(NODE_175, 1, 1.0/GAL_R46, NODE_174)
+ //DISCRETE_MULTIPLY(NODE_176, 1, 1.0/GAL_R48, NODE_173)
+ //DISCRETE_ADDER2(NODE_177, 1, NODE_175, NODE_176)
+ DISCRETE_MULTIPLY(NODE_178, 1, RES_2_PARALLEL(GAL_R46, GAL_R48), NODE_177)
- DISCRETE_555_ASTABLE_CV(NODE_171, 1, GAL_R44, GAL_R45, GAL_C27, NODE_168, &galaxian_555_fire_vco_desc)
+ DISCRETE_555_ASTABLE_CV(NODE_181, 1, GAL_R44, GAL_R45, GAL_C27, NODE_178, &galaxian_555_fire_vco_desc)
/* 555 toggles discharge on rc discharge module */
- DISCRETE_RCDISC5(NODE_172, NODE_171, NODE_161, (GAL_R41), GAL_C25)
+ DISCRETE_RCDISC5(NODE_182, NODE_181, NODE_171, (GAL_R41), GAL_C25)
/************************************************/
/* FINAL MIX */
/************************************************/
DISCRETE_MIXER5(NODE_279, 1, NODE_SUB(133,0), NODE_SUB(133,2), NODE_SUB(133,2), NODE_SUB(133,3), NODE_120, &galaxian_mixerpre_desc)
- DISCRETE_MIXER3(NODE_280, 1, NODE_279, NODE_157, NODE_172, &galaxian_mixer_desc)
+ DISCRETE_MIXER3(NODE_280, 1, NODE_279, NODE_157, NODE_182, &galaxian_mixer_desc)
DISCRETE_OUTPUT(NODE_280, 32767.0/5.0*5)
DISCRETE_SOUND_END
@@ -364,7 +365,7 @@ static DISCRETE_SOUND_START(mooncrst)
/************************************************/
DISCRETE_DELETE(NODE_279, NODE_279)
DISCRETE_REPLACE
- DISCRETE_MIXER7(NODE_280, 1, NODE_SUB(133,0), NODE_SUB(133,2), NODE_SUB(133,2), NODE_SUB(133,3), NODE_120, NODE_157, NODE_172, &mooncrst_mixer_desc)
+ DISCRETE_MIXER7(NODE_280, 1, NODE_SUB(133,0), NODE_SUB(133,2), NODE_SUB(133,2), NODE_SUB(133,3), NODE_120, NODE_157, NODE_182, &mooncrst_mixer_desc)
DISCRETE_SOUND_END
/*************************************