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; }
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); } }
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; }
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; }
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; }
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; }
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; }
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; }
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]); } }
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; }
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]); } } }
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; }
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; } }
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; } }
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; }
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; } }
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; }
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; } }
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; }
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; }
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; }
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; }