diff --git a/src/emu/sound/disc_dev.c b/src/emu/sound/disc_dev.c index ff4992a5bba..4520ee7b018 100644 --- a/src/emu/sound/disc_dev.c +++ b/src/emu/sound/disc_dev.c @@ -234,7 +234,7 @@ static DISCRETE_STEP(dsd_555_astbl) * dt = R*C(log(1/(1-(Vc/Vr)))) */ - dt = disc_info->sample_time; + dt = node->info->sample_time; /* Sometimes a switching network is used to setup the capacitance. * These may select no capacitor, causing oscillation to stop. @@ -338,7 +338,7 @@ static DISCRETE_STEP(dsd_555_astbl) } /* Convert last switch time to a ratio */ - x_time = x_time / disc_info->sample_time; + x_time = x_time / node->info->sample_time; switch (context->output_type) { @@ -387,7 +387,7 @@ static DISCRETE_RESET(dsd_555_astbl) context->v_out_high = (info->v_out_high == DEFAULT_555_HIGH) ? info->v_pos - 1.2 : info->v_out_high; /* setup v_charge or node */ - v_charge_node = discrete_find_node(disc_info, info->v_charge); + v_charge_node = discrete_find_node(node->info, info->v_charge); if (v_charge_node) context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]); else @@ -548,7 +548,7 @@ static DISCRETE_RESET(dsd_555_mstbl) context->output_type = info->options & DISC_555_OUT_MASK; if ((context->output_type == DISC_555_OUT_COUNT_F) || (context->output_type == DISC_555_OUT_COUNT_R)) { - discrete_log(disc_info, "Invalid Output type in NODE_%d.\n", node->node - NODE_00); + discrete_log(node->info, "Invalid Output type in NODE_%d.\n", node->node - NODE_00); context->output_type = DISC_555_OUT_SQW; } @@ -642,7 +642,7 @@ static DISCRETE_STEP(dsd_555_cc) return; } - dt = disc_info->sample_time; /* Change in time */ + dt = node->info->sample_time; /* Change in time */ v_cap = context->cap_voltage; /* Set to voltage before change */ v_vcharge_limit = DSD_555_CC__VIN + info->v_cc_junction; /* the max v_cap can be and still be charged by i */ /* Calculate charging current */ @@ -888,7 +888,7 @@ static DISCRETE_STEP(dsd_555_cc) context->cap_voltage = v_cap_next; /* Convert last switch time to a ratio */ - x_time = x_time / disc_info->sample_time; + x_time = x_time / node->info->sample_time; switch (context->output_type) { @@ -1171,7 +1171,7 @@ static DISCRETE_STEP(dsd_555_vco1) double v_cap; /* Current voltage on capacitor, before dt */ double v_cap_next = 0; /* Voltage on capacitor, after dt */ - dt = disc_info->sample_time; /* Change in time */ + dt = node->info->sample_time; /* Change in time */ v_cap = context->cap_voltage; /* Check: if the Control Voltage node is connected. */ @@ -1275,7 +1275,7 @@ static DISCRETE_STEP(dsd_555_vco1) context->cap_voltage = v_cap_next; /* Convert last switch time to a ratio. No x_time in reset. */ - x_time = x_time / disc_info->sample_time; + x_time = x_time / node->info->sample_time; if (!DSD_555_VCO1__RESET) x_time = 0; switch (context->output_type) @@ -1403,7 +1403,7 @@ static DISCRETE_STEP(dsd_566) if (DSD_566__ENABLE && !context->error) { - dt = disc_info->sample_time; /* Change in time */ + dt = node->info->sample_time; /* Change in time */ v_cap = context->cap_voltage; /* Set to voltage before change */ /* get the v_charge and update each step if it is a node */ @@ -1528,7 +1528,7 @@ static DISCRETE_RESET(dsd_566) } /* setup v_charge or node */ - v_charge_node = discrete_find_node(disc_info, info->v_charge); + v_charge_node = discrete_find_node(node->info, info->v_charge); if (v_charge_node) context->v_charge_node = &(v_charge_node->output[NODE_CHILD_NODE_NUM(info->v_charge)]); else @@ -1608,7 +1608,7 @@ static DISCRETE_STEP(dsd_ls624) double en = 0.0f; int cntf = 0, cntr = 0; - sample_t = disc_info->sample_time; /* Change in time */ + sample_t = node->info->sample_time; /* Change in time */ //dt = LS624_T(DSD_LS624__C, DSD_LS624__VRNG, DSD_LS624__VMOD) / 2.0; dt = 1.0f / (2.0f * LS624_F(DSD_LS624__C, DSD_LS624__VMOD, DSD_LS624__VRNG)); t = context->remain; diff --git a/src/emu/sound/disc_flt.c b/src/emu/sound/disc_flt.c index 6986f851691..c284939a47c 100644 --- a/src/emu/sound/disc_flt.c +++ b/src/emu/sound/disc_flt.c @@ -229,7 +229,7 @@ static DISCRETE_RESET(dst_filter1) { struct dss_filter1_context *context = (struct dss_filter1_context *)node->context; - calculate_filter1_coefficients(disc_info, DST_FILTER1__FREQ, DST_FILTER1__TYPE, &context->a1, &context->b0, &context->b1); + calculate_filter1_coefficients(node->info, DST_FILTER1__FREQ, DST_FILTER1__TYPE, &context->a1, &context->b0, &context->b1); node->output[0] = 0; } @@ -259,7 +259,7 @@ static void calculate_filter2_coefficients(const discrete_info *disc_info, double w; /* cutoff freq, in radians/sec */ double w_squared; double den; /* temp variable */ - double two_over_T = 2*disc_info->sample_rate; + double two_over_T = 2 * disc_info->sample_rate; double two_over_T_squared = two_over_T * two_over_T; /* calculate digital filter coefficents */ @@ -318,7 +318,7 @@ static DISCRETE_RESET(dst_filter2) { struct dss_filter2_context *context = (struct dss_filter2_context *)node->context; - calculate_filter2_coefficients(disc_info, DST_FILTER2__FREQ, DST_FILTER2__DAMP, DST_FILTER2__TYPE, + calculate_filter2_coefficients(node->info, DST_FILTER2__FREQ, DST_FILTER2__DAMP, DST_FILTER2__TYPE, &context->a1, &context->a2, &context->b0, &context->b1, &context->b2); node->output[0] = 0; @@ -508,7 +508,7 @@ static DISCRETE_RESET(dst_op_amp_filt) double d = (info->c1 + info->c2) / sqrt(info->rF / context->rTotal * info->c1 * info->c2); double gain = -info->rF / context->rTotal * info->c2 / (info->c1 + info->c2); - calculate_filter2_coefficients(disc_info, fc, d, DISC_FILTER_BANDPASS, + calculate_filter2_coefficients(node->info, fc, d, DISC_FILTER_BANDPASS, &context->a1, &context->a2, &context->b0, &context->b1, &context->b2); context->b0 *= gain; @@ -577,7 +577,7 @@ static DISCRETE_STEP(dst_rcdisc) if (DST_RCDISC__ENABLE) { node->output[0] = DST_RCDISC__IN * exp(context->t / context->exponent0); - context->t += disc_info->sample_time; + context->t += node->info->sample_time; } else { context->state = 0; @@ -780,17 +780,17 @@ static DISCRETE_RESET( dst_rcdisc4) /* some error checking. */ if (DST_RCDISC4__R1 <= 0 || DST_RCDISC4__R2 <= 0 || DST_RCDISC4__C1 <= 0 || (DST_RCDISC4__R3 <= 0 && context->type == 1)) { - discrete_log(disc_info, "Invalid component values in NODE_%d.\n", node->node - NODE_00); + discrete_log(node->info, "Invalid component values in NODE_%d.\n", node->node - NODE_00); return; } if (DST_RCDISC4__VP < 3) { - discrete_log(disc_info, "vP must be >= 3V in NODE_%d.\n", node->node - NODE_00); + discrete_log(node->info, "vP must be >= 3V in NODE_%d.\n", node->node - NODE_00); return; } if (DST_RCDISC4__TYPE < 1 || DST_RCDISC4__TYPE > 3) { - discrete_log(disc_info, "Invalid circuit type in NODE_%d.\n", node->node - NODE_00); + discrete_log(node->info, "Invalid circuit type in NODE_%d.\n", node->node - NODE_00); return; } @@ -1236,7 +1236,7 @@ static DISCRETE_RESET(dst_rcintegrate) struct dst_rcintegrate_context *context = (struct dst_rcintegrate_context *)node->context; double r; - double dt = disc_info->sample_time; + double dt = node->info->sample_time; context->type = DST_RCINTEGRATE__TYPE; @@ -1312,7 +1312,7 @@ static DISCRETE_RESET(dst_sallen_key) fatalerror("Unknown sallen key filter type"); } - calculate_filter2_coefficients(disc_info, freq, 1.0 / q, DISC_FILTER_LOWPASS, + calculate_filter2_coefficients(node->info, freq, 1.0 / q, DISC_FILTER_LOWPASS, &context->a1, &context->a2, &context->b0, &context->b1, &context->b2); node->output[0] = 0; @@ -1460,8 +1460,8 @@ static DISCRETE_RESET(dst_rcdisc2N) f1 = 1.0 / (2 * M_PI * DST_RCDISC2N__R0 * DST_RCDISC2N__C); f2 = 1.0 / (2 * M_PI * DST_RCDISC2N__R1 * DST_RCDISC2N__C); - calculate_filter1_coefficients(disc_info, f1, DISC_FILTER_LOWPASS, &context->a1_0, &context->b0_0, &context->b1_0); - calculate_filter1_coefficients(disc_info, f2, DISC_FILTER_LOWPASS, &context->a1_1, &context->b0_1, &context->b1_1); + calculate_filter1_coefficients(node->info, f1, DISC_FILTER_LOWPASS, &context->a1_0, &context->b0_0, &context->b1_0); + calculate_filter1_coefficients(node->info, f2, DISC_FILTER_LOWPASS, &context->a1_1, &context->b0_1, &context->b1_1); /* Initialize the object */ node->output[0] = 0; diff --git a/src/emu/sound/disc_inp.c b/src/emu/sound/disc_inp.c index 5361cf6fa9b..54d9f71116d 100644 --- a/src/emu/sound/disc_inp.c +++ b/src/emu/sound/disc_inp.c @@ -15,6 +15,8 @@ * ************************************************************************/ +#define EXPERIMENTAL_STREAM_PARALLEL (0) + #define DSS_INPUT__GAIN (*(node->input[0])) #define DSS_INPUT__OFFSET (*(node->input[1])) #define DSS_INPUT__INIT (*(node->input[2])) @@ -54,7 +56,7 @@ READ8_DEVICE_HANDLER(discrete_sound_r) /* Bring the system up to now */ stream_update(info->discrete_stream); - if ((node->module.type >= DSS_INPUT_DATA) && (node->module.type <= DSS_INPUT_PULSE)) + if ((node->module->type >= DSS_INPUT_DATA) && (node->module->type <= DSS_INPUT_PULSE)) { data = *node_data; } @@ -65,7 +67,7 @@ READ8_DEVICE_HANDLER(discrete_sound_r) return data; } -#if 0 +#if EXPERIMENTAL_STREAM_PARALLEL static STREAM_BACKGROUND_CALLBACK( disc_cb ) { node_description *node = (node_description *) ptr; @@ -86,7 +88,7 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w) UINT8 last_data = *node_data; UINT8 new_data = 0; - switch (node->module.type) + switch (node->module->type) { case DSS_INPUT_DATA: new_data = data; @@ -102,7 +104,7 @@ WRITE8_DEVICE_HANDLER(discrete_sound_w) if (last_data != new_data) { -#if 1 +#if !EXPERIMENTAL_STREAM_PARALLEL /* Bring the system up to now */ stream_update(info->discrete_stream); @@ -172,12 +174,12 @@ static DISCRETE_RESET(dss_adjustment) if (node->custom) { - context->port = input_port_by_tag(disc_info->device->machine->portconfig, (const char *)node->custom); + context->port = input_port_by_tag(node->info->device->machine->portconfig, (const char *)node->custom); if (context->port == NULL) fatalerror("DISCRETE_ADJUSTMENT_TAG - NODE_%d has invalid tag", node->node-NODE_00); } else - context->port = input_port_by_index(disc_info->device->machine->portconfig, DSS_ADJUSTMENT__PORT); + context->port = input_port_by_index(node->info->device->machine->portconfig, DSS_ADJUSTMENT__PORT); context->lastpval = 0x7fffffff; context->pmin = DSS_ADJUSTMENT__PMIN; @@ -233,7 +235,7 @@ static DISCRETE_RESET(dss_input) { UINT8 *node_data = (UINT8 *)node->context; - switch (node->module.type) + switch (node->module->type) { case DSS_INPUT_DATA: *node_data = DSS_INPUT__INIT; @@ -280,13 +282,19 @@ static DISCRETE_STEP(dss_input_stream) stream_sample_t **ptr = (stream_sample_t **)node->context; stream_sample_t *data = *ptr; - node->output[0] = data ? (*data) * DSS_INPUT_STREAM__GAIN + DSS_INPUT_STREAM__OFFSET : 0; + if (data) + { + node->output[0] = (*data) * DSS_INPUT_STREAM__GAIN + DSS_INPUT_STREAM__OFFSET; + (*ptr)++; + } + else + node->output[0] = 0; } static DISCRETE_RESET(dss_input_stream) { int istream = DSS_INPUT_STREAM__STREAM; /* we will use the node's context pointer to point to the input stream data */ - assert(istream < disc_info->discrete_input_streams); - node->context = (discrete_info *) &disc_info->input_stream_data[istream]; + assert(istream < node->info->discrete_input_streams); + node->context = (discrete_info *) &node->info->input_stream_data[istream]; } diff --git a/src/emu/sound/disc_mth.c b/src/emu/sound/disc_mth.c index 6419e8b9128..09bd83518a3 100644 --- a/src/emu/sound/disc_mth.c +++ b/src/emu/sound/disc_mth.c @@ -384,11 +384,11 @@ static DISCRETE_RESET(dst_dac_r1) if (info->ladderLength < 2) { /* You need at least 2 resistors for a ladder */ - discrete_log(disc_info, "dst_dac_r1_reset - Ladder length too small"); + discrete_log(node->info, "dst_dac_r1_reset - Ladder length too small"); } if (info->ladderLength > DISC_LADDER_MAXRES ) { - discrete_log(disc_info, "dst_dac_r1_reset - Ladder length exceeds DISC_LADDER_MAXRES"); + discrete_log(node->info, "dst_dac_r1_reset - Ladder length exceeds DISC_LADDER_MAXRES"); } /* @@ -491,7 +491,7 @@ static DISCRETE_STEP(dst_divide) if(DST_DIVIDE__DIV == 0) { node->output[0 ]= DBL_MAX; /* Max out but don't break */ - discrete_log(disc_info, "dst_divider_step() - Divide by Zero attempted in NODE_%02d.\n",NODE_INDEX(node->node)); + discrete_log(node->info, "dst_divider_step() - Divide by Zero attempted in NODE_%02d.\n",NODE_INDEX(node->node)); } else { @@ -609,7 +609,7 @@ static DISCRETE_STEP(dst_integrate) i_neg = context->v_max_in / info->r1; i_pos = (DST_INTEGRATE__TRG0 - OP_AMP_NORTON_VBE) / info->r2; if (i_pos < 0) i_pos = 0; - node->output[0] += (i_pos - i_neg) / disc_info->sample_rate / info->c; + node->output[0] += (i_pos - i_neg) / node->info->sample_rate / info->c; break; case DISC_INTEGRATE_OP_AMP_2 | DISC_OP_AMP_IS_NORTON: @@ -618,7 +618,7 @@ static DISCRETE_STEP(dst_integrate) i_neg = dst_trigger_function(trig0, trig1, 0, info->f0) ? context->v_max_in_d / info->r1 : 0; i_pos = dst_trigger_function(trig0, trig1, 0, info->f1) ? context->v_max_in / info->r2 : 0; i_pos += dst_trigger_function(trig0, trig1, 0, info->f2) ? context->v_max_in_d / info->r3 : 0; - node->output[0] += (i_pos - i_neg) / disc_info->sample_rate / info->c; + node->output[0] += (i_pos - i_neg) / node->info->sample_rate / info->c; break; } @@ -646,7 +646,7 @@ static DISCRETE_RESET(dst_integrate) v = info->v1 * info->r3 / (info->r2 + info->r3); /* vRef */ v = info->v1 - v; /* actual charging voltage */ i = v / info->r1; - context->change = i / disc_info->sample_rate / info->c; + context->change = i / node->info->sample_rate / info->c; } node->output[0] = 0; } @@ -1227,7 +1227,7 @@ static DISCRETE_RESET(dst_mixer) context->r_node_bit_flag = 0; for (bit = 0; bit < 8; bit++) { - r_node = discrete_find_node(disc_info, info->r_node[bit]); + r_node = discrete_find_node(node->info, info->r_node[bit]); if (r_node != NULL) { context->r_node[bit] = &(r_node->output[NODE_CHILD_NODE_NUM(info->r_node[bit])]); @@ -1354,7 +1354,7 @@ static DISCRETE_STEP(dst_multiplex) else { /* Bad address. We will leave the output alone. */ - discrete_log(disc_info, "NODE_%02d - Address = %d. Out of bounds\n", node->node-NODE_00, addr); + discrete_log(node->info, "NODE_%02d - Address = %d. Out of bounds\n", node->node-NODE_00, addr); } } else @@ -1439,7 +1439,7 @@ static DISCRETE_STEP(dst_oneshot) if (do_count) { - context->countdown -= disc_info->sample_time; + context->countdown -= node->info->sample_time; if(context->countdown <= 0.0) { node->output[0] = (DST_ONESHOT__TYPE & DISC_OUT_ACTIVE_LOW) ? DST_ONESHOT__AMP : 0; @@ -1514,7 +1514,7 @@ static DISCRETE_RESET(dst_ramp) struct dss_ramp_context *context = (struct dss_ramp_context *)node->context; node->output[0] = DST_RAMP__CLAMP; - context->step = DST_RAMP__GRAD / disc_info->sample_rate; + context->step = DST_RAMP__GRAD / node->info->sample_rate; context->dir = ((DST_RAMP__END - DST_RAMP__START) == abs(DST_RAMP__END - DST_RAMP__START)); context->last_en = 0; } @@ -1560,7 +1560,7 @@ static DISCRETE_STEP(dst_samphold) if (DST_SAMPHOLD__CLOCK == 0) node->output[0] = DST_SAMPHOLD__IN0; break; default: - discrete_log(disc_info, "dst_samphold_step - Invalid clocktype passed"); + discrete_log(node->info, "dst_samphold_step - Invalid clocktype passed"); break; } } @@ -1762,7 +1762,7 @@ static DISCRETE_STEP(dst_transform) top = (int)number1 ^ (int)top; break; default: - discrete_log(disc_info, "dst_transform_step - Invalid function type/variable passed"); + discrete_log(node->info, "dst_transform_step - Invalid function type/variable passed"); node->output[0] = 0; break; } @@ -1869,7 +1869,7 @@ static DISCRETE_RESET(dst_op_amp) } else /* linear charge */ - context->exponent = disc_info->sample_rate * info->c; + context->exponent = node->info->sample_rate * info->c; } if (info->r3 > 0) diff --git a/src/emu/sound/disc_wav.c b/src/emu/sound/disc_wav.c index 21868c7b54a..33d698fc94d 100644 --- a/src/emu/sound/disc_wav.c +++ b/src/emu/sound/disc_wav.c @@ -199,10 +199,10 @@ static DISCRETE_STEP(dss_counter) if (context->clock_type == DISC_CLK_IS_FREQ) { /* We need to keep clocking the internal clock even if disabled. */ - cycles = (context->t_left + disc_info->sample_time) * ds_clock; + cycles = (context->t_left + node->info->sample_time) * ds_clock; inc = (int)cycles; context->t_left = (cycles - inc) / ds_clock; - if (inc) x_time = context->t_left / disc_info->sample_time; + if (inc) x_time = context->t_left / node->info->sample_time; } else { @@ -401,7 +401,7 @@ static DISCRETE_STEP(dss_lfsr) if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ) { /* We need to keep clocking the internal clock even if disabled. */ - cycles = (context->t_left + disc_info->sample_time) / context->t_clock; + cycles = (context->t_left + node->info->sample_time) / context->t_clock; inc = (int)cycles; context->t_left = (cycles - inc) * context->t_clock; } @@ -445,22 +445,22 @@ static DISCRETE_STEP(dss_lfsr) fbresult = (context->lfsr_reg >> lfsr_desc->bitlength) & 0x01; /* Stage 2 feedback combine fbresultNew with infeed bit */ - fbresult = dss_lfsr_function(disc_info, lfsr_desc->feedback_function1, fbresult, noise_feed, 0x01); + fbresult = dss_lfsr_function(node->info, lfsr_desc->feedback_function1, fbresult, noise_feed, 0x01); /* Stage 3 first we setup where the bit is going to be shifted into */ fbresult = fbresult * lfsr_desc->feedback_function2_mask; /* Then we left shift the register, */ context->lfsr_reg = context->lfsr_reg << 1; /* Now move the fbresult into the shift register and mask it to the bitlength */ - context->lfsr_reg = dss_lfsr_function(disc_info, lfsr_desc->feedback_function2, fbresult, context->lfsr_reg, (1 << lfsr_desc->bitlength) - 1 ); + context->lfsr_reg = dss_lfsr_function(node->info, lfsr_desc->feedback_function2, fbresult, context->lfsr_reg, (1 << lfsr_desc->bitlength) - 1 ); /* Now get and store the new feedback result */ /* Fetch the feedback bits */ fb0 = (context->lfsr_reg >> lfsr_desc->feedback_bitsel0) & 0x01; fb1 = (context->lfsr_reg >> lfsr_desc->feedback_bitsel1) & 0x01; /* Now do the combo on them */ - fbresult = dss_lfsr_function(disc_info, lfsr_desc->feedback_function0, fb0, fb1, 0x01); - context->lfsr_reg = dss_lfsr_function(disc_info, DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << lfsr_desc->bitlength, (2 << lfsr_desc->bitlength) - 1); + fbresult = dss_lfsr_function(node->info, lfsr_desc->feedback_function0, fb0, fb1, 0x01); + context->lfsr_reg = dss_lfsr_function(node->info, DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << lfsr_desc->bitlength, (2 << lfsr_desc->bitlength) - 1); } /* Now select the output bit */ @@ -500,7 +500,7 @@ static DISCRETE_RESET(dss_lfsr) context->out_lfsr_reg = (lfsr_desc->flags & DISC_LFSR_FLAG_OUTPUT_SR_SN1) ? 1 : 0; if ((lfsr_desc->clock_type < DISC_CLK_ON_F_EDGE) || (lfsr_desc->clock_type > DISC_CLK_IS_FREQ)) - discrete_log(disc_info, "Invalid clock type passed in NODE_%d\n", NODE_INDEX(node->node)); + discrete_log(node->info, "Invalid clock type passed in NODE_%d\n", NODE_INDEX(node->node)); context->last = (DSS_COUNTER__CLOCK != 0); if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_LFSR_NOISE__CLOCK; @@ -513,8 +513,8 @@ static DISCRETE_RESET(dss_lfsr) fb0 = (context->lfsr_reg >> lfsr_desc->feedback_bitsel0) & 0x01; fb1=(context->lfsr_reg >> lfsr_desc->feedback_bitsel1) & 0x01; /* Now do the combo on them */ - fbresult = dss_lfsr_function(disc_info, lfsr_desc->feedback_function0, fb0, fb1, 0x01); - context->lfsr_reg=dss_lfsr_function(disc_info, DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << lfsr_desc->bitlength, (2<< lfsr_desc->bitlength ) - 1); + fbresult = dss_lfsr_function(node->info, lfsr_desc->feedback_function0, fb0, fb1, 0x01); + context->lfsr_reg=dss_lfsr_function(node->info, DISC_LFSR_REPLACE, context->lfsr_reg, fbresult << lfsr_desc->bitlength, (2<< lfsr_desc->bitlength ) - 1); /* Now select and setup the output bit */ node->output[0] = (context->lfsr_reg >> lfsr_desc->output_bit) & 0x01; @@ -554,7 +554,7 @@ static DISCRETE_STEP(dss_noise) if(context->phase > (2.0 * M_PI)) { /* GCC's rand returns a RAND_MAX value of 0x7fff */ - int newval = (mame_rand(disc_info->device->machine) & 0x7fff) - 16384; + int newval = (mame_rand(node->info->device->machine) & 0x7fff) - 16384; /* make sure the peak to peak values are the amplitude */ node->output[0] = DSS_NOISE__AMP / 2; @@ -577,7 +577,7 @@ static DISCRETE_STEP(dss_noise) /* The enable input only curtails output, phase rotation still occurs. */ /* We allow the phase to exceed 2Pi here, so we can tell when to sample the noise. */ - context->phase += ((2.0 * M_PI * DSS_NOISE__FREQ) / disc_info->sample_rate); + context->phase += ((2.0 * M_PI * DSS_NOISE__FREQ) / node->info->sample_rate); } @@ -621,10 +621,10 @@ static DISCRETE_STEP(dss_note) if (context->clock_type == DISC_CLK_IS_FREQ) { /* We need to keep clocking the internal clock even if disabled. */ - cycles = (context->t_left + disc_info->sample_time) / context->t_clock; + cycles = (context->t_left + node->info->sample_time) / context->t_clock; inc = (int)cycles; context->t_left = (cycles - inc) * context->t_clock; - if (inc) x_time = context->t_left / disc_info->sample_time; + if (inc) x_time = context->t_left / node->info->sample_time; } else { @@ -754,7 +754,7 @@ static DISCRETE_STEP(dss_op_amp_osc) UINT8 force_charge = 0; UINT8 enable = DSS_OP_AMP_OSC__ENABLE; - dt = disc_info->sample_time; /* Change in time */ + dt = node->info->sample_time; /* Change in time */ vC = context->v_cap; /* Set to voltage before change */ /* work out the charge currents for the VCOs. */ @@ -931,7 +931,7 @@ static DISCRETE_RESET(dss_op_amp_osc) { if IS_VALUE_A_NODE(*r_info_ptr) { - r_node = discrete_find_node(disc_info, *r_info_ptr); + r_node = discrete_find_node(node->info, *r_info_ptr); *r_context_ptr = &(r_node->output[NODE_CHILD_NODE_NUM((int)*r_info_ptr)]); } else @@ -1078,7 +1078,7 @@ static DISCRETE_STEP(dss_sawtoothwave) /* boils out to */ /* phase step = (2Pi*output freq)/sample freq) */ /* Also keep the new phasor in the 2Pi range. */ - context->phase = fmod((context->phase + ((2.0 * M_PI * DSS_SAWTOOTHWAVE__FREQ) / disc_info->sample_rate)), 2.0 * M_PI); + context->phase = fmod((context->phase + ((2.0 * M_PI * DSS_SAWTOOTHWAVE__FREQ) / node->info->sample_rate)), 2.0 * M_PI); } static DISCRETE_RESET(dss_sawtoothwave) @@ -1257,7 +1257,7 @@ static DISCRETE_STEP(dss_sinewave) /* boils out to */ /* phase step = (2Pi*output freq)/sample freq) */ /* Also keep the new phasor in the 2Pi range. */ - context->phase=fmod((context->phase + ((2.0 * M_PI * DSS_SINEWAVE__FREQ) / disc_info->sample_rate)), 2.0 * M_PI); + context->phase=fmod((context->phase + ((2.0 * M_PI * DSS_SINEWAVE__FREQ) / node->info->sample_rate)), 2.0 * M_PI); } static DISCRETE_RESET(dss_sinewave) @@ -1323,7 +1323,7 @@ static DISCRETE_STEP(dss_squarewave) /* boils out to */ /* phase step = (2Pi*output freq)/sample freq) */ /* Also keep the new phasor in the 2Pi range. */ - context->phase=fmod(context->phase + ((2.0 * M_PI * DSS_SQUAREWAVE__FREQ) / disc_info->sample_rate), 2.0 * M_PI); + context->phase=fmod(context->phase + ((2.0 * M_PI * DSS_SQUAREWAVE__FREQ) / node->info->sample_rate), 2.0 * M_PI); } static DISCRETE_RESET(dss_squarewave) @@ -1392,7 +1392,7 @@ static DISCRETE_RESET(dss_squarewfix) { struct dss_squarewfix_context *context = (struct dss_squarewfix_context *)node->context; - context->sample_step = 1.0 / disc_info->sample_rate; + context->sample_step = 1.0 / node->info->sample_rate; context->flip_flop = 1; /* Do the intial time shift and convert freq to off/on times */ @@ -1454,7 +1454,7 @@ static DISCRETE_STEP(dss_squarewave2) /* phase step = 2Pi/(output period/sample period) */ /* boils out to */ /* phase step = 2Pi/(output period*sample freq) */ - newphase = context->phase + ((2.0 * M_PI) / ((DSS_SQUAREWAVE2__T_OFF + DSS_SQUAREWAVE2__T_ON) * disc_info->sample_rate)); + newphase = context->phase + ((2.0 * M_PI) / ((DSS_SQUAREWAVE2__T_OFF + DSS_SQUAREWAVE2__T_ON) * node->info->sample_rate)); /* Keep the new phasor in the 2Pi range.*/ context->phase = fmod(newphase, 2.0 * M_PI); @@ -1607,7 +1607,7 @@ static DISCRETE_STEP(dss_inverter_osc) vMix = rMix* ( (vG3-vG2) / context->r1 + (DSS_INVERTER_OSC__MOD-vG2) / context->r2 + (vI-0.7-vG2)/context->rp); } diff = vMix - context->v_cap; - diff = diff - diff * exp(-disc_info->sample_time / (context->c * rMix)); + diff = diff - diff * exp(-node->info->sample_time / (context->c * rMix)); break; case DISC_OSC_INVERTER_IS_TYPE5: if ((info->clamp >= 0.0) && ((vI< - info->clamp) || (vI> info->vB+info->clamp))) @@ -1625,7 +1625,7 @@ static DISCRETE_STEP(dss_inverter_osc) vMix = rMix* ( (vG3 - vG2) / context->r1 + (DSS_INVERTER_OSC__MOD-vG2) / context->r2 + (vI+0.7-vG2)/context->rp); } diff = vMix - context->v_cap; - diff = diff - diff * exp(-disc_info->sample_time/(context->c * rMix)); + diff = diff - diff * exp(-node->info->sample_time/(context->c * rMix)); break; default: fatalerror("DISCRETE_INVERTER_OSC - Wrong type on NODE_%02d", node->node - NODE_00); @@ -1648,8 +1648,8 @@ static DISCRETE_RESET(dss_inverter_osc) int i; /* exponent */ - context->w = exp(-disc_info->sample_time / (DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__C)); - context->wc = exp(-disc_info->sample_time / ((DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__RP) / (DSS_INVERTER_OSC__RP + DSS_INVERTER_OSC__RC) * DSS_INVERTER_OSC__C)); + context->w = exp(-node->info->sample_time / (DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__C)); + context->wc = exp(-node->info->sample_time / ((DSS_INVERTER_OSC__RC * DSS_INVERTER_OSC__RP) / (DSS_INVERTER_OSC__RP + DSS_INVERTER_OSC__RC) * DSS_INVERTER_OSC__C)); node->output[0] = 0; context->v_cap = 0; context->v_g2_old = 0; @@ -1708,7 +1708,7 @@ static DISCRETE_STEP(dss_trianglewave) /* boils out to */ /* phase step = (2Pi*output freq)/sample freq) */ /* Also keep the new phasor in the 2Pi range. */ - context->phase=fmod((context->phase + ((2.0 * M_PI * DSS_TRIANGLEWAVE__FREQ) / disc_info->sample_rate)), 2.0 * M_PI); + context->phase=fmod((context->phase + ((2.0 * M_PI * DSS_TRIANGLEWAVE__FREQ) / node->info->sample_rate)), 2.0 * M_PI); } static DISCRETE_RESET(dss_trianglewave) diff --git a/src/emu/sound/discrete.c b/src/emu/sound/discrete.c index fe50f12f07e..c19e83266f5 100644 --- a/src/emu/sound/discrete.c +++ b/src/emu/sound/discrete.c @@ -57,16 +57,14 @@ #define DISCRETE_PROFILING (0) - - /************************************* * * Prototypes * *************************************/ -static void init_nodes(discrete_info *info, discrete_sound_block *block_list, const device_config *device); -static void find_input_nodes(discrete_info *info, discrete_sound_block *block_list); +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); @@ -229,7 +227,19 @@ static const discrete_module module_list[] = { DSS_NULL ,"DSS_NULL" , 0 ,0 ,NULL ,NULL } }; +/************************************* + * + * Add an entry to a list + * + *************************************/ +static void add_list(discrete_info *info, linked_list_entry ***list, void *ptr) +{ + **list = auto_alloc(info->device->machine, linked_list_entry); + (**list)->ptr = ptr; + (**list)->next = NULL; + *list = &((**list)->next); +} /************************************* * @@ -249,7 +259,7 @@ static node_description *discrete_find_node(const discrete_info *info, int node) * *************************************/ -static int discrete_build_list(discrete_info *info, discrete_sound_block *intf, discrete_sound_block *out, int offset) +static void discrete_build_list(discrete_info *info, discrete_sound_block *intf, linked_list_entry ***current) { int node_count = 0; @@ -258,56 +268,103 @@ static int discrete_build_list(discrete_info *info, discrete_sound_block *intf, /* scan imported */ if (intf[node_count].type == DSO_IMPORT) { - offset = discrete_build_list(info, (discrete_sound_block *) intf[node_count].custom, out, offset); + discrete_log(info, "discrete_build_list() - DISCRETE_IMPORT @ NODE_%02d", NODE_INDEX(intf[node_count].node) ); + discrete_build_list(info, (discrete_sound_block *) intf[node_count].custom, current); } else if (intf[node_count].type == DSO_REPLACE) { - int i; - + linked_list_entry *entry; + node_count++; if (intf[node_count].type == DSS_NULL) fatalerror("discrete_build_list: DISCRETE_REPLACE at end of node_list"); - for (i = 0; i < offset; i++) - if (out[i].type != NODE_SPECIAL ) - if (out[i].node == intf[node_count].node) + for (entry = info->block_list; entry != NULL; entry = entry->next) + { + discrete_sound_block *block = (discrete_sound_block *) entry->ptr; + + if (block->type != NODE_SPECIAL ) + if (block->node == intf[node_count].node) { - out[i] = intf[node_count]; + entry->ptr = (void *) &intf[node_count]; + discrete_log(info, "discrete_build_list() - DISCRETE_REPLACE @ NODE_%02d", NODE_INDEX(intf[node_count].node) ); break; } + } - if (i >= offset) + if (entry == NULL) fatalerror("discrete_build_list: DISCRETE_REPLACE did not found node %d", NODE_INDEX(intf[node_count].node)); } else if (intf[node_count].type == DSO_DELETE) { - int i,p,deleted; + int p,deleted; + linked_list_entry *entry, *last; p = 0; deleted = 0; - for (i = 0; i < offset; i++) + last = NULL; + for (entry = info->block_list; entry != NULL; last = entry, entry = entry->next) { - if ((out[i].node >= intf[node_count].input_node[0]) && - (out[i].node <= intf[node_count].input_node[1])) + discrete_sound_block *block = (discrete_sound_block *) entry->ptr; + + if ((block->node >= intf[node_count].input_node[0]) && + (block->node <= intf[node_count].input_node[1])) { - discrete_log(info, "discrete_build_list() - DISCRETE_DELETE deleted NODE_%02d", NODE_INDEX(out[i].node) ); - deleted++; - } - else - { - out[p++] = out[i]; + discrete_log(info, "discrete_build_list() - DISCRETE_DELETE deleted NODE_%02d", NODE_INDEX(block->node) ); + if (last != NULL) + last->next = entry->next; + else + info->block_list = entry->next; } } - offset -= deleted; } else - out[offset++] = intf[node_count]; + { + discrete_log(info, "discrete_build_list() - adding node %d (*current %p)\n", node_count, *current); + add_list(info, current, &intf[node_count]); + } node_count++; } - out[offset] = intf[node_count]; - return offset; +} + +/************************************* + * + * Sanity check list + * + *************************************/ + +static void discrete_sanity_check(discrete_info *info) +{ + linked_list_entry *entry; + int node_count = 0; + + discrete_log(info, "discrete_start() - Doing node list sanity check"); + for (entry = info->block_list; entry != NULL; entry = entry->next) + { + discrete_sound_block *block = (discrete_sound_block *) entry->ptr; + + /* make sure we don't have too many nodes overall */ + if (node_count > DISCRETE_MAX_NODES) + fatalerror("discrete_start() - Upper limit of %d nodes exceeded, have you terminated the interface block?", DISCRETE_MAX_NODES); + + /* make sure the node number is in range */ + if (block->node < NODE_START || block->node > NODE_END) + fatalerror("discrete_start() - Invalid node number on node %02d descriptor", block->node); + + /* make sure the node type is valid */ + if (block->type > DSO_OUTPUT) + fatalerror("discrete_start() - Invalid function type on NODE_%02d", NODE_INDEX(block->node) ); + + /* make sure this is a main node */ + if (NODE_CHILD_NODE_NUM(block->node) > 0) + fatalerror("discrete_start() - Child node number on NODE_%02d", NODE_INDEX(block->node) ); + + node_count++; + } + discrete_log(info, "discrete_start() - Sanity check counted %d nodes", node_count); + } /************************************* @@ -318,7 +375,7 @@ static int discrete_build_list(discrete_info *info, discrete_sound_block *intf, static DEVICE_START( discrete ) { - discrete_sound_block *intf; + linked_list_entry **intf; discrete_sound_block *intf_start = (discrete_sound_block *)device->static_config; discrete_info *info = get_safe_token(device); char name[32]; @@ -337,50 +394,29 @@ static DEVICE_START( discrete ) /* create the logfile */ sprintf(name, "discrete%s.log", device->tag); - if (DISCRETE_DEBUGLOG && !info->disclogfile) + if (DISCRETE_DEBUGLOG) info->disclogfile = fopen(name, "w"); /* Build the final block list */ - intf = auto_alloc_array_clear(device->machine, discrete_sound_block, DISCRETE_MAX_NODES); - discrete_build_list(info, intf_start, intf, 0); + info->block_list = NULL; + intf = &info->block_list; + discrete_build_list(info, intf_start, &intf); /* first pass through the nodes: sanity check, fill in the indexed_nodes, and make a total count */ - discrete_log(info, "discrete_start() - Doing node list sanity check"); - for (info->node_count = 0; intf[info->node_count].type != DSS_NULL; info->node_count++) - { - /* make sure we don't have too many nodes overall */ - if (info->node_count > DISCRETE_MAX_NODES) - fatalerror("discrete_start() - Upper limit of %d nodes exceeded, have you terminated the interface block?", DISCRETE_MAX_NODES); - - /* make sure the node number is in range */ - if (intf[info->node_count].node < NODE_START || intf[info->node_count].node > NODE_END) - fatalerror("discrete_start() - Invalid node number on node %02d descriptor", info->node_count); - - /* make sure the node type is valid */ - if (intf[info->node_count].type > DSO_OUTPUT) - fatalerror("discrete_start() - Invalid function type on NODE_%02d", NODE_INDEX(intf[info->node_count].node) ); - - /* make sure this is a main node */ - if (NODE_CHILD_NODE_NUM(intf[info->node_count].node) > 0) - fatalerror("discrete_start() - Child node number on NODE_%02d", NODE_INDEX(intf[info->node_count].node) ); - } - info->node_count++; - discrete_log(info, "discrete_start() - Sanity check counted %d nodes", info->node_count); - - /* allocate memory for the array of actual nodes */ - info->node_list = auto_alloc_array_clear(device->machine, node_description, info->node_count); - - /* allocate memory for the node execution order array */ - info->running_order = auto_alloc_array_clear(device->machine, node_description *, info->node_count); + discrete_sanity_check(info); + + /* Start with empty lists */ + info->node_list = NULL; + info->step_list = NULL; /* allocate memory to hold pointers to nodes by index */ info->indexed_node = auto_alloc_array_clear(device->machine, node_description *, DISCRETE_MAX_NODES); /* initialize the node data */ - init_nodes(info, intf, device); + init_nodes(info, info->block_list, device); /* now go back and find pointers to all input nodes */ - find_input_nodes(info, intf); + find_input_nodes(info); /* then set up the output nodes */ setup_output_nodes(device, info); @@ -403,27 +439,29 @@ static DEVICE_STOP( discrete ) if (DISCRETE_PROFILING) { - int nodenum; + int count = 0; + linked_list_entry *entry; osd_ticks_t total = 0; osd_ticks_t tresh; - printf("Total Samples: %d\n", info->total_samples); /* calculate total time */ - for (nodenum = 0; nodenum < info->node_count; nodenum++) + for (entry = info->step_list; entry != NULL; entry = entry->next) { - node_description *node = info->running_order[nodenum]; + node_description *node = (node_description *) entry->ptr; /* Now step the node */ total += node->run_time; + count++; } /* print statistics */ - tresh = total / info->node_count; - for (nodenum = 0; nodenum < info->node_count; nodenum++) + printf("Total Samples: %d\n", info->total_samples); + tresh = total / count; + for (entry = info->step_list; entry != NULL; entry = entry->next) { - node_description *node = info->running_order[nodenum]; + node_description *node = (node_description *) entry->ptr; if (node->run_time > tresh) - printf("%3d: %20s %8.2f %10d\n", NODE_INDEX(node->node), node->module.name, (float) node->run_time / (float) total * 100.0, ((int) node->run_time) / info->total_samples); + printf("%3d: %20s %8.2f %10d\n", NODE_INDEX(node->node), node->module->name, (float) node->run_time / (float) total * 100.0, ((int) node->run_time) / info->total_samples); } } @@ -457,22 +495,22 @@ static DEVICE_STOP( discrete ) static DEVICE_RESET( discrete ) { discrete_info *info = get_safe_token(device); - int nodenum; + linked_list_entry *entry; /* loop over all nodes */ - for (nodenum = 0; nodenum < info->node_count; nodenum++) + for (entry = info->node_list; entry != 0; entry = entry->next) { - node_description *node = info->running_order[nodenum]; + node_description *node = (node_description *) entry->ptr; node->output[0] = 0; /* if the node has a reset function, call it */ - if (node->module.reset) - (*node->module.reset)(info, node); + if (node->module->reset) + (*node->module->reset)(node); /* otherwise, just step it */ - else if (node->module.step) - (*node->module.step)(info, node); + else if (node->module->step) + (*node->module->step)(node); } } @@ -562,87 +600,120 @@ INLINE void bigselect(const device_config *device, node_description *node) * *************************************/ -static STREAM_UPDATE( discrete_stream_update ) +INLINE void discrete_stream_update_csv(discrete_info *info) { - discrete_info *info = (discrete_info *)param; - int samplenum, nodenum, outputnum; + int nodenum, outputnum; + + /* Dump any csv logs */ + for (outputnum = 0; outputnum < info->num_csvlogs; outputnum++) + { + fprintf(info->disc_csv_file[outputnum], "%" I64FMT "d", ++info->sample_num); + for (nodenum = 0; nodenum < info->csvlog_node[outputnum]->active_inputs; nodenum++) + { + fprintf(info->disc_csv_file[outputnum], ", %f", *info->csvlog_node[outputnum]->input[nodenum]); + } + fprintf(info->disc_csv_file[outputnum], "\n"); + } +} + +INLINE void discrete_stream_update_wave(discrete_info *info) +{ + int outputnum; double val; INT16 wave_data_l, wave_data_r; + /* Dump any wave logs */ + for (outputnum = 0; outputnum < info->num_wavelogs; outputnum++) + { + /* get nodes to be logged and apply gain, then clip to 16 bit */ + val = (*info->wavelog_node[outputnum]->input[0]) * (*info->wavelog_node[outputnum]->input[1]); + val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; + wave_data_l = (INT16)val; + if (info->wavelog_node[outputnum]->active_inputs == 2) + { + /* DISCRETE_WAVELOG1 */ + wav_add_data_16(info->disc_wav_file[outputnum], &wave_data_l, 1); + } + else + { + /* DISCRETE_WAVELOG2 */ + val = (*info->wavelog_node[outputnum]->input[2]) * (*info->wavelog_node[outputnum]->input[3]); + val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; + wave_data_r = (INT16)val; + + wav_add_data_16lr(info->disc_wav_file[outputnum], &wave_data_l, &wave_data_r, 1); + } + } +} + +INLINE void discrete_stream_update_nodes(discrete_info *info, stream_sample_t **outputs) +{ + int outputnum; + double val; + linked_list_entry *entry; + + if (DISCRETE_PROFILING) + info->total_samples++; + + /* loop over all nodes */ + for (entry = info->step_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(); + + } + + /* 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; + } +} + +static STREAM_UPDATE( discrete_stream_update ) +{ + discrete_info *info = (discrete_info *)param; + stream_sample_t *outptr[DISCRETE_MAX_OUTPUTS]; + int samplenum, nodenum, outputnum; + + /* Setup any output streams */ + for (outputnum = 0; outputnum < info->discrete_outputs; outputnum++) + outptr[outputnum] = outputs[outputnum]; + /* Setup any input streams */ for (nodenum = 0; nodenum < info->discrete_input_streams; nodenum++) { info->input_stream_data[nodenum] = inputs[nodenum]; } - /* Now we must do samples iterations of the node list, one output for each step */ - for (samplenum = 0; samplenum < samples; samplenum++) + if ((info->num_csvlogs > 0) || (info->num_wavelogs > 0)) { - info->total_samples++; - /* loop over all nodes */ - for (nodenum = 0; nodenum < info->node_count; nodenum++) + /* Now we must do samples iterations of the node list, one output for each step */ + for (samplenum = 0; samplenum < samples; samplenum++) { - node_description *node = info->running_order[nodenum]; - - /* Now step the node */ - if (DISCRETE_PROFILING) - node->run_time -= osd_profiling_ticks(); - - if (node->module.step) - (*node->module.step)(info, node); - //bigselect(info->device, node); - - if (DISCRETE_PROFILING) - node->run_time += osd_profiling_ticks(); - + discrete_stream_update_nodes(info, outptr); } - - /* 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++) + } + else + { + /* Now we must do samples iterations of the node list, one output for each step */ + for (samplenum = 0; samplenum < samples; samplenum++) { - val = (*info->output_node[outputnum]->input[0]) * (*info->output_node[outputnum]->input[1]); - outputs[outputnum][samplenum] = val; - } + discrete_stream_update_nodes(info, outptr); + discrete_stream_update_csv(info); + discrete_stream_update_wave(info); - /* Dump any csv logs */ - for (outputnum = 0; outputnum < info->num_csvlogs; outputnum++) - { - fprintf(info->disc_csv_file[outputnum], "%" I64FMT "d", ++info->sample_num); - for (nodenum = 0; nodenum < info->csvlog_node[outputnum]->active_inputs; nodenum++) - { - fprintf(info->disc_csv_file[outputnum], ", %f", *info->csvlog_node[outputnum]->input[nodenum]); - } - fprintf(info->disc_csv_file[outputnum], "\n"); - } - - /* Dump any wave logs */ - for (outputnum = 0; outputnum < info->num_wavelogs; outputnum++) - { - /* get nodes to be logged and apply gain, then clip to 16 bit */ - val = (*info->wavelog_node[outputnum]->input[0]) * (*info->wavelog_node[outputnum]->input[1]); - val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; - wave_data_l = (INT16)val; - if (info->wavelog_node[outputnum]->active_inputs == 2) - { - /* DISCRETE_WAVELOG1 */ - wav_add_data_16(info->disc_wav_file[outputnum], &wave_data_l, 1); - } - else - { - /* DISCRETE_WAVELOG2 */ - val = (*info->wavelog_node[outputnum]->input[2]) * (*info->wavelog_node[outputnum]->input[3]); - val = (val < -32768) ? -32768 : (val > 32767) ? 32767 : val; - wave_data_r = (INT16)val; - - wav_add_data_16lr(info->disc_wav_file[outputnum], &wave_data_l, &wave_data_r, 1); - } - } - - /* advance input streams */ - for (nodenum = 0; nodenum < info->discrete_input_streams; nodenum++) - { - info->input_stream_data[nodenum]++; } } @@ -656,24 +727,24 @@ static STREAM_UPDATE( discrete_stream_update ) * *************************************/ -static void init_nodes(discrete_info *info, discrete_sound_block *block_list, const device_config *device) + +static void init_nodes(discrete_info *info, linked_list_entry *block_list, const device_config *device) { - int nodenum; + linked_list_entry **step_list = &info->step_list; + linked_list_entry **node_list = &info->node_list; + linked_list_entry *entry; /* start with no outputs or input streams */ info->discrete_outputs = 0; info->discrete_input_streams = 0; /* loop over all nodes */ - for (nodenum = 0; nodenum < info->node_count; nodenum++) + for (entry = block_list; entry != NULL; entry = entry->next) { - discrete_sound_block *block = &block_list[nodenum]; - node_description *node = &info->node_list[nodenum]; + discrete_sound_block *block = (discrete_sound_block *) entry->ptr; + node_description *node = auto_alloc_clear(info->device->machine, node_description); int inputnum, modulenum; - /* our running order just follows the order specified */ - info->running_order[nodenum] = node; - /* keep track of special nodes */ if (block->node == NODE_SPECIAL) { @@ -721,8 +792,9 @@ static void init_nodes(discrete_info *info, discrete_sound_block *block_list, co 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->module = &module_list[modulenum]; node->output[0] = 0.0; node->block = block; @@ -733,36 +805,40 @@ static void init_nodes(discrete_info *info, discrete_sound_block *block_list, co } node->context = NULL; - node->name = block->name; node->custom = block->custom; /* setup module if custom */ if (block->type == DST_CUSTOM) { const discrete_custom_info *custom = (const discrete_custom_info *)node->custom; - node->module.reset = custom->reset; - node->module.step = custom->step; - node->module.contextsize = custom->contextsize; + node->module = &custom->module; node->custom = custom->custom; } /* allocate memory if necessary */ - if (node->module.contextsize) - node->context = auto_alloc_array_clear(device->machine, UINT8, node->module.contextsize); + if (node->module->contextsize) + node->context = auto_alloc_array_clear(device->machine, UINT8, node->module->contextsize); /* if we are an stream input node, track that */ if (block->type == DSS_INPUT_STREAM) { if (info->discrete_input_streams == DISCRETE_MAX_OUTPUTS) fatalerror("init_nodes() - There can not be more then %d input stream nodes", DISCRETE_MAX_OUTPUTS); - /* we will use the node's context pointer to point to the input stream data */ - //node->context = &info->input_stream_data[info->discrete_input_streams++]; + node->context = NULL; info->discrete_input_streams++; } + /* add to node list */ + add_list(info, &node_list, node); + + /* our running order just follows the order specified */ + /* does the node step ? */ + if (node->module->step != NULL) + add_list(info, &step_list, node); + /* and register save state */ - state_save_register_device_item_array(device, nodenum, node->output); + state_save_register_device_item_array(device, node->node, node->output); } /* if no outputs, give an error */ @@ -778,15 +854,16 @@ static void init_nodes(discrete_info *info, discrete_sound_block *block_list, co * *************************************/ -static void find_input_nodes(discrete_info *info, discrete_sound_block *block_list) +static void find_input_nodes(discrete_info *info) { - int nodenum, inputnum; + int inputnum; + linked_list_entry *entry; /* loop over all nodes */ - for (nodenum = 0; nodenum < info->node_count; nodenum++) + for (entry = info->node_list; entry != NULL; entry = entry->next) { - node_description *node = &info->node_list[nodenum]; - discrete_sound_block *block = &block_list[nodenum]; + node_description *node = (node_description *) entry->ptr; + const discrete_sound_block *block = node->block; /* loop over all active inputs */ for (inputnum = 0; inputnum < node->active_inputs; inputnum++) @@ -800,7 +877,7 @@ static void find_input_nodes(discrete_info *info, discrete_sound_block *block_li if (!node_ref) fatalerror("discrete_start - NODE_%02d referenced a non existent node NODE_%02d", NODE_INDEX(node->node), NODE_INDEX(inputnode)); - if (NODE_CHILD_NODE_NUM(inputnode) >= node_ref->module.num_output) + if (NODE_CHILD_NODE_NUM(inputnode) >= node_ref->module->num_output) fatalerror("discrete_start - NODE_%02d referenced non existent output %d on node NODE_%02d", NODE_INDEX(node->node), NODE_CHILD_NODE_NUM(inputnode), NODE_INDEX(inputnode)); node->input[inputnum] = &(node_ref->output[NODE_CHILD_NODE_NUM(inputnode)]); /* Link referenced node out to input */ diff --git a/src/emu/sound/discrete.h b/src/emu/sound/discrete.h index 27f68b9d95b..c4dbad7c179 100644 --- a/src/emu/sound/discrete.h +++ b/src/emu/sound/discrete.h @@ -3228,13 +3228,18 @@ * DISCRETE_CUSTOMx(name of node, * input 0 node or static value, ...) * - * discrete_custom_info = {reset, step, contextsize, custom} - * reset = address called to reset a node after creation or system reset - * step = address called to execute one time delta of output update - * contextsize = size of context to create + * discrete_custom_info = {discrete_module, custom} + * discrete_module = discrete module definition * custom = address of specific initialization data * - * EXAMPLES: see Donkey Kong + * In most case, you should be able to use + * + * discrete_custom_info = {DISCRETE_CUSTOM_MODULE(basename, context type), custom} + * + * if you have used DISCRETE_STEP(basename) and DISCRETE_RESET(basename) to define + * the step/reset procedures. + * + * EXAMPLES: see Donkey Kong, Mario Bros. * *********************************************************************** ======================================================================= @@ -3329,13 +3334,13 @@ *************************************/ /* calculate charge exponent using discrete sample time */ -#define RC_CHARGE_EXP(rc) (1.0 - exp(disc_info->neg_sample_time / (rc))) +#define RC_CHARGE_EXP(rc) (1.0 - exp(node->info->neg_sample_time / (rc))) /* calculate charge exponent using given sample time */ #define RC_CHARGE_EXP_DT(rc, dt) (1.0 - exp(-(dt) / (rc))) #define RC_CHARGE_NEG_EXP_DT(rc, dt) (1.0 - exp((dt) / (rc))) /* calculate discharge exponent using discrete sample time */ -#define RC_DISCHARGE_EXP(rc) (exp(disc_info->neg_sample_time / (rc))) +#define RC_DISCHARGE_EXP(rc) (exp(node->info->neg_sample_time / (rc))) /* calculate discharge exponent using given sample time */ #define RC_DISCHARGE_EXP_DT(rc, dt) (exp(-(dt) / (rc))) #define RC_DISCHARGE_NEG_EXP_DT(rc, dt) (exp((dt) / (rc))) @@ -3349,19 +3354,14 @@ #define DISCRETE_STEP_NAME( _func ) _func ## _step #define DISCRETE_RESET_NAME( _func ) _func ## _reset -#define DISCRETE_STEP(_func) void DISCRETE_STEP_NAME(_func) (const discrete_info *disc_info, node_description *node) -#define DISCRETE_RESET(_func) void DISCRETE_RESET_NAME(_func) (const discrete_info *disc_info, node_description *node) +#define DISCRETE_STEP(_func) void DISCRETE_STEP_NAME(_func) (node_description *node) +#define DISCRETE_RESET(_func) void DISCRETE_RESET_NAME(_func) (node_description *node) -#define DISCRETE_STEP_CALL(_func) DISCRETE_STEP_NAME(_func) (disc_info, node) -#define DISCRETE_RESET_CALL(_func) DISCRETE_RESET_NAME(_func) (disc_info, node) +#define DISCRETE_STEP_CALL(_func) DISCRETE_STEP_NAME(_func) (node) +#define DISCRETE_RESET_CALL(_func) DISCRETE_RESET_NAME(_func) (node) -#if 0 -#define DISCRETE_STEP(_func) void DISCRETE_STEP_NAME(_func) (const device_config *device, node_description *node) -#define DISCRETE_RESET(_func) void DISCRETE_RESET_NAME(_func) (const device_config *device, node_description *node) - -#define DISCRETE_STEP_CALL(_func) DISCRETE_STEP_NAME(_func) (device, node) -#define DISCRETE_RESET_CALL(_func) DISCRETE_RESET_NAME(_func) (device, node) -#endif +#define DISCRETE_CUSTOM_MODULE(_basename, _context_type) \ + { DST_CUSTOM, "CUSTOM", 1, sizeof(_context_type), DISCRETE_RESET_NAME(_basename), DISCRETE_STEP_NAME(_basename) } /************************************* * @@ -3611,8 +3611,8 @@ struct _discrete_module const char * name; int num_output; /* Total number of output nodes, i.e. Master node + 1 */ size_t contextsize; - void (*reset)(const discrete_info *disc_info, node_description *node); /* Called to reset a node after creation or system reset */ - void (*step)(const discrete_info *disc_info, node_description *node); /* Called to execute one time delta of output update */ + void (*reset)(node_description *node); /* Called to reset a node after creation or system reset */ + void (*step)(node_description *node); /* Called to execute one time delta of output update */ }; @@ -3631,15 +3631,17 @@ struct _node_description int input_is_node; /* Bit Flags. 1 in bit location means input_is_node */ const double * input[DISCRETE_MAX_INPUTS]; /* Addresses of Input values */ - discrete_module module; /* Copy of the node's module info */ - const discrete_sound_block *block; /* Points to the node's setup block. */ void * context; /* Contextual information specific to this node type */ - const char * name; /* Text name string for identification/debug */ const void * custom; /* Custom function specific initialisation data */ + + const discrete_module *module; /* Node's module info */ + const discrete_sound_block *block; /* Points to the node's setup block. */ + const discrete_info *info; /* Points to the parent */ + osd_ticks_t run_time; }; - + /************************************* * * Core runtime info @@ -3650,6 +3652,13 @@ struct _node_description * *************************************/ +typedef struct _linked_list_entry linked_list_entry; +struct _linked_list_entry +{ + void *ptr; + linked_list_entry *next; +}; + struct _discrete_info { const device_config *device; @@ -3660,10 +3669,16 @@ struct _discrete_info double neg_sample_time; /* internal node tracking */ - int node_count; - node_description **running_order; node_description **indexed_node; - node_description *node_list; + + /* list of all nodes */ + linked_list_entry *node_list; /* node_description * */ + + /* list of nodes which step */ + linked_list_entry *step_list; /* node_description * */ + + /* list of discrete blocks after prescan (IMPORT, DELETE, REPLACE) */ + linked_list_entry *block_list; /* discrete_sound_block * */ /* the input streams */ int discrete_input_streams; @@ -3953,9 +3968,7 @@ struct _discrete_adsr typedef struct _discrete_custom_info discrete_custom_info; struct _discrete_custom_info { - void (*reset)(const discrete_info *disc_info, node_description *node); /* Called to reset a node after creation or system reset */ - void (*step)(const discrete_info *disc_info, node_description *node); /* Called to execute one time delta of output update */ - size_t contextsize; + const discrete_module module; const void *custom; /* Custom function specific initialisation data */ }; @@ -4184,6 +4197,12 @@ enum DSO_IMPORT, /* import from another discrete block */ 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 diff --git a/src/mame/audio/dkong.c b/src/mame/audio/dkong.c index 8304a710c4b..8fa045269d0 100644 --- a/src/mame/audio/dkong.c +++ b/src/mame/audio/dkong.c @@ -343,9 +343,7 @@ static DISCRETE_RESET( dkong_custom_mixer ) static const discrete_custom_info dkong_custom_mixer_info = { - DISCRETE_RESET_NAME( dkong_custom_mixer ), - DISCRETE_STEP_NAME( dkong_custom_mixer ), - sizeof(struct dkong_custom_mixer_context), + DISCRETE_CUSTOM_MODULE( dkong_custom_mixer, struct dkong_custom_mixer_context), NULL }; #endif diff --git a/src/mame/audio/mario.c b/src/mame/audio/mario.c index eec3c406d02..247c7dc1559 100644 --- a/src/mame/audio/mario.c +++ b/src/mame/audio/mario.c @@ -192,7 +192,7 @@ static DISCRETE_STEP( mario_custom_run ) double t1 = 0.5 / LS624_F(MARIO_CUSTOM_C1, MARIO_CUSTOM_IN1, RUN_VCO_VOLTAGE); double t2 = 0.5 / LS624_F(MARIO_CUSTOM_C2, MARIO_CUSTOM_IN2, RUN_VCO_VOLTAGE); - double sample_t = disc_info->sample_time; + double sample_t = node->info->sample_time; double vn, t; //if (MARIO_CUSTOM_VOUT) @@ -258,9 +258,7 @@ static DISCRETE_RESET( mario_custom_run ) static const discrete_custom_info mario_custom_run_info = { - DISCRETE_RESET_NAME( mario_custom_run ), - DISCRETE_STEP_NAME( mario_custom_run ), - sizeof(struct mario_custom_run_context), + DISCRETE_CUSTOM_MODULE( mario_custom_run, struct mario_custom_run_context), NULL };