Discrete: Added DISCRETE_INPUT_BUFFER

Added DISCRETE_INPUT_BUFFER to use a stream to buffer an input node.
For input nodes with a lot of writes this prevents a stream_update 
on the whole discrete module which is very ineffective. Instead,
the data is buffered and the discrete emulation can process a lot 
of samples in one go later.
Updated dkong.c to use this instead of using the DAC device.
This change requires a recompile of all files referencing the discrete 
system. A "rm `grep -rl discrete obj/`" should do the trick (at least
on .+nix)
This commit is contained in:
Couriersud 2009-09-04 20:15:48 +00:00
parent 810c3a67ef
commit 698949fe6a
4 changed files with 88 additions and 23 deletions

View File

@ -93,6 +93,7 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
switch (node->module->type)
{
case DSS_INPUT_DATA:
case DSS_INPUT_BUFFER:
new_data = data;
break;
case DSS_INPUT_LOGIC:
@ -106,13 +107,23 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w)
if (context->data != new_data)
{
/* Bring the system up to now */
stream_update(info->discrete_stream);
if (context->is_buffered)
{
/* Bring the system up to now */
stream_update(info->buffer_stream);
context->data = new_data;
context->data = new_data;
}
else
{
/* Bring the system up to now */
stream_update(info->discrete_stream);
/* Update the node output here so we don't have to do it each step */
node->output[0] = new_data * context->gain + context->offset;
context->data = new_data;
/* Update the node output here so we don't have to do it each step */
node->output[0] = new_data * context->gain + context->offset;
}
}
}
else
@ -295,10 +306,23 @@ static DISCRETE_RESET(dss_input_stream)
struct dss_input_context *context = (struct dss_input_context *)node->context;
assert(DSS_INPUT_STREAM__STREAM < linked_list_count(node->info->input_list));
context->is_buffered = FALSE;
context->is_stream = TRUE;
/* Stream out number is set during start */
context->stream_in_number = DSS_INPUT_STREAM__STREAM;
context->gain = DSS_INPUT_STREAM__GAIN;
context->offset = DSS_INPUT_STREAM__OFFSET;
context->ptr = NULL;
//context->data = 0;
if (node->block->type == DSS_INPUT_BUFFER)
{
context->is_buffered = TRUE;
stream_set_input(node->info->discrete_stream, context->stream_in_number,
node->info->buffer_stream, context->stream_out_number, 1.0);
}
else
{
context->is_buffered = FALSE;
}
}

View File

@ -70,6 +70,7 @@ 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 );
static STREAM_UPDATE( buffer_stream_update );
/*************************************
@ -263,6 +264,7 @@ static const discrete_module module_list[] =
{ DSS_INPUT_NOT ,"DSS_INPUT_NOT" , 1 ,sizeof(struct dss_input_context) ,dss_input_reset ,NULL },
{ DSS_INPUT_PULSE ,"DSS_INPUT_PULSE" , 1 ,sizeof(struct dss_input_context) ,dss_input_reset ,dss_input_pulse_step },
{ DSS_INPUT_STREAM,"DSS_INPUT_STREAM", 1 ,sizeof(struct dss_input_context) ,dss_input_stream_reset,dss_input_stream_step},
{ DSS_INPUT_BUFFER,"DSS_INPUT_BUFFER", 1 ,sizeof(struct dss_input_context) ,dss_input_stream_reset,dss_input_stream_step},
/* from disc_wav.c */
/* Generic modules */
@ -531,10 +533,11 @@ static DEVICE_START( discrete )
/* now go back and find pointers to all input nodes */
find_input_nodes(info);
/* then set up the output nodes */
/* initialize the stream(s) */
info->discrete_stream = stream_create(device,linked_list_count(info->input_list), linked_list_count(info->output_list), info->sample_rate, info, discrete_stream_update);
if (info->buffer_count > 0)
info->buffer_stream = stream_create(device, 0, info->buffer_count, info->sample_rate, info, buffer_stream_update);
/* allocate a queue */
info->queue = osd_work_queue_alloc(WORK_QUEUE_FLAG_MULTI | WORK_QUEUE_FLAG_HIGH_FREQ);
@ -815,6 +818,35 @@ INLINE void discrete_stream_update_nodes(discrete_info *info)
step_nodes_in_list(&info->step_list);
}
static STREAM_UPDATE( buffer_stream_update )
{
discrete_info *info = (discrete_info *)param;
linked_list_entry *entry;
if (samples == 0)
return;
/* process buffered inputs */
for (entry = info->input_list; entry != NULL; entry = entry->next)
{
node_description *node = (node_description *) entry->ptr;
if (node->block->type == DSS_INPUT_BUFFER)
{
struct dss_input_context *context = (struct dss_input_context *)node->context;
stream_sample_t *ptr = outputs[context->stream_out_number];
int data = context->data;
int samplenum = samples;
while (samplenum--)
*(ptr++) = data;
//for (samplenum = 0; samplenum < samples; samplenum++)
// outputs[context->stream_out_number][samplenum] = data;
}
}
}
static STREAM_UPDATE( discrete_stream_update )
{
discrete_info *info = (discrete_info *)param;
@ -891,6 +923,9 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
linked_list_entry **task_list = &info->task_list;
linked_list_entry **output_list = &info->output_list;
linked_list_entry **input_list = &info->input_list;
/* stream buffered node counter */
info->buffer_count = 0;
/* loop over all nodes */
for (entry = block_list; entry != NULL; entry = entry->next)
@ -1000,6 +1035,12 @@ static void init_nodes(discrete_info *info, linked_list_entry *block_list, const
{
linked_list_add(info, &input_list, node);
}
else if (block->type == DSS_INPUT_BUFFER)
{
struct dss_input_context *context = (struct dss_input_context *)node->context;
context->stream_out_number = info->buffer_count++;
linked_list_add(info, &input_list, node);
}
/* add to node list */
linked_list_add(info, &node_list, node);

View File

@ -3703,6 +3703,7 @@ struct _discrete_info
/* the input streams */
linked_list_entry *input_list;
int buffer_count; /* number of stream buffered nodes */
/* output node tracking */
linked_list_entry *output_list;
@ -3710,6 +3711,10 @@ struct _discrete_info
/* the output stream */
sound_stream *discrete_stream;
/* the buffer stream */
sound_stream *buffer_stream;
/* debugging statics */
FILE *disclogfile;
@ -4119,6 +4124,7 @@ enum
DSS_INPUT_NOT, /* Input node */
DSS_INPUT_PULSE, /* Input node, single pulsed version */
DSS_INPUT_STREAM, /* Stream Input */
DSS_INPUT_BUFFER, /* Buffer Input node, for high freq inputs like DAC */
/* from disc_wav.c */
/* generic modules */
@ -4258,9 +4264,12 @@ enum
#define DISCRETE_INPUT_NOT(NODE) { NODE, DSS_INPUT_NOT , 3, { NODE_NC,NODE_NC,NODE_NC }, { 1,0,0 }, NULL, "DISCRETE_INPUT_NOT" },
#define DISCRETE_INPUTX_NOT(NODE,GAIN,OFFSET,INIT) { NODE, DSS_INPUT_NOT , 3, { NODE_NC,NODE_NC,NODE_NC }, { GAIN,OFFSET,INIT }, NULL, "DISCRETE_INPUTX_NOT" },
#define DISCRETE_INPUT_PULSE(NODE,INIT) { NODE, DSS_INPUT_PULSE , 3, { NODE_NC,NODE_NC,NODE_NC }, { 1,0,INIT }, NULL, "DISCRETE_INPUT_PULSE" },
#define DISCRETE_INPUT_STREAM(NODE, NUM) { NODE, DSS_INPUT_STREAM, 3, { NUM,NODE_NC,NODE_NC }, { NUM,1,0 }, NULL, "DISCRETE_INPUT_STREAM" },
#define DISCRETE_INPUTX_STREAM(NODE, NUM, GAIN,OFFSET) { NODE, DSS_INPUT_STREAM, 3, { NUM,NODE_NC,NODE_NC }, { NUM,GAIN,OFFSET }, NULL, "DISCRETE_INPUTX_STREAM" },
#define DISCRETE_INPUT_BUFFER(NODE, NUM) { NODE, DSS_INPUT_BUFFER, 3, { NUM,NODE_NC,NODE_NC }, { NUM,1,0 }, NULL, "DISCRETE_INPUT_BUFFER" },
/* from disc_wav.c */
/* generic modules */
#define DISCRETE_COUNTER(NODE,ENAB,RESET,CLK,MAX,DIR,INIT0,CLKTYPE) { NODE, DSS_COUNTER , 7, { ENAB,RESET,CLK,NODE_NC,DIR,INIT0,NODE_NC }, { ENAB,RESET,CLK,MAX,DIR,INIT0,CLKTYPE }, NULL, "DISCRETE_COUNTER" },

View File

@ -348,12 +348,6 @@ 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)
/************************************************/
@ -457,7 +451,9 @@ static DISCRETE_SOUND_START(dkong2b)
/************************************************/
DISCRETE_TASK_START()
DISCRETE_INPUTX_STREAM(DS_DAC, 0, 1.0, 0)
/* Buffer DAC first to input stream 0 */
DISCRETE_INPUT_BUFFER(DS_DAC, 0)
//DISCRETE_INPUT_DATA(DS_DAC)
/* 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+*")
@ -639,7 +635,7 @@ static DISCRETE_SOUND_START(radarscp)
DISCRETE_INPUT_NOT(DS_DISCHARGE_INV)
/* Must be in task if tasks added */
DISCRETE_INPUTX_STREAM(DS_DAC, 0, 1.0, 0)
DISCRETE_INPUT_BUFFER(DS_DAC, 0)
//DISCRETE_INPUT_DATA(DS_DAC)
/* Mixing - DAC */
@ -1171,7 +1167,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("discdac", dkong_p1_w) /* only write to dac */
AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_DEVWRITE("discrete", 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)
@ -1187,7 +1183,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("discdac", dkong_p1_w) /* DAC here */
AM_RANGE(0x00, 0xff) AM_DEVWRITE("discrete", 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")
@ -1262,11 +1258,6 @@ 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)