示例#1
0
int dss_lfsr_init(struct node_description *node)
{
	struct dss_lfsr_context *context;

	discrete_log("dss_lfsr_init() - Creating node %d.",node->node-NODE_00);

	/* Allocate memory for the context array and the node execution order array */
	if((node->context=malloc(sizeof(struct dss_lfsr_context)))==NULL)
	{
		discrete_log("dss_lfsr_init() - Failed to allocate local context memory.");
		return 1;
	}
	else
	{
		/* Initialise memory */
		memset(node->context,0,sizeof(struct dss_lfsr_context));
	}

	/* Initialise the object */
	context=(struct dss_lfsr_context*)node->context;
	context->sampleStep = 1.0 / Machine->sample_rate;
	context->shiftStep = 1.0 / node->input[2];
	context->t = 0;

	dss_lfsr_reset(node);

	return 0;
}
示例#2
0
void dst_dac_r1_reset(struct node_description *node)
{
	const struct discrete_dac_r1_ladder *info = node->custom;
	struct dst_dac_r1_context *context = node->context;

	int	bit;

	/* Calculate the Millman current of the bias circuit */
	if (info->rBias)
		context->iBias = info->vBias / info->rBias;
	else
		context->iBias = 0;

	/*
	 * We will do a small amount of error checking.
	 * But if you are an idiot and pass a bad ladder table
	 * then you deserve a crash.
	 */
	if (info->ladderLength < 2)
	{
		/* You need at least 2 resistors for a ladder */
		discrete_log("dst_dac_r1_reset - Ladder length too small");
	}
	if (info->ladderLength > DISC_LADDER_MAXRES )
	{
		discrete_log("dst_dac_r1_reset - Ladder length exceeds DISC_LADDER_MAXRES");
	}

	/*
	 * Calculate the total of all resistors in parallel.
	 * This is the combined resistance of the voltage sources.
	 * This is used for the charging curve.
	 */
	context->rTotal = 0;
	for(bit=0; bit < info->ladderLength; bit++)
	{
		if (!info->r[bit])
		{
			discrete_log("dst_dac_r1_reset - Resistor can't equal 0");
		}
		context->rTotal += 1.0 / info->r[bit];
	}
	if (info->rBias) context->rTotal += 1.0 / info->rBias;
	if (info->rGnd) context->rTotal += 1.0 / info->rGnd;
	context->rTotal = 1.0 / context->rTotal;

	node->output = 0;

	if (info->cFilter)
	{
		/* Setup filter constants */
		context->exponent = -1.0 / (context->rTotal * info->cFilter  * Machine->sample_rate);
		context->exponent = 1.0 - exp(context->exponent);
	}
}
示例#3
0
void dss_lfsr_reset(struct node_description *node)
{
	const struct discrete_lfsr_desc *lfsr_desc = node->custom;
	struct dss_lfsr_context *context = node->context;
	int fb0,fb1,fbresult;

	if ((lfsr_desc->clock_type < DISC_CLK_ON_F_EDGE) || (lfsr_desc->clock_type > DISC_CLK_IS_FREQ))
		discrete_log("Invalid clock type passed in NODE_%d\n", node->node - NODE_START);
	context->last = (DSS_COUNTER__CLOCK != 0);
	if (lfsr_desc->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_LFSR_NOISE__CLOCK;
	context->t_left = 0;

	context->lfsr_reg=lfsr_desc->reset_value;

	/* 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(lfsr_desc->feedback_function0,fb0,fb1,0x01);
	context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,(context->lfsr_reg), fbresult<<(lfsr_desc->bitlength), ((2<<(lfsr_desc->bitlength))-1));

	/* Now select and setup the output bit */
	node->output=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01;

	/* Final inversion if required */
	if(lfsr_desc->flags&DISC_LFSR_FLAG_OUT_INVERT) node->output=(node->output)?0.0:1.0;

	/* Gain stage */
	node->output=(node->output)?(DSS_LFSR_NOISE__AMP)/2:-(DSS_LFSR_NOISE__AMP)/2;
	/* Bias input as required */
	node->output=node->output+DSS_LFSR_NOISE__BIAS;
}
示例#4
0
文件: discrete.c 项目: mp-lee/pinmame
void discrete_sh_stop (void)
{
	int loop=0;
	if(!init_ok) return;

#ifdef DISCRETE_WAVELOG
	wav_close(wav_file);
#endif

	for(loop=0;loop<node_count;loop++)
	{
	/* Destruct all of the objects */
		discrete_log("discrete_sh_stop() - Calling stop for %s",module_list[node_list[loop].module].name);
		if(module_list[node_list[loop].module].kill) (*module_list[node_list[loop].module].kill)(&node_list[loop]);
	}
	if(node_list) free(node_list);
	if(running_order) free(running_order);
	node_count=0;
	node_list=NULL;
	running_order=NULL;

#ifdef DISCRETE_DEBUGLOG
    if(disclogfile) fclose(disclogfile);
	disclogfile=NULL;
#endif
}
vector <int> residue(int p,int N,int a)
{
    int g=primitive_root(p);
    long long m=discrete_log(g,a,p);
    vector<int> ret;
    if (a==0)
    {
        ret.push_back(0);
        return ret;
    }
    if (m==-1) return ret;
    long long A=N,B=p-1,C=m,x,y;
    long long d=extended_gcd(A,B,x,y);
    if (c%d!=0) return ret;
    x=x*(C/d)%B;
    long long delta=B/d;
    for (int i=0;i<d;i++)
    {
        x=((x+delta)%B+B)%B;
        ret.push_back((int)pow_mod(g,x,p));
    }
    sort(ret.begin(),ret.end());
    ret.erase(unqinue(ret.begin(),ret.end()),ret.end());
    return ret;
}
示例#6
0
void dsd_555_mstbl_reset(node_description *node)
{
	const discrete_555_desc *info = node->custom;
	struct dsd_555_mstbl_context *context = node->context;

	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("Invalid Output type in NODE_%d.\n", node->node - NODE_00);
		context->output_type = DISC_555_OUT_SQW;
	}

	/* Use the supplied values or set to defaults. */
	context->threshold = (info->threshold555 == DEFAULT_555_THRESHOLD) ? info->v555 *2 /3 : info->threshold555;
	context->trigger =  (info->trigger555 == DEFAULT_555_TRIGGER) ? info->v555 /3 : info->trigger555;
	context->output_high_voltage = (info->v555high == DEFAULT_555_HIGH) ? info->v555 - 1.2 : info->v555high;

	context->output_is_ac = info->options & DISC_555_OUT_AC;
	/* Calculate DC shift needed to make squarewave waveform AC */
	context->ac_shift = context->output_is_ac ? -context->output_high_voltage / 2.0 : 0;

	context->error = test_555(context->threshold, context->trigger, info->v555, node->node);

	context->trig_is_logic = (info->options & DISC_555_TRIGGER_IS_VOLTAGE) ? 0: 1;

	context->flip_flop = 0;
	context->cap_voltage = 0;

	node->output = 0;
}
示例#7
0
int dss_lfsr_reset(struct node_description *node)
{
	struct dss_lfsr_context *context;
	struct discrete_lfsr_desc *lfsr_desc;

	context=(struct dss_lfsr_context*)node->context;
	lfsr_desc=(struct discrete_lfsr_desc*)(node->custom);

	context->lfsr_reg=lfsr_desc->reset_value;

	context->lfsr_reg=dss_lfsr_function(DISC_LFSR_REPLACE,0, (dss_lfsr_function(lfsr_desc->feedback_function0,0,0,0x01))<<(lfsr_desc->bitlength),((2<<(lfsr_desc->bitlength))-1));
	discrete_log("Shift register RESET to     %#10X.\n",(context->lfsr_reg));

	/* Now select and setup the output bit */
	node->output=((context->lfsr_reg)>>(lfsr_desc->output_bit))&0x01;

	/* Final inversion if required */
	if(lfsr_desc->flags&DISC_LFSR_FLAG_OUT_INVERT) node->output=(node->output)?0.0:1.0;

	/* Gain stage */
	node->output=(node->output)?(node->input[3])/2:-(node->input[3])/2;
	/* Bias input as required */
	node->output=node->output+node->input[5];

	return 0;
}
示例#8
0
int dss_sawtoothwave_init(struct node_description *node)
{
	discrete_log("dss_trianglewave_init() - Creating node %d.",node->node-NODE_00);

	/* Allocate memory for the context array and the node execution order array */
	if((node->context=malloc(sizeof(struct dss_sawtoothwave_context)))==NULL)
	{
		discrete_log("dss_sawtoothwave_init() - Failed to allocate local context memory.");
		return 1;
	}
	else
	{
		/* Initialise memory */
		memset(node->context,0,sizeof(struct dss_sawtoothwave_context));
	}

	/* Initialise the object */
	dss_sawtoothwave_reset(node);
	return 0;
}
示例#9
0
int	dss_lfsr_function(int myfunc,int in0,int in1,int bitmask)
{
	int retval;

	in0&=bitmask;
	in1&=bitmask;

	switch(myfunc)
	{
		case DISC_LFSR_XOR:
			retval=in0^in1;
			break;
		case DISC_LFSR_OR:
			retval=in0|in1;
			break;
		case DISC_LFSR_AND:
			retval=in0&in1;
			break;
		case DISC_LFSR_XNOR:
			retval=in0^in1;
			retval=retval^bitmask;	/* Invert output */
			break;
		case DISC_LFSR_NOR:
			retval=in0|in1;
			retval=retval^bitmask;	/* Invert output */
			break;
		case DISC_LFSR_NAND:
			retval=in0&in1;
			retval=retval^bitmask;	/* Invert output */
			break;
		case DISC_LFSR_IN0:
			retval=in0;
			break;
		case DISC_LFSR_IN1:
			retval=in1;
			break;
		case DISC_LFSR_NOT_IN0:
			retval=in0^bitmask;
			break;
		case DISC_LFSR_NOT_IN1:
			retval=in1^bitmask;
			break;
		case DISC_LFSR_REPLACE:
			retval=in0&~in1;
			retval=in0|in1;
			break;
		default:
			discrete_log("dss_lfsr_function - Invalid function type passed");
			retval=0;
			break;
	}
	return retval;
}
示例#10
0
void discrete_sh_reset (void)
{
	/* Reset all of the objects */
	int loop=0;

	if(!init_ok) return;

	for(loop=0;loop<node_count;loop++)
	{
		discrete_log("discrete_sh_reset() - Calling reset for %s",module_list[node_list[loop].module].name);
		if(module_list[node_list[loop].module].reset) (*module_list[node_list[loop].module].reset)(&node_list[loop]);
	}
}
示例#11
0
int dss_squarewfix_reset(struct node_description *node)
{
	struct dss_squarewfix_context *context=(struct dss_squarewfix_context*)node->context;

	context->sampleStep = 1.0 / Machine->sample_rate;
	context->flip_flop = 1;

	/* Do the intial time shift and convert freq to off/on times */
	context->tOff = 1.0 / node->input[1];	/* cycle time */
	context->tLeft = node->input[5] / 360.0;	/* convert start phase to % */
	context->tLeft = context->tLeft - (int)context->tLeft;	/* keep % between 0 & 1 */
	context->tLeft = context->tLeft < 0 ? 1.0 + context->tLeft : context->tLeft;	/* if - then flip to + phase */
	context->tLeft *= context->tOff;
	context->tOn = context->tOff * (node->input[3] / 100.0);
	context->tOff -= context->tOn;

discrete_log("RESET in - F:%f D:%f P:%f == tOff:%f tOn:%f tLeft:%f",node->input[1],node->input[3],node->input[5],context->tOff,context->tOn,context->tLeft);
//	while (context->tLeft >= context->flip_flop ? context->tOn : context->tOff)
//	{
//		context->tLeft -= context->flip_flop ? context->tOn : context->tOff;
//		context->flip_flop = context->flip_flop ? 0 : 1;
//	}


	context->tLeft = -context->tLeft;

	/* toggle output and work out intial time shift */
	while (context->tLeft <= 0)
	{
		context->flip_flop = context->flip_flop ? 0 : 1;
		context->tLeft += context->flip_flop ? context->tOn : context->tOff;
	}
discrete_log("RESET out - tLeft:%f FF:%d",context->tLeft,context->flip_flop);

	/* Step the output */
	dss_squarewfix_step(node);

	return 0;
}
示例#12
0
文件: discrete.c 项目: mp-lee/pinmame
void discrete_sh_reset(void)
{
	struct node_description *node;

	/* Reset all of the objects */
	int loop=0,loop2=0;

	if(!init_ok) return;

	for(loop=0;loop<node_count;loop++)
	{
		/* Pick the first node to process */
		node=running_order[loop];

		/* Work out what nodes/inputs are required, dont process NO CONNECT nodes */
		/* these are ones that are connected to NODE_LIST[0]                      */
		for(loop2=0;loop2<node->active_inputs;loop2++)
		{
			if(node->input_node[loop2] && (node->input_node[loop2])->node!=NODE_NC) node->input[loop2]=(node->input_node[loop2])->output;
		}

		/* Now that the inputs have been setup then we should call the reset function */
		/* if a node is stateless then it may have no reset function in which case we */
		/* will call its _step function to setup the output.                          */
		if(module_list[node_list[loop].module].reset)
		{
			discrete_log("discrete_sh_reset() - Calling reset for %s node %d.",module_list[node_list[loop].module].name,node_list[loop].node-NODE_00);
			(*module_list[node_list[loop].module].reset)(&node_list[loop]);
		}
		else if (module_list[node_list[loop].module].step)
		{
			discrete_log("discrete_sh_reset() - Node has no reset, calling step for %s node %d.",module_list[node_list[loop].module].name,node_list[loop].node-NODE_00);
			(*module_list[node_list[loop].module].step)(&node_list[loop]);
		}	
	}
}
示例#13
0
void discrete_sh_stop (void)
{
	int loop=0;
	if(!init_ok) return;

	for(loop=0;loop<node_count;loop++)
	{
	/* Destruct all of the objects */
		discrete_log("discrete_sh_stop() - Calling stop for %s",module_list[node_list[loop].module].name);
		if(module_list[node_list[loop].module].kill) (*module_list[node_list[loop].module].kill)(&node_list[loop]);
	}
	if(node_list) free(node_list);
	if(running_order) free(running_order);
	node_count=0;
	node_list=NULL;
	running_order=NULL;
}
示例#14
0
void dst_divide_step(node_description *node)
{
	if(DST_DIVIDE__ENABLE)
	{
		if(DST_DIVIDE__DIV == 0)
		{
			node->output=DBL_MAX;	/* Max out but don't break */
			discrete_log("dst_divider_step() - Divide by Zero attempted in NODE_%02d.\n",node->node-NODE_START);
		}
		else
		{
			node->output= DST_DIVIDE__IN / DST_DIVIDE__DIV;
		}
	}
	else
	{
		node->output=0;
	}
}
示例#15
0
void dst_divide_step(struct node_description *node)
{
	if(node->input[0])
	{
		if(node->input[2]==0)
		{
			node->output=DBL_MAX;	/* Max out but don't break */
			discrete_log("dst_divider_step() - Divide by Zero attempted.");
		}
		else
		{
			node->output=node->input[1] / node->input[2];
		}
	}
	else
	{
		node->output=0;
	}
}
示例#16
0
void dss_counter_reset(struct node_description *node)
{
	struct dss_counter_context *context = node->context;

	context->clock_type = (int)DSS_COUNTER__CLOCK_TYPE;
	if (context->clock_type == DISC_COUNTER_IS_7492)
	{
		context->clock_type = DISC_CLK_ON_F_EDGE;
		context->is_7492 = 1;
	}
	else
		context->is_7492 = 0;
	if ((context->clock_type < DISC_CLK_ON_F_EDGE) || (context->clock_type > DISC_CLK_IS_FREQ))
		discrete_log("Invalid clock type passed in NODE_%d\n", node->node - NODE_START);
	context->last = 0;
	if (context->clock_type == DISC_CLK_IS_FREQ) context->t_clock = 1.0 / DSS_COUNTER__CLOCK;
	context->t_left = 0;
	context->count = DSS_COUNTER__INIT; /* count starts at reset value */
	node->output = DSS_COUNTER__INIT;
}
示例#17
0
void dst_multiplex_step(node_description *node)
{
	struct dst_size_context *context = node->context;
	int addr;

	if(DST_MULTIPLEX__ENABLE)
	{
		addr = DST_MULTIPLEX__ADDR;	// FP to INT
		if ((addr >= 0)  && (addr < context->size))
		{
			node->output = DST_MULTIPLEX__INP(addr);
		}
		else
		{
			/* Bad address.  We will leave the output alone. */
			discrete_log("NODE_%02d - Address = %d. Out of bounds\n",node->node-NODE_00, addr);
		}
	}
	else
	{
		node->output=0;
	}
}
示例#18
0
void dst_samphold_step(node_description *node)
{
	struct dst_samphold_context *context = node->context;

	if(DST_SAMPHOLD__ENABLE)
	{
		switch(context->clocktype)
		{
			case DISC_SAMPHOLD_REDGE:
				/* Clock the whole time the input is rising */
				if(DST_SAMPHOLD__CLOCK > context->lastinput) node->output=DST_SAMPHOLD__IN0;
				break;
			case DISC_SAMPHOLD_FEDGE:
				/* Clock the whole time the input is falling */
				if(DST_SAMPHOLD__CLOCK < context->lastinput) node->output=DST_SAMPHOLD__IN0;
				break;
			case DISC_SAMPHOLD_HLATCH:
				/* Output follows input if clock != 0 */
				if(DST_SAMPHOLD__CLOCK) node->output=DST_SAMPHOLD__IN0;
				break;
			case DISC_SAMPHOLD_LLATCH:
				/* Output follows input if clock == 0 */
				if(DST_SAMPHOLD__CLOCK==0) node->output=DST_SAMPHOLD__IN0;
				break;
			default:
				discrete_log("dst_samphold_step - Invalid clocktype passed");
				break;
		}
	}
	else
	{
		node->output=0;
	}
	/* Save the last value */
	context->lastinput=DST_SAMPHOLD__CLOCK;
}
示例#19
0
void dst_transform_step(node_description *node)
{
	if(DST_TRANSFORM__ENABLE)
	{
		double trans_stack[MAX_TRANS_STACK];
		double result,number1,number2;
		int	trans_stack_ptr=0;

		const char *fPTR = node->custom;
		node->output=0;

		while(*fPTR!=0)
		{
			switch (*fPTR++)
			{
				case '*':
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=number1*number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '/':
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=number1/number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '+':
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=number1+number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '-':
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=number1-number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '0':
					dst_transform_push(trans_stack,&trans_stack_ptr,DST_TRANSFORM__IN0);
					break;
				case '1':
					dst_transform_push(trans_stack,&trans_stack_ptr,DST_TRANSFORM__IN1);
					break;
				case '2':
					dst_transform_push(trans_stack,&trans_stack_ptr,DST_TRANSFORM__IN2);
					break;
				case '3':
					dst_transform_push(trans_stack,&trans_stack_ptr,DST_TRANSFORM__IN3);
					break;
				case '4':
					dst_transform_push(trans_stack,&trans_stack_ptr,DST_TRANSFORM__IN4);
					break;
				case 'P':
					result=dst_transform_pop(trans_stack,&trans_stack_ptr);
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case 'i':	// * -1
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=-number1;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '!':	// Logical NOT of Last Value
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=!number1;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '=':	// Logical =
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=(int)number1 == (int)number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '>':	// Logical >
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=number1 > number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '<':	// Logical <
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=number1 < number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '&':	// Bitwise AND
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=(int)number1 & (int)number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '|':	// Bitwise OR
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=(int)number1 | (int)number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				case '^':	// Bitwise XOR
					number2=dst_transform_pop(trans_stack,&trans_stack_ptr);
					number1=dst_transform_pop(trans_stack,&trans_stack_ptr);
					result=(int)number1 ^ (int)number2;
					dst_transform_push(trans_stack,&trans_stack_ptr,result);
					break;
				default:
					discrete_log("dst_transform_step - Invalid function type/variable passed");
					node->output = 0;
					break;
			}
		}
		node->output=dst_transform_pop(trans_stack,&trans_stack_ptr);
	}
	else
	{
		node->output=0;
	}
}
示例#20
0
int main(int argc, char **argv)
{
   int num_degrees, angle;
   FILE *headerfile, *tablefile;
   double radians;
   fix result;
   char tempbuf[512], *dir;
   int viewer_distance, maxx;

   if (argc != 2)
      usage();

   dir = argv[1];

   num_degrees = NUMDEGREES;
   maxx = MAXX;
   viewer_distance = VIEWER_DISTANCE;

   /* First spew the header file */
   sprintf(tempbuf, "%s\\%s", dir, header_file);
   headerfile = fopen(tempbuf, "wt");

   if (headerfile == NULL)
      file_error();

   fprintf(headerfile, "/*\n");
   fprintf(headerfile, " * %s: Header file for trig tables.\n", header_file);
   fprintf(headerfile, " * This file was automatically generated by %s.\n", progname);
   fprintf(headerfile, " */\n\n");
   fprintf(headerfile, "#ifndef _TRIG_H\n");
   fprintf(headerfile, "#define _TRIG_H\n\n");
   fprintf(headerfile, "#define NUMDEGREES %d\n", num_degrees);
   fprintf(headerfile, "#define LOG_NUMDEGREES %d\n", discrete_log(num_degrees));
   fprintf(headerfile, "#define COS(x) (cos_table[x & (NUMDEGREES - 1)])\n");
   fprintf(headerfile, "#define SIN(x) (sin_table[x & (NUMDEGREES - 1)])\n");
//   fprintf(headerfile, "#define TAN(x) (tan_table[x & (NUMDEGREES - 1)])\n");
//   fprintf(headerfile, "#define COT(x) (cot_table[x & (NUMDEGREES - 1)])\n");
   fprintf(headerfile, "\n");
   fprintf(headerfile, "extern long cos_table[NUMDEGREES];\n");
   fprintf(headerfile, "extern long sin_table[NUMDEGREES];\n");
//   fprintf(headerfile, "extern long tan_table[NUMDEGREES];\n");
//   fprintf(headerfile, "extern long cot_table[NUMDEGREES];\n");
//   fprintf(headerfile, "extern long atan_table[%d];\n", maxx);
   fprintf(headerfile, "\n#endif /* ifndef _TRIG_H */\n");

   fclose(headerfile);

   /* Now write out the tables themselves */
   sprintf(tempbuf, "%s\\%s", dir, table_file);
   tablefile = fopen(tempbuf, "wt");

   if (tablefile == NULL)
      file_error();

   fprintf(tablefile, "/*\n");
   fprintf(tablefile, " * %s: Trig tables.\n", table_file);
   fprintf(tablefile, " * This file was automatically generated by %s.\n", progname);
   fprintf(tablefile, " */\n");
   fprintf(tablefile, "#include \"client.h\"\n\n");

   /* cosine table */
   fprintf(tablefile, "long cos_table[%d] = {\n", num_degrees);

   for (angle = 0; angle < num_degrees; angle++)
   {
      radians = (double) angle * PITWICE / num_degrees;

      result = FloatToFix(cos(radians));
      
      fprintf(tablefile, "0x%8.8x, ", result);

      if (angle % 4 == 3)
	 fprintf(tablefile, "\n");
   }

   fprintf(tablefile, "\n};\n\n");


   /* sine table */
   fprintf(tablefile, "long sin_table[%d] = {\n", num_degrees);

   for (angle = 0; angle < num_degrees; angle++)
   {
      radians = (double) angle * PITWICE / num_degrees;

      result = FloatToFix(sin(radians));
      
      fprintf(tablefile, "0x%8.8x, ", result);

      if (angle % 4 == 3)
	 fprintf(tablefile, "\n");
   }

   fprintf(tablefile, "\n};\n\n");

// Tangent and cotangent tables no longer needed 9/95 ARK
// Arctangent table no longer needed 12/95 ARK
#if 0
   /* tangent table */
   fprintf(tablefile, "long tan_table[%d] = {\n", num_degrees);

   for (angle = 0; angle < num_degrees; angle++)
   {
      radians = (double) angle * PITWICE / num_degrees;

      /* Watch out for pi/2 and -pi/2 */
      if (angle == num_degrees / 4)
	 result = BIGFIXINT;
      else if (angle == num_degrees / 4 * 3)
	 result = -BIGFIXINT;
      else result = FloatToFix(tan(radians));

      if (result > BIGFIXINT)
	 result = BIGFIXINT;
      if (result < -BIGFIXINT)
	 result = -BIGFIXINT;

      fprintf(tablefile, "0x%8.8x, ", result);

      if (angle % 4 == 3)
	 fprintf(tablefile, "\n");
   }

   fprintf(tablefile, "\n};\n\n");

   /* cotangent table */
   fprintf(tablefile, "long cot_table[%d] = {\n", num_degrees);

   for (angle = 0; angle < num_degrees; angle++)
   {
      radians = (double) angle * PITWICE / num_degrees;

      /* Watch out for 0 and pi */
      if (angle == 0)
	 result = BIGFIXINT;
      else if (angle == num_degrees / 2)
	 result = BIGFIXINT;
      else result = FloatToFix(1.0 / tan(radians));

      if (result > BIGFIXINT)
	 result = BIGFIXINT;
      if (result < -BIGFIXINT)
	 result = -BIGFIXINT;
      
      fprintf(tablefile, "0x%8.8x, ", result);

      if (angle % 4 == 3)
	 fprintf(tablefile, "\n");
   }

   fprintf(tablefile, "\n};\n\n");

   /* Arctangent table */
   fprintf(tablefile, "long atan_table[%d] = {\n", maxx);

   for (i = 0; i < maxx; i++)
   {
      radians = atan(((double)(i - maxx / 2)) / viewer_distance);
      /* Convert radians to pseudodegrees */
      result = (long) ((radians * num_degrees) / PITWICE);
      if (result < 0)
	 result += num_degrees;

      fprintf(tablefile, "%4d, ", result);
      if (i % 8 == 7)
	 fprintf(tablefile, "\n");
   }
   fprintf(tablefile, "\n};\n\n");

   fclose(tablefile);
#endif

   return 0;
}
示例#21
0
void dst_mixer_reset(struct node_description *node)
{
	const struct discrete_mixer_desc *info = node->custom;
	struct dst_mixer_context *context = node->context;

	int	bit;
	double	rTemp = 0;

	/*
	 * THERE IS NO ERROR CHECKING!!!!!!!!!
	 * If you are an idiot and pass a bad ladder table
	 * then you deserve a crash.
	 */

	context->type = ((info->type == DISC_MIXER_IS_OP_AMP) && info->rI) ? DISC_MIXER_IS_OP_AMP_WITH_RI : info->type;

	/*
	 * Calculate the total of all resistors in parallel.
	 * This is the combined resistance of the voltage sources.
	 * Also calculate the exponents while we are here.
	 */
	context->rTotal = 0;
	for(bit=0; bit < info->mixerLength; bit++)
	{
		if (info->rNode[bit])
		{
			context->type = context->type | DISC_MIXER_HAS_R_NODE;
			context->rNode[bit] = discrete_find_node(info->rNode[bit]);	// get node pointers
		}
		else
			context->rNode[bit] = NULL;

		if ((info->r[bit] != 0) && !info->rNode[bit] )
		{
			context->rTotal += 1.0 / info->r[bit];
		}

		context->vCap[bit] = 0;
		context->exponent_rc[bit] = 0;
		if ((info->c[bit] != 0)  && !info->rNode[bit])
		{
			switch (context->type)
			{
				case DISC_MIXER_IS_RESISTOR:
					rTemp = 1.0 / ((1.0 / info->r[bit]) + (1.0 / info->rF));
					break;
				case DISC_MIXER_IS_OP_AMP:
					rTemp = info->r[bit];
					break;
				case DISC_MIXER_IS_OP_AMP_WITH_RI:
					rTemp = info->r[bit] + info->rI;
					break;
			}
			/* Setup filter constants */
			context->exponent_rc[bit] = -1.0 / (rTemp * info->c[bit]  * Machine->sample_rate);
			context->exponent_rc[bit] = 1.0 - exp(context->exponent_rc[bit]);
		}
	}

	if (info->rF == 0)
	{
		/* You must have an rF */
		discrete_log("dst_mixer_reset - rF can't equal 0");
	}
	if (info->type == DISC_MIXER_IS_RESISTOR) context->rTotal += 1.0 / info->rF;
	if (context->type == DISC_MIXER_IS_OP_AMP_WITH_RI) context->rTotal += 1.0 / info->rI;

	context->vCapF = 0;
	context->exponent_cF = 0;
	if (info->cF != 0)
	{
		/* Setup filter constants */
		context->exponent_cF = -1.0 / (((info->type == DISC_MIXER_IS_OP_AMP) ? info->rF : (1.0 / context->rTotal))* info->cF  * Machine->sample_rate);
		context->exponent_cF = 1.0 - exp(context->exponent_cF);
	}

	context->vCapAmp = 0;
	context->exponent_cAmp = 0;
	if (info->cAmp != 0)
	{
		/* Setup filter constants */
		/* We will use 100000 ohms as an average final stage impedance. */
		/* Your amp/speaker system will have more effect on incorrect filtering then any value used here. */
		context->exponent_cAmp = -1.0 / (100000 * info->cAmp  * Machine->sample_rate);
		context->exponent_cAmp = 1.0 - exp(context->exponent_cAmp);
	}

	if ((context->type & DISC_MIXER_TYPE_MASK) == DISC_MIXER_IS_OP_AMP_WITH_RI) context->gain = info->rF / info->rI;

	node->output = 0;
}
示例#22
0
int discrete_sh_start (const struct MachineSound *msound)
{
	struct discrete_sound_block *intf;
	int loop=0,loop2=0,search=0,failed=0;
	int vol[2];
	const char *stereo_names[2] = { "Discrete Left", "Discrete Right" };
	vol[0] = MIXER(100,MIXER_PAN_LEFT);
	vol[1] = MIXER(100,MIXER_PAN_RIGHT);

	/* Initialise */
	intf=msound->sound_interface;
	node_count=0;

	/* Sanity check and node count */
	discrete_log("discrete_sh_start() - Doing node list sanity check");
	while(1)
	{
		/* Check the node parameter is a valid node */
		if(intf[node_count].node<NODE_START || intf[node_count].node>NODE_END)
		{
			logerror("discrete_sh_start() - Invalid node number on node %02d descriptor\n",node_count);
			return 1;
		}
		if(intf[node_count].type>DSO_OUTPUT)
		{
			logerror("discrete_sh_start() - Invalid function type on node %02d descriptor\n",node_count);
			return 1;
		}

		/* Node count must include the NULL node as well */
		if(intf[node_count].type==DSS_NULL)
		{
			node_count++;
			break;
		}

		node_count++;

		/* Sanity check */
		if(node_count>255)
		{
			logerror("discrete_sh_start() - Upper limit of 255 nodes exceeded, have you terminated the interface block.");
			return 1;
		}
	}
	discrete_log("discrete_sh_start() - Sanity check counted %d nodes", node_count);

	/* Allocate memory for the context array and the node execution order array */
	if((running_order=malloc(node_count*sizeof(struct node_description*)))==NULL)
	{
		logerror("discrete_sh_start() - Failed to allocate running order array.\n");
		return 1;
	}
	else
	{
		/* Initialise memory */
		memset(running_order,0,node_count*sizeof(struct node_description*));
	}

	if((node_list=malloc(node_count*sizeof(struct node_description)))==NULL)
	{
		logerror("discrete_sh_start() - Failed to allocate context list array.\n");
		return 1;
	}
	else
	{
		/* Initialise memory */
		memset(node_list,0,node_count*sizeof(struct node_description));
	}
	discrete_log("discrete_sh_start() - Malloc completed", node_count);

	/* Work out the execution order */
	/* FAKE IT FOR THE MOMENT, EXECUTE IN ORDER */
	for(loop=0;loop<node_count;loop++)
	{
		running_order[loop]=&node_list[loop];
	}
	discrete_log("discrete_sh_start() - Running order sort completed", node_count);

	/* Configure the input node pointers, the find_node function wont work without the node ID setup beforehand */
	for(loop=0;loop<node_count;loop++) node_list[loop].node=intf[loop].node;
	failed=0;

	/* Duplicate node number test */
	for(loop=0;loop<node_count;loop++)
	{
		for(loop2=0;loop2<node_count;loop2++)
		{
			if(node_list[loop].node==node_list[loop2].node && loop!=loop2)
			{
				logerror("discrete_sh_start - Node NODE_%02d defined more than once\n",node_list[loop].node-NODE_00);
				failed=1;
			}
		}
	}

	/* Initialise and start all of the objects */
	for(loop=0;loop<node_count;loop++)
	{
		/* Configure the input node pointers */
		node_list[loop].node=intf[loop].node;
		node_list[loop].output=0;
		node_list[loop].input0=intf[loop].initial0;
		node_list[loop].input1=intf[loop].initial1;
		node_list[loop].input2=intf[loop].initial2;
		node_list[loop].input3=intf[loop].initial3;
		node_list[loop].input4=intf[loop].initial4;
		node_list[loop].input5=intf[loop].initial5;
		node_list[loop].input_node0=find_node(intf[loop].input_node0);
		node_list[loop].input_node1=find_node(intf[loop].input_node1);
		node_list[loop].input_node2=find_node(intf[loop].input_node2);
		node_list[loop].input_node3=find_node(intf[loop].input_node3);
		node_list[loop].input_node4=find_node(intf[loop].input_node4);
		node_list[loop].input_node5=find_node(intf[loop].input_node5);

		/* Check that all referenced nodes have actually been found */
		if(node_list[loop].input_node0==NULL && intf[loop].input_node0>=NODE_START && intf[loop].input_node0<=NODE_END)
		{
			logerror("discrete_sh_start - Node NODE_%02d referenced a non existant node NODE_%02d\n",node_list[loop].node-NODE_00,intf[loop].input_node0-NODE_00);
			failed=1;
		}
		if(node_list[loop].input_node1==NULL && intf[loop].input_node1>=NODE_START && intf[loop].input_node1<=NODE_END)
		{
			logerror("discrete_sh_start - Node NODE_%02d referenced a non existant node NODE_%02d\n",node_list[loop].node-NODE_00,intf[loop].input_node1-NODE_00);
			failed=1;
		}
		if(node_list[loop].input_node2==NULL && intf[loop].input_node2>=NODE_START && intf[loop].input_node2<=NODE_END)
		{
			logerror("discrete_sh_start - Node NODE_%02d referenced a non existant node NODE_%02d\n",node_list[loop].node-NODE_00,intf[loop].input_node2-NODE_00);
			failed=1;
		}
		if(node_list[loop].input_node3==NULL && intf[loop].input_node3>=NODE_START && intf[loop].input_node3<=NODE_END)
		{
			logerror("discrete_sh_start - Node NODE_%02d referenced a non existant node NODE_%02d\n",node_list[loop].node-NODE_00,intf[loop].input_node3-NODE_00);
			failed=1;
		}
		if(node_list[loop].input_node4==NULL && intf[loop].input_node4>=NODE_START && intf[loop].input_node4<=NODE_END)
		{
			logerror("discrete_sh_start - Node NODE_%02d referenced a non existant node NODE_%02d\n",node_list[loop].node-NODE_00,intf[loop].input_node4-NODE_00);
			failed=1;
		}
		if(node_list[loop].input_node5==NULL && intf[loop].input_node5>=NODE_START && intf[loop].input_node5<=NODE_END)
		{
			logerror("discrete_sh_start - Node NODE_%02d referenced a non existant node NODE_%02d\n",node_list[loop].node-NODE_00,intf[loop].input_node5-NODE_00);
			failed=1;
		}

		/* Try to find the simulation module in the module list table */
		search=0;
		while(1)
		{
			if(module_list[search].type==intf[loop].type)
			{
				node_list[loop].module=search;
				discrete_log("discrete_sh_start() - Calling init for %s",module_list[search].name);
				if(module_list[search].init)
					if(((*module_list[search].init)(&node_list[loop]))==1) failed=1;
				break;
			}
			else if(module_list[search].type==DSS_NULL)
			{
				if(intf[loop].type==DSS_NULL) break;
				else
				{
					logerror("discrete_sh_start() - Invalid DSS/DST/DSO module type specified in interface, item %02d\n",loop+1);
					failed=1;
					break;
				}
			}
			search++;
		}
	}
	/* Setup the output node */
	if((output_node=find_node(NODE_OP))==NULL)
	{
		logerror("discrete_sh_start() - Counldnt find an output node");
		failed=1;
	}

	discrete_log("discrete_sh_start() - Nodes initialised", node_count);

	/* Initialise a stereo, stream, we always use stereo even if only a mono system */
	discrete_stream=stream_init_multi(2,stereo_names,vol,Machine->sample_rate,0,discrete_stream_update);
	discrete_log("discrete_sh_start() - Audio Stream Initialised", node_count);

	/* Report success or fail */
	if(!failed) init_ok=1;
	return failed;
}
示例#23
0
文件: discrete.c 项目: mp-lee/pinmame
int discrete_sh_start (const struct MachineSound *msound)
{
	struct discrete_sound_block *intf;
	int loop=0,loop2=0,search=0,failed=0;

#ifdef DISCRETE_WAVELOG
	wav_file = wav_open("discrete.wav", Machine->sample_rate, ((Machine->drv->sound_attributes&SOUND_SUPPORTS_STEREO) == SOUND_SUPPORTS_STEREO) ? 2: 1);
#endif
#ifdef DISCRETE_DEBUGLOG
	if(!disclogfile) disclogfile=fopen("discrete.log", "w");
#endif

	/* Initialise */
	intf=msound->sound_interface;
	node_count=0;

	/* Sanity check and node count */
	discrete_log("discrete_sh_start() - Doing node list sanity check");
	while(1)
	{
		/* Check the node parameter is a valid node */
		if(intf[node_count].node<NODE_START || intf[node_count].node>NODE_END)
		{
			logerror("discrete_sh_start() - Invalid node number on node %02d descriptor\n",node_count);
			return 1;
		}
		if(intf[node_count].type>DSO_OUTPUT)
		{
			logerror("discrete_sh_start() - Invalid function type on node %02d descriptor\n",node_count);
			return 1;
		}

		/* Node count must include the NULL node as well */
		if(intf[node_count].type==DSS_NULL)
		{
			node_count++;
			break;
		}

		node_count++;

		/* Sanity check */
		if(node_count>DISCRETE_MAX_NODES)
		{
			logerror("discrete_sh_start() - Upper limit of %d nodes exceeded, have you terminated the interface block.",DISCRETE_MAX_NODES);
			return 1;
		}
	}
	discrete_log("discrete_sh_start() - Sanity check counted %d nodes", node_count);

	/* Allocate memory for the context array and the node execution order array */
	if((running_order=malloc(node_count*sizeof(struct node_description*)))==NULL)
	{
		logerror("discrete_sh_start() - Failed to allocate running order array.\n");
		return 1;
	}
	else
	{
		/* Initialise memory */
		memset(running_order,0,node_count*sizeof(struct node_description*));
	}

	if((node_list=malloc(node_count*sizeof(struct node_description)))==NULL)
	{
		logerror("discrete_sh_start() - Failed to allocate context list array.\n");
		return 1;
	}
	else
	{
		/* Initialise memory */
		memset(node_list,0,node_count*sizeof(struct node_description));

		/* Initialise structs */
		for(loop=0;loop<node_count;loop++)
		{
			for(loop2=0;loop2<DISCRETE_MAX_INPUTS;loop2++)
			{
				node_list[loop].input[loop2]=0.0;
				node_list[loop].input_node[loop2]=NULL;
			}
		}


	}
	discrete_log("discrete_sh_start() - Malloc completed", node_count);

	/* Work out the execution order */
	/* FAKE IT FOR THE MOMENT, EXECUTE IN ORDER */
	for(loop=0;loop<node_count;loop++)
	{
		running_order[loop]=&node_list[loop];
	}
	discrete_log("discrete_sh_start() - Running order sort completed", node_count);

	/* Configure the input node pointers, the find_node function wont work without the node ID setup beforehand */
	for(loop=0;loop<node_count;loop++) node_list[loop].node=intf[loop].node;
	failed=0;

	/* Duplicate node number test */
	for(loop=0;loop<node_count;loop++)
	{
		for(loop2=0;loop2<node_count;loop2++)
		{
			if(node_list[loop].node==node_list[loop2].node && loop!=loop2)
			{
				logerror("discrete_sh_start - Node NODE_%02d defined more than once\n",node_list[loop].node-NODE_00);
				failed=1;
			}
		}
	}

	/* Initialise and start all of the objects */
	for(loop=0;loop<node_count;loop++)
	{
		/* Configure the input node pointers */
		node_list[loop].node=intf[loop].node;
		node_list[loop].output=0;
		node_list[loop].active_inputs=intf[loop].active_inputs;
		for(loop2=0;loop2<intf[loop].active_inputs;loop2++)
		{
			node_list[loop].input[loop2]=intf[loop].initial[loop2];
			node_list[loop].input_node[loop2]=find_node(intf[loop].input_node[loop2]);
		}
		node_list[loop].name=intf[loop].name;
		node_list[loop].custom=intf[loop].custom;

		/* Check that all referenced nodes have actually been found */
		for(loop2=0;loop2<intf[loop].active_inputs;loop2++)
		{
			if(node_list[loop].input_node[loop2]==NULL && intf[loop].input_node[loop2]>=NODE_START && intf[loop].input_node[loop2]<=NODE_END)
			{
				logerror("discrete_sh_start - Node NODE_%02d referenced a non existant node NODE_%02d\n",node_list[loop].node-NODE_00,intf[loop].input_node[loop2]-NODE_00);
				failed=1;
			}
		}

		/* Try to find the simulation module in the module list table */
		search=0;
		while(1)
		{
			if(module_list[search].type==intf[loop].type)
			{
				node_list[loop].module=search;
				discrete_log("discrete_sh_start() - Calling init for %s",module_list[search].name);
				if(module_list[search].init)
					if(((*module_list[search].init)(&node_list[loop]))==1) failed=1;
				break;
			}
			else if(module_list[search].type==DSS_NULL)
			{
				if(intf[loop].type==DSS_NULL) break;
				else
				{
					logerror("discrete_sh_start() - Invalid DSS/DST/DSO module type specified in interface, item %02d\n",loop+1);
					failed=1;
					break;
				}
			}
			search++;
		}
	}
	/* Setup the output node */
	if((output_node=find_node(NODE_OP))==NULL)
	{
		logerror("discrete_sh_start() - Couldn't find an output node");
		failed=1;
	}

	discrete_log("discrete_sh_start() - Nodes initialised", node_count);

	/* Different setup for Mono/Stereo systems */
	if ((Machine->drv->sound_attributes&SOUND_SUPPORTS_STEREO) == SOUND_SUPPORTS_STEREO)
	{
		int vol[2];
		const char *stereo_names[2] = { "Discrete Left", "Discrete Right" };
		vol[0] = MIXER((int)output_node->input[2],MIXER_PAN_LEFT);
		vol[1] = MIXER((int)output_node->input[2],MIXER_PAN_RIGHT);
		/* Initialise a stereo, stream, we always use stereo even if only a mono system */
		discrete_stream=stream_init_multi(2,stereo_names,vol,Machine->sample_rate,0,discrete_stream_update_stereo);
		discrete_log("discrete_sh_start() - Stereo Audio Stream Initialised", node_count);
		discrete_stereo=1;
	}
	else
	{
		int vol = (int)output_node->input[2];
		/* Initialise a stereo, stream, we always use stereo even if only a mono system */
		discrete_stream=stream_init("Discrete Sound",vol,Machine->sample_rate,0,discrete_stream_update_mono);
		discrete_log("discrete_sh_start() - Mono Audio Stream Initialised", node_count);
	}

	if(discrete_stream==-1)
	{
		logerror("discrete_sh_start - Stream init returned an error\n");
		failed=1;
	}

	/* Report success or fail */
	if(!failed) init_ok=1;

	/* Now reset the system to a sensible state */
	discrete_sh_reset();
	discrete_log("discrete_sh_start() - Nodes reset", node_count);

	return failed;
}