1 // license:BSD-3-Clause 2 // copyright-holders:Derrick Renaud 3 /************************************************************************* 4 5 audio\dragrace.c 6 7 *************************************************************************/ 8 #include "emu.h" 9 #include "includes/dragrace.h" 10 #include "sound/discrete.h" 11 12 /************************************************************************/ 13 /* dragrace Sound System Analog emulation */ 14 /************************************************************************/ 15 16 static const discrete_lfsr_desc dragrace_lfsr = 17 { 18 DISC_CLK_IS_FREQ, 19 16, /* Bit Length */ 20 0, /* Reset Value */ 21 0, /* Use Bit 0 as XOR input 0 */ 22 14, /* Use Bit 14 as XOR input 1 */ 23 DISC_LFSR_XNOR, /* Feedback stage1 is XNOR */ 24 DISC_LFSR_OR, /* Feedback stage2 is just stage 1 output OR with external feed */ 25 DISC_LFSR_REPLACE, /* Feedback stage3 replaces the shifted register contents */ 26 0x000001, /* Everything is shifted into the first bit only */ 27 0, /* Output is already inverted by XNOR */ 28 15 /* Output bit */ 29 }; 30 31 /* Nodes - Sounds */ 32 #define DRAGRACE_NOISE NODE_10 33 #define DRAGRACE_SCREECH1_SND NODE_11 34 #define DRAGRACE_SCREECH2_SND NODE_12 35 #define DRAGRACE_LOTONE_SND NODE_13 36 #define DRAGRACE_HITONE_SND NODE_14 37 #define DRAGRACE_TONE_SND NODE_15 38 #define DRAGRACE_EXPLODE1_SND NODE_16 39 #define DRAGRACE_EXPLODE2_SND NODE_17 40 #define DRAGRACE_MOTOR1_SND NODE_18 41 #define DRAGRACE_MOTOR2_SND NODE_19 42 43 DISCRETE_SOUND_START(dragrace_discrete) 44 /************************************************/ 45 /* dragrace Effects Relataive Gain Table */ 46 /* */ 47 /* Effect V-ampIn Gain ratio Relative */ 48 /* LoTone 3.8 10/32 593.8 */ 49 /* HiTone 3.8 10/32 593.8 */ 50 /* Screech 3.8 10/330 57.6 */ 51 /* Motor 3.8 10/32.67 581.6 */ 52 /* Explode 5.0 10/25 1000.0 */ 53 /************************************************/ 54 55 56 /************************************************/ 57 /* Input register mapping for dragrace */ 58 /************************************************/ 59 DISCRETE_INPUT_LOGIC(DRAGRACE_SCREECH1_EN) 60 DISCRETE_INPUT_LOGIC(DRAGRACE_SCREECH2_EN) 61 DISCRETE_INPUT_LOGIC(DRAGRACE_LOTONE_EN) 62 DISCRETE_INPUT_LOGIC(DRAGRACE_HITONE_EN) 63 DISCRETE_INPUT_LOGIC(DRAGRACE_EXPLODE1_EN) 64 DISCRETE_INPUT_LOGIC(DRAGRACE_EXPLODE2_EN) 65 DISCRETE_INPUT_DATA (DRAGRACE_MOTOR1_DATA) 66 DISCRETE_INPUT_DATA (DRAGRACE_MOTOR2_DATA) 67 DISCRETE_INPUT_LOGIC(DRAGRACE_MOTOR1_EN) 68 DISCRETE_INPUT_LOGIC(DRAGRACE_MOTOR2_EN) 69 DISCRETE_INPUT_LOGIC(DRAGRACE_KLEXPL1_EN) 70 DISCRETE_INPUT_LOGIC(DRAGRACE_KLEXPL2_EN) 71 DISCRETE_INPUT_LOGIC(DRAGRACE_ATTRACT_EN) 72 73 /************************************************/ 74 /* Motor sound circuit is based on a 556 VCO */ 75 /* with the input frequency set by the MotorSND */ 76 /* latch (4 bit). This freqency is then used to */ 77 /* driver a modulo 12 counter, with div6, 4 & 3 */ 78 /* summed as the output of the circuit. */ 79 /* VCO Output is Sq wave = 27-382Hz */ 80 /* F1 freq - (Div6) */ 81 /* F2 freq = (Div4) */ 82 /* F3 freq = (Div3) 33.3% duty, 33.3 deg phase */ 83 /* To generate the frequency we take the freq. */ 84 /* diff. and /15 to get all the steps between */ 85 /* 0 - 15. Then add the low frequency and send */ 86 /* that value to a squarewave generator. */ 87 /* Also as the frequency changes, it ramps due */ 88 /* to a 2.2uf capacitor on the R-ladder. */ 89 /* Note the VCO freq. is controlled by a 250k */ 90 /* pot. The freq. used here is for the pot set */ 91 /* to 125k. The low freq is allways the same. */ 92 /* This adjusts the high end. */ 93 /* 0k = 214Hz. 250k = 4416Hz */ 94 /* NOTE: freqs are ripped from Sprint for now. */ 95 /************************************************/ 96 DISCRETE_RCFILTER(NODE_20, DRAGRACE_MOTOR1_DATA, 119898, 2.2e-6) 97 DISCRETE_ADJUSTMENT(NODE_21, (214.0-27.0)/12/31, (4416.0-27.0)/12/31, DISC_LOGADJ, "MOTOR1") 98 DISCRETE_MULTIPLY(NODE_22, NODE_20, NODE_21) 99 100 DISCRETE_MULTADD(NODE_23, NODE_22, 2, 27.0/6) /* F1 = /12*2 = /6 */ 101 DISCRETE_SQUAREWAVE(NODE_24, 1, NODE_23, (581.6/3), 50.0, 0, 0) 102 DISCRETE_RCFILTER(NODE_25, NODE_24, 10000, 1e-7) 103 104 DISCRETE_MULTADD(NODE_26, NODE_22, 3, 27.0/4) /* F2 = /12*3 = /4 */ 105 DISCRETE_SQUAREWAVE(NODE_27, 1, NODE_26, (581.6/3), 50.0, 0, 0) 106 DISCRETE_RCFILTER(NODE_28, NODE_27, 10000, 1e-7) 107 108 DISCRETE_MULTADD(NODE_29, NODE_22, 4, 27.0/3) /* F3 = /12*4 = /3 */ 109 DISCRETE_SQUAREWAVE(NODE_30, 1, NODE_29, (581.6/3), 100.0/3, 0, 360.0/3) 110 DISCRETE_RCFILTER(NODE_31, NODE_30, 10000, 1e-7) 111 112 DISCRETE_ADDER3(DRAGRACE_MOTOR1_SND, DRAGRACE_MOTOR1_EN, NODE_25, NODE_28, NODE_31) 113 114 /************************************************/ 115 /* Car2 motor sound is basically the same as */ 116 /* Car1. But I shifted the frequencies up for */ 117 /* it to sound different from car1. */ 118 /************************************************/ 119 DISCRETE_RCFILTER(NODE_40, DRAGRACE_MOTOR2_DATA, 119898, 2.2e-6) 120 DISCRETE_ADJUSTMENT(NODE_41, (214.0-27.0)/12/31, (4416.0-27.0)/12/31, DISC_LOGADJ, "MOTOR2") 121 DISCRETE_MULTIPLY(NODE_42, NODE_40, NODE_41) 122 123 DISCRETE_MULTADD(NODE_43, NODE_42, 2, 27.0/6) /* F1 = /12*2 = /6 */ 124 DISCRETE_SQUAREWAVE(NODE_44, 1, NODE_43, (581.6/3), 50.0, 0, 0) 125 DISCRETE_RCFILTER(NODE_45, NODE_44, 10000, 1e-7) 126 127 DISCRETE_MULTADD(NODE_46, NODE_42, 3, 27.0/4) /* F2 = /12*3 = /4 */ 128 DISCRETE_SQUAREWAVE(NODE_47, 1, NODE_46, (581.6/3), 50.0, 0, 0) 129 DISCRETE_RCFILTER(NODE_48, NODE_47, 10000, 1e-7) 130 131 DISCRETE_MULTADD(NODE_49, NODE_42, 4, 27.0/3) /* F3 = /12*4 = /3 */ 132 DISCRETE_SQUAREWAVE(NODE_50, 1, NODE_49, (581.6/3), 100.0/3, 0, 360.0/3) 133 DISCRETE_RCFILTER(NODE_51, NODE_50, 10000, 1e-7) 134 135 DISCRETE_ADDER3(DRAGRACE_MOTOR2_SND, DRAGRACE_MOTOR2_EN, NODE_45, NODE_48, NODE_51) 136 137 /************************************************/ 138 /* Explosion circuit is built around a noise */ 139 /* generator built from 2 shift registers that */ 140 /* are clocked by the 1V signal. */ 141 /* 1V = HSYNC/2 */ 142 /* = 15750/2 */ 143 /* Output is integrated to apply decay. */ 144 /************************************************/ 145 DISCRETE_LFSR_NOISE(DRAGRACE_NOISE, 1, DRAGRACE_ATTRACT_EN, 15750.0/2, 1.0, 0, 0, &dragrace_lfsr) 146 147 DISCRETE_RAMP(NODE_61, DRAGRACE_EXPLODE1_EN, DRAGRACE_EXPLODE1_EN, (1000.0-0.0)/1, 1000.0, 0.0, 1000.0) 148 DISCRETE_MULTIPLY(NODE_62, DRAGRACE_NOISE, NODE_61) 149 DISCRETE_RCFILTER(NODE_63, NODE_62, 1500, 2.2e-7) 150 DISCRETE_MULTIPLY(DRAGRACE_EXPLODE1_SND, NODE_63, DRAGRACE_KLEXPL1_EN) 151 152 DISCRETE_RAMP(NODE_66, DRAGRACE_EXPLODE2_EN, DRAGRACE_EXPLODE2_EN, (1000.0-0.0)/1, 1000.0, 0.0, 1000.0) 153 DISCRETE_MULTIPLY(NODE_67, DRAGRACE_NOISE, NODE_66) 154 DISCRETE_RCFILTER(NODE_68, NODE_67, 1500, 2.2e-7) 155 DISCRETE_MULTIPLY(DRAGRACE_EXPLODE2_SND, NODE_68, DRAGRACE_KLEXPL2_EN) 156 157 /************************************************/ 158 /* Skid circuits takes the noise output from */ 159 /* the crash circuit and applies +ve feedback */ 160 /* to cause oscillation. There is also an RC */ 161 /* filter on the input to the feedback cct. */ 162 /* RC is 1K & 10uF */ 163 /* Feedback cct is modelled by using the RC out */ 164 /* as the frequency input on a VCO, */ 165 /* breadboarded freq range as: */ 166 /* 0 = 940Hz, 34% duty */ 167 /* 1 = 630Hz, 29% duty */ 168 /* the duty variance is so small we ignore it */ 169 /************************************************/ 170 DISCRETE_INVERT(NODE_70, DRAGRACE_NOISE) 171 DISCRETE_MULTADD(NODE_71, NODE_70, 940.0-630.0, ((940.0-630.0)/2)+630.0) 172 DISCRETE_RCFILTER(NODE_72, NODE_71, 1000, 1e-5) 173 DISCRETE_SQUAREWAVE(NODE_73, 1, NODE_72, 407.8, 31.5, 0, 0.0) 174 DISCRETE_ONOFF(DRAGRACE_SCREECH1_SND, DRAGRACE_SCREECH1_EN, NODE_73) 175 DISCRETE_ONOFF(DRAGRACE_SCREECH2_SND, DRAGRACE_SCREECH2_EN, NODE_73) 176 177 /************************************************/ 178 /* LoTone = 32V = 15750Hz/2/32 */ 179 /* HiTone = 4V = 15750Hz/2/4 */ 180 /************************************************/ 181 DISCRETE_SQUAREWFIX(DRAGRACE_LOTONE_SND, DRAGRACE_LOTONE_EN, 15750.0/2/32, 593.8, 50.0, 0, 0.0) 182 DISCRETE_SQUAREWFIX(DRAGRACE_HITONE_SND, DRAGRACE_HITONE_EN, 15750.0/2/4, 593.8, 50.0, 0, 0.0) 183 DISCRETE_ADDER2(DRAGRACE_TONE_SND, 1, DRAGRACE_LOTONE_SND, DRAGRACE_HITONE_SND) 184 185 /************************************************/ 186 /* Combine all 5 sound sources. */ 187 /* Add some final gain to get to a good sound */ 188 /* level. */ 189 /************************************************/ 190 DISCRETE_ADDER4(NODE_90, DRAGRACE_ATTRACT_EN, DRAGRACE_TONE_SND, DRAGRACE_MOTOR1_SND, DRAGRACE_EXPLODE1_SND, DRAGRACE_SCREECH1_SND) 191 DISCRETE_ADDER4(NODE_91, DRAGRACE_ATTRACT_EN, DRAGRACE_TONE_SND, DRAGRACE_MOTOR2_SND, DRAGRACE_EXPLODE2_SND, DRAGRACE_SCREECH2_SND) 192 193 DISCRETE_OUTPUT(NODE_90, 65534.0/(593.8+581.6+1000.0+57.6)) 194 DISCRETE_OUTPUT(NODE_91, 65534.0/(593.8+581.6+1000.0+57.6)) 195 DISCRETE_SOUND_END 196