| 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 | } |