summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/subs.cpp
blob: 7ca93c95fb5f98aa5ad28f0374b9bd5e2f919a61 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// license:BSD-3-Clause
// copyright-holders:Derrick Renaud
/*************************************************************************

    audio\subs.cpp

*************************************************************************/
#include "emu.h"
#include "includes/subs.h"
#include "sound/discrete.h"


/***************************************************************************
sub sound functions
***************************************************************************/

void subs_state::noise_reset_w(uint8_t data)
{
	/* Pulse noise reset */
	m_discrete->write(SUBS_NOISE_RESET, 0);
}


/************************************************************************/
/* subs Sound System Analog emulation                                   */
/************************************************************************/

static const discrete_lfsr_desc subs_lfsr =
{
	DISC_CLK_IS_FREQ,
	16,         /* Bit Length */
	0,          /* Reset Value */
	13,         /* Use Bit 13 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 */
	13          /* Output bit */
};

/* Nodes - Sounds */
#define SUBS_NOISE          NODE_10
#define SUBS_SONAR1_SND     NODE_11
#define SUBS_SONAR2_SND     NODE_12
#define SUBS_LAUNCH_SND     NODE_13
#define SUBS_CRASH_SND      NODE_14
#define SUBS_EXPLODE_SND    NODE_15

DISCRETE_SOUND_START(subs_discrete)
	/************************************************/
	/* subs  Effects Relataive Gain Table           */
	/*                                              */
	/* NOTE: The schematic does not show the amp    */
	/*  stage so I will assume a 5K volume control. */
	/*                                              */
	/* Effect       V-ampIn   Gain ratio  Relative  */
	/* Sonar         2.33     5/(5+2.7)     320.8   */
	/* Launch        3.8      5/(5+47)       77.5   */
	/* Crash         3.8      5/(5+22)      149.2   */
/* Explosion     10.0     5/(5+5.6)    1000.0   */
	/************************************************/

	/************************************************/
	/* Input register mapping for subs              */
	/************************************************/
	/*                   NODE              GAIN      OFFSET  INIT */
	DISCRETE_INPUTX_DATA(SUBS_SONAR1_EN,   400.0,     0,     0.0)
	DISCRETE_INPUTX_DATA(SUBS_SONAR2_EN,   400.0,     0,     0.0)
	DISCRETE_INPUTX_DATA(SUBS_LAUNCH_DATA,  77.5/15,  0,     0.0)
	DISCRETE_INPUTX_DATA(SUBS_CRASH_DATA,  149.2/15,  0,     0.0)
	DISCRETE_INPUT_NOT  (SUBS_CRASH_EN)
	DISCRETE_INPUT_NOT  (SUBS_EXPLODE_EN)
	DISCRETE_INPUT_PULSE(SUBS_NOISE_RESET, 1)

	/************************************************/
	/* Noise source                                 */
	/* LFSR clk = 256H = 15750.0Hz                  */
	/************************************************/
	DISCRETE_LFSR_NOISE(SUBS_NOISE, SUBS_NOISE_RESET, SUBS_NOISE_RESET, 15750.0, 1.0, 0, 0, &subs_lfsr)

	/************************************************/
	/* Launch is just amplitude contolled noise     */
	/************************************************/
	DISCRETE_MULTIPLY(SUBS_LAUNCH_SND, SUBS_NOISE, SUBS_LAUNCH_DATA)

	/************************************************/
	/* Crash resamples the noise at 8V and then     */
	/* controls the amplitude.                      */
	/* 8V = Hsync/2/8 = 15750/2/8                   */
	/************************************************/
	DISCRETE_SQUAREWFIX(NODE_20, 1, 15750.0/2/8, 1.0, 50, 1.0/2, 0) /* Resample freq. */
	DISCRETE_SAMPLHOLD(NODE_21, SUBS_NOISE, NODE_20, DISC_SAMPHOLD_REDGE)
	DISCRETE_MULTIPLY(NODE_22, NODE_21, SUBS_CRASH_DATA)
	DISCRETE_ONOFF(SUBS_CRASH_SND, SUBS_CRASH_EN, NODE_22)

	/************************************************/
	/* Explode filters the crash sound.             */
	/* I'm not sure of the exact filter freq.       */
	/************************************************/
	DISCRETE_TRANSFORM3(NODE_30, NODE_21, SUBS_CRASH_DATA, 1000.0 / 149.2*7.6, "01*2*")
	DISCRETE_FILTER2(SUBS_EXPLODE_SND, SUBS_EXPLODE_EN, NODE_30, 100.0, (1.0 / 7.6), DISC_FILTER_BANDPASS)

	/************************************************/
	/* Not sure how the sonar works yet.            */
	/************************************************/
	DISCRETE_RCDISC2(NODE_40, SUBS_SONAR1_EN, SUBS_SONAR1_EN, 680000.0, SUBS_SONAR1_EN, 1000.0, 1e-6)   /* Decay envelope */
	DISCRETE_ADDER2(NODE_41, 1, NODE_40, 800)
	DISCRETE_LOGIC_AND(NODE_42, SUBS_SONAR1_EN, SUBS_NOISE)
	DISCRETE_TRIANGLEWAVE(SUBS_SONAR1_SND, NODE_42, NODE_41, 320.8, 0.0, 0)

	DISCRETE_RCDISC2(NODE_50, SUBS_SONAR2_EN, SUBS_SONAR2_EN, 18600.0, SUBS_SONAR2_EN, 20.0, 4.7e-6)    /* Decay envelope */
	DISCRETE_ADDER2(NODE_51, 1, NODE_50, 800)
	DISCRETE_LOGIC_AND(NODE_52, SUBS_SONAR2_EN, SUBS_NOISE)
	DISCRETE_TRIANGLEWAVE(SUBS_SONAR2_SND, NODE_52, NODE_51, 320.8, 0.0, 0)

	/************************************************/
	/* Combine all sound sources.                   */
	/* Add some final gain to get to a good sound   */
	/* level.                                       */
	/************************************************/

	DISCRETE_ADDER4(NODE_90, 1, 0, SUBS_LAUNCH_SND, SUBS_CRASH_SND, SUBS_EXPLODE_SND)
	DISCRETE_ADDER4(NODE_91, 1, 0, SUBS_LAUNCH_SND, SUBS_CRASH_SND, SUBS_EXPLODE_SND)

	DISCRETE_OUTPUT(NODE_90, 65534.0/(320.8+77.5+149.2+1000.0))
	DISCRETE_OUTPUT(NODE_91, 65534.0/(320.8+77.5+149.2+1000.0))
DISCRETE_SOUND_END