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