Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/dsp/echo.cpp
2 views
1
#ifdef DSP_CPP
2
3
int DSP::calc_fir(int i, bool channel) {
4
int s = state.echo_hist[channel][state.echo_hist_pos + i + 1];
5
return (s * (int8)REG(fir + i * 0x10)) >> 6;
6
}
7
8
int DSP::echo_output(bool channel) {
9
int output = (int16)((state.t_main_out[channel] * (int8)REG(mvoll + channel * 0x10)) >> 7)
10
+ (int16)((state.t_echo_in [channel] * (int8)REG(evoll + channel * 0x10)) >> 7);
11
return sclamp<16>(output);
12
}
13
14
void DSP::echo_read(bool channel) {
15
unsigned addr = state.t_echo_ptr + channel * 2;
16
uint8 lo = smp.apuram[(uint16)(addr + 0)];
17
uint8 hi = smp.apuram[(uint16)(addr + 1)];
18
int s = (int16)((hi << 8) + lo);
19
state.echo_hist[channel].write(state.echo_hist_pos, s >> 1);
20
}
21
22
void DSP::echo_write(bool channel) {
23
if(!(state.t_echo_disabled & 0x20)) {
24
unsigned addr = state.t_echo_ptr + channel * 2;
25
int s = state.t_echo_out[channel];
26
smp.apuram[(uint16)(addr + 0)] = s;
27
smp.apuram[(uint16)(addr + 1)] = s >> 8;
28
}
29
30
state.t_echo_out[channel] = 0;
31
}
32
33
void DSP::echo_22() {
34
//history
35
state.echo_hist_pos++;
36
if(state.echo_hist_pos >= echo_hist_size) state.echo_hist_pos = 0;
37
38
state.t_echo_ptr = (uint16)((state.t_esa << 8) + state.echo_offset);
39
echo_read(0);
40
41
//FIR
42
int l = calc_fir(0, 0);
43
int r = calc_fir(0, 1);
44
45
state.t_echo_in[0] = l;
46
state.t_echo_in[1] = r;
47
}
48
49
void DSP::echo_23() {
50
int l = calc_fir(1, 0) + calc_fir(2, 0);
51
int r = calc_fir(1, 1) + calc_fir(2, 1);
52
53
state.t_echo_in[0] += l;
54
state.t_echo_in[1] += r;
55
56
echo_read(1);
57
}
58
59
void DSP::echo_24() {
60
int l = calc_fir(3, 0) + calc_fir(4, 0) + calc_fir(5, 0);
61
int r = calc_fir(3, 1) + calc_fir(4, 1) + calc_fir(5, 1);
62
63
state.t_echo_in[0] += l;
64
state.t_echo_in[1] += r;
65
}
66
67
void DSP::echo_25() {
68
int l = state.t_echo_in[0] + calc_fir(6, 0);
69
int r = state.t_echo_in[1] + calc_fir(6, 1);
70
71
l = (int16)l;
72
r = (int16)r;
73
74
l += (int16)calc_fir(7, 0);
75
r += (int16)calc_fir(7, 1);
76
77
state.t_echo_in[0] = sclamp<16>(l) & ~1;
78
state.t_echo_in[1] = sclamp<16>(r) & ~1;
79
}
80
81
void DSP::echo_26() {
82
//left output volumes
83
//(save sample for next clock so we can output both together)
84
state.t_main_out[0] = echo_output(0);
85
86
//echo feedback
87
int l = state.t_echo_out[0] + (int16)((state.t_echo_in[0] * (int8)REG(efb)) >> 7);
88
int r = state.t_echo_out[1] + (int16)((state.t_echo_in[1] * (int8)REG(efb)) >> 7);
89
90
state.t_echo_out[0] = sclamp<16>(l) & ~1;
91
state.t_echo_out[1] = sclamp<16>(r) & ~1;
92
}
93
94
void DSP::echo_27() {
95
//output
96
int outl = state.t_main_out[0];
97
int outr = echo_output(1);
98
state.t_main_out[0] = 0;
99
state.t_main_out[1] = 0;
100
101
//TODO: global muting isn't this simple
102
//(turns DAC on and off or something, causing small ~37-sample pulse when first muted)
103
if(REG(flg) & 0x40) {
104
outl = 0;
105
outr = 0;
106
}
107
108
//output sample to DAC
109
audio.sample(outl, outr);
110
}
111
112
void DSP::echo_28() {
113
state.t_echo_disabled = REG(flg);
114
}
115
116
void DSP::echo_29() {
117
state.t_esa = REG(esa);
118
119
if(!state.echo_offset) state.echo_length = (REG(edl) & 0x0f) << 11;
120
121
state.echo_offset += 4;
122
if(state.echo_offset >= state.echo_length) state.echo_offset = 0;
123
124
//write left echo
125
echo_write(0);
126
127
state.t_echo_disabled = REG(flg);
128
}
129
130
void DSP::echo_30() {
131
//write right echo
132
echo_write(1);
133
}
134
135
#endif
136
137