1 #include <math.h>
2 #include <stdio.h>
3 #include "fceu-types.h"
4
5 #include "sound.h"
6 #include "x6502.h"
7 #include "fceu.h"
8 #include "filter.h"
9
10 #include "fcoeffs.h"
11
12 static uint32 mrindex;
13 static uint32 mrratio;
14
SexyFilter2(int32 * in,int32 count)15 void SexyFilter2(int32 *in, int32 count) {
16 #ifdef moo
17 static int64 acc = 0;
18 double x, p;
19 int64 c;
20
21 x = 2 * M_PI * 6000 / FSettings.SndRate;
22 p = ((double)2 - cos(x)) - sqrt(pow((double)2 - cos(x), 2) - 1);
23
24 c = p * 0x100000;
25 /* printf("%f\n",(double)c/0x100000); */
26 #endif
27 static int64 acc = 0;
28
29 while (count--) {
30 int64 dropcurrent;
31 dropcurrent = ((*in << 16) - acc) >> 3;
32
33 acc += dropcurrent;
34 *in = acc >> 16;
35 in++;
36 #if 0
37 acc=((int64)0x100000-c)* *in + ((c*acc)>>20);
38 *in=acc>>20;
39 in++;
40 #endif
41 }
42 }
43
44 int64 sexyfilter_acc1 = 0, sexyfilter_acc2 = 0;
45
SexyFilter(int32 * in,int32 * out,int32 count)46 void SexyFilter(int32 *in, int32 *out, int32 count) {
47 int32 mul1, mul2, vmul;
48
49 mul1 = (94 << 16) / FSettings.SndRate;
50 mul2 = (24 << 16) / FSettings.SndRate;
51 vmul = (FSettings.SoundVolume << 16) * 3 / 4 / 100;
52
53 if (FSettings.soundq)
54 vmul /= 4;
55 else
56 vmul *= 2; /* TODO: Increase volume in low quality sound rendering code itself */
57
58 while (count) {
59 int64 ino = (int64) * in * vmul;
60 sexyfilter_acc1 += ((ino - sexyfilter_acc1) * mul1) >> 16;
61 sexyfilter_acc2 += ((ino - sexyfilter_acc1 - sexyfilter_acc2) * mul2) >> 16;
62 /* printf("%d ",*in); */
63 *in = 0;
64 {
65 int32 t = (sexyfilter_acc1 - ino + sexyfilter_acc2) >> 16;
66 /* if(t>32767 || t<-32768) printf("Flow: %d\n",t); */
67 if (t > 32767) t = 32767;
68 if (t < -32768) t = -32768;
69 *out = t;
70 }
71 in++;
72 out++;
73 count--;
74 }
75 }
76
77 /* Returns number of samples written to out. */
78 /* leftover is set to the number of samples that need to be copied
79 from the end of in to the beginning of in.
80 */
81
82 /* static uint32 mva=1000; */
83
84 /* This filtering code assumes that almost all input values stay below 32767.
85 Do not adjust the volume in the wlookup tables and the expansion sound
86 code to be higher, or you *might* overflow the FIR code.
87 */
88
NeoFilterSound(int32 * in,int32 * out,uint32 inlen,int32 * leftover)89 int32 NeoFilterSound(int32 *in, int32 *out, uint32 inlen, int32 *leftover) {
90 uint32 x;
91 uint32 max;
92 int32 *outsave = out;
93 int32 count = 0;
94
95 #if 0
96 for(x=0;x<inlen;x++)
97 {
98 if(in[x]>mva) { mva=in[x]; printf("%ld\n",in[x]);}
99 }
100 #endif
101 max = (inlen - 1) << 16;
102
103 if (FSettings.soundq == 2) {
104 for (x = mrindex; x < max; x += mrratio) {
105 int32 acc = 0, acc2 = 0;
106 uint32 c;
107 int32 *S, *D;
108
109 for (c = SQ2NCOEFFS, S = &in[(x >> 16) - SQ2NCOEFFS], D = sq2coeffs; c; c--, D++) {
110 acc += (S[c] * *D) >> 6;
111 acc2 += (S[1 + c] * *D) >> 6;
112 }
113
114 acc = ((int64)acc * (65536 - (x & 65535)) + (int64)acc2 * (x & 65535)) >> (16 + 11);
115 *out = acc;
116 out++;
117 count++;
118 }
119 } else {
120 for (x = mrindex; x < max; x += mrratio) {
121 int32 acc = 0, acc2 = 0;
122 uint32 c;
123 int32 *S, *D;
124
125 for (c = NCOEFFS, S = &in[(x >> 16) - NCOEFFS], D = coeffs; c; c--, D++) {
126 acc += (S[c] * *D) >> 6;
127 acc2 += (S[1 + c] * *D) >> 6;
128 }
129
130 acc = ((int64)acc * (65536 - (x & 65535)) + (int64)acc2 * (x & 65535)) >> (16 + 11);
131 *out = acc;
132 out++;
133 count++;
134 }
135 }
136
137 mrindex = x - max;
138
139 if (FSettings.soundq == 2) {
140 mrindex += SQ2NCOEFFS * 65536;
141 *leftover = SQ2NCOEFFS + 1;
142 } else {
143 mrindex += NCOEFFS * 65536;
144 *leftover = NCOEFFS + 1;
145 }
146
147 if (GameExpSound.NeoFill)
148 GameExpSound.NeoFill(outsave, count);
149
150 SexyFilter(outsave, outsave, count);
151 if (FSettings.lowpass)
152 SexyFilter2(outsave, count);
153 return(count);
154 }
155
MakeFilters(int32 rate)156 void MakeFilters(int32 rate) {
157 int32 *tabs[6] = { C44100NTSC, C44100PAL, C48000NTSC, C48000PAL, C96000NTSC,
158 C96000PAL };
159 int32 *sq2tabs[6] = { SQ2C44100NTSC, SQ2C44100PAL, SQ2C48000NTSC, SQ2C48000PAL,
160 SQ2C96000NTSC, SQ2C96000PAL };
161
162 int32 *tmp;
163 int32 x;
164 uint32 nco;
165
166 if (FSettings.soundq == 2)
167 nco = SQ2NCOEFFS;
168 else
169 nco = NCOEFFS;
170
171 mrindex = (nco + 1) << 16;
172 mrratio = (PAL ? (int64)(PAL_CPU * 65536) : (int64)(NTSC_CPU * 65536)) / rate;
173
174 if (FSettings.soundq == 2)
175 tmp = sq2tabs[(PAL ? 1 : 0) | (rate == 48000 ? 2 : 0) | (rate == 96000 ? 4 : 0)];
176 else
177 tmp = tabs[(PAL ? 1 : 0) | (rate == 48000 ? 2 : 0) | (rate == 96000 ? 4 : 0)];
178
179 if (FSettings.soundq == 2)
180 for (x = 0; x < (SQ2NCOEFFS >> 1); x++)
181 sq2coeffs[x] = sq2coeffs[SQ2NCOEFFS - 1 - x] = tmp[x];
182 else
183 for (x = 0; x < (NCOEFFS >> 1); x++)
184 coeffs[x] = coeffs[NCOEFFS - 1 - x] = tmp[x];
185
186 #ifdef MOO
187 /* Some tests involving precision and error. */
188 {
189 static int64 acc = 0;
190 int x;
191 for (x = 0; x < SQ2NCOEFFS; x++)
192 acc += (int64)32767 * sq2coeffs[x];
193 printf("Foo: %lld\n", acc);
194 }
195 #endif
196 }
197