// license:BSD-3-Clause // copyright-holders:Derrick Renaud /************************************************************************* audio\atarifb.c *************************************************************************/ #include "emu.h" #include "includes/atarifb.h" #include "sound/discrete.h" /************************************************************************/ /* atarifb Sound System Analog emulation */ /* */ /* Complete re-write Dec 2004, D. Renaud */ /************************************************************************/ static const discrete_555_desc atarifbWhistl555 = { DISC_555_OUT_CAP | DISC_555_OUT_DC, 5, // B+ voltage of 555 DEFAULT_555_VALUES }; static const discrete_lfsr_desc atarifb_lfsr = { DISC_CLK_IS_FREQ, 16, /* Bit Length */ 0, /* Reset Value */ 0, /* Use Bit 0 as XOR input 0 */ 14, /* Use Bit 14 as XOR input 1 */ DISC_LFSR_XNOR, /* Feedback stage1 is XNOR */ DISC_LFSR_OR, /* Feedback stage2 is just stage 1 output OR with external feed */ DISC_LFSR_REPLACE, /* Feedback stage3 replaces the shifted register contents */ 0x000001, /* Everything is shifted into the first bit only */ 0, /* Output is already inverted by XNOR */ 16 /* Output bit is feedback bit */ }; static const discrete_dac_r1_ladder atarifb_crowd_r1_ladder = { 4, {RES_K(390), RES_K(220), RES_K(100), RES_K(56)}, // r17, r16, r14, r15 0, 0, // no bias 0, // no rGnd CAP_U(0.1) // c32 }; static const discrete_op_amp_filt_info atarifb_crowd_filt = { 1.0/(1.0/RES_K(390) + 1.0/RES_K(220) + 1.0/RES_K(100) + 1.0/RES_K(56)), // r17, r16, r14, r15 0, 0, 0, RES_K(330), // r35 CAP_U(.01), // c33 CAP_U(.01), // c44 0, 5, 12, 0 }; static const discrete_mixer_desc atarifb_mixer = { DISC_MIXER_IS_OP_AMP, {RES_K(47), RES_K(47), RES_K(220)}, // r71, r70, r73 {0}, // no rNodes {CAP_U(.01), CAP_U(.01), CAP_U(.01)}, // c53, c52, c51 0, RES_K(47), // r74 CAP_U(.001), // c54 CAP_U(0.1), // c57 5, 40000 }; /* Nodes - Sounds */ #define ATARIFB_NOISE NODE_10 #define ATARIFB_HIT_SND ATARIFB_HIT_EN #define ATARIFB_WHISTLE_SND NODE_12 #define ATARIFB_CROWD_SND NODE_13 DISCRETE_SOUND_START(atarifb_discrete) /************************************************/ /* Input register mapping for atarifb */ /************************************************/ /* NODE GAIN OFFSET INIT */ DISCRETE_INPUT_LOGIC (ATARIFB_WHISTLE_EN) DISCRETE_INPUT_DATA (ATARIFB_CROWD_DATA) /* Hit is a trigger fed directly to the amp */ DISCRETE_INPUTX_LOGIC(ATARIFB_HIT_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0.0) DISCRETE_INPUT_NOT (ATARIFB_ATTRACT_EN) DISCRETE_INPUT_LOGIC (ATARIFB_NOISE_EN) /************************************************/ /* Crowd effect is variable amplitude, filtered */ /* random noise. */ /* LFSR clk = 256H = 15750.0Hz */ /************************************************/ DISCRETE_LFSR_NOISE(NODE_20, ATARIFB_NOISE_EN, ATARIFB_NOISE_EN, 15750.0, 1, 0, .5, &atarifb_lfsr) DISCRETE_SWITCH(NODE_21, 1, NODE_20, 0, ATARIFB_CROWD_DATA) // enable data, gate D8 DISCRETE_DAC_R1(NODE_22, NODE_21, DEFAULT_TTL_V_LOGIC_1, &atarifb_crowd_r1_ladder) DISCRETE_OP_AMP_FILTER(ATARIFB_CROWD_SND, 1, NODE_22, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &atarifb_crowd_filt) /************************************************/ /* Whistle effect is a triggered 555 cap charge */ /* Q10 is a buffer to make sure there is no */ /* load on the cap. It shifts the voltage by */ /* -0.5V */ /************************************************/ DISCRETE_555_ASTABLE(NODE_30, ATARIFB_WHISTLE_EN, RES_K(2.2), RES_K(2.2), CAP_U(0.1), // r34, r33, c44 &atarifbWhistl555) DISCRETE_TRANSFORM3(ATARIFB_WHISTLE_SND, NODE_30, .5, 0, "01-P2>*") // Q10 drop /************************************************/ /* Mixing stage - A9 */ /* We will diliberately drive the amp into */ /* clipping. */ /* This is what the original game did. */ /************************************************/ DISCRETE_MIXER3(NODE_90, ATARIFB_ATTRACT_EN, ATARIFB_HIT_SND, ATARIFB_WHISTLE_SND, ATARIFB_CROWD_SND, &atarifb_mixer) DISCRETE_OUTPUT(NODE_90, 1) DISCRETE_SOUND_END /************************************************************************/ /* abaseb Sound System Analog emulation */ /* */ /* Complete re-write Dec 2004, D. Renaud */ /************************************************************************/ static const discrete_dac_r1_ladder abaseb_crowd_r1_ladder = { 4, {RES_K(390), RES_K(220), RES_K(100), RES_K(56)}, // r17, r16, r14, r15 0, 0, // no bias RES_K(1), // r76 0 // no filter }; static const discrete_op_amp_filt_info abaseb_crowd_filt = { 1.0/(1.0/RES_K(390) + 1.0/RES_K(220) + 1.0/RES_K(100) + 1.0/RES_K(56) + 1.0/RES_K(1)), // r17, r16, r14, r15, r76 0, 0, 0, RES_K(470), // r35 CAP_U(.01), // c33 CAP_U(.022), // c44 0, 5, 12, 0 }; static const discrete_mixer_desc abaseb_mixer = { DISC_MIXER_IS_OP_AMP, {RES_K(330), RES_K(220), RES_K(220)}, // r71, r70, r73 {0}, // no rNodes {CAP_U(.01), CAP_U(.01), CAP_U(.01)}, // c53, c52, c51 0, RES_K(47), // r74 CAP_U(.001), // c54 CAP_U(10), // c69 5, 25000 }; /* Nodes - Sounds */ #define ABASEB_NOISE NODE_10 #define ABASEB_HIT_SND ATARIFB_HIT_EN #define ABASEB_WHISTLE_SND NODE_12 #define ABASEB_CROWD_SND NODE_13 DISCRETE_SOUND_START(abaseb_discrete) /************************************************/ /* Input register mapping for abaseb */ /************************************************/ /* NODE GAIN OFFSET INIT */ DISCRETE_INPUT_LOGIC (ATARIFB_WHISTLE_EN) DISCRETE_INPUT_DATA (ATARIFB_CROWD_DATA) /* Hit is a trigger fed directly to the amp */ DISCRETE_INPUTX_LOGIC(ATARIFB_HIT_EN, DEFAULT_TTL_V_LOGIC_1, 0, 0.0) DISCRETE_INPUT_NOT (ATARIFB_ATTRACT_EN) DISCRETE_INPUT_LOGIC (ATARIFB_NOISE_EN) /************************************************/ /* Crowd effect is variable amplitude, filtered */ /* random noise. */ /* LFSR clk = 256H = 15750.0Hz */ /************************************************/ DISCRETE_LFSR_NOISE(NODE_20, ATARIFB_NOISE_EN, ATARIFB_NOISE_EN, 15750.0, 1, 0, .5, &atarifb_lfsr) DISCRETE_SWITCH(NODE_21, 1, NODE_20, 0, ATARIFB_CROWD_DATA) // enable data, gate D8 DISCRETE_DAC_R1(NODE_22, NODE_21, DEFAULT_TTL_V_LOGIC_1, &abaseb_crowd_r1_ladder) DISCRETE_OP_AMP_FILTER(ABASEB_CROWD_SND, 1, NODE_22, 0, DISC_OP_AMP_FILTER_IS_BAND_PASS_1M, &abaseb_crowd_filt) /************************************************/ /* Whistle effect is a triggered 555 cap charge */ /* Q10 is a buffer to make sure there is no */ /* load on the cap. It shifts the voltage by */ /* -0.5V */ /************************************************/ DISCRETE_555_ASTABLE(NODE_30, ATARIFB_WHISTLE_EN, RES_K(2.2), RES_K(2.2), CAP_U(0.1), // r34, r33, c44 &atarifbWhistl555) DISCRETE_TRANSFORM3(ABASEB_WHISTLE_SND, NODE_30, .5, 0, "01-P2>*") // Q10 drop /************************************************/ /* Mixing stage - A9 */ /************************************************/ DISCRETE_MIXER3(NODE_90, ATARIFB_ATTRACT_EN, ABASEB_HIT_SND, ABASEB_WHISTLE_SND, ABASEB_CROWD_SND, &abaseb_mixer) DISCRETE_OUTPUT(NODE_90, 1) DISCRETE_SOUND_END