more 0.98.15-like timing, but sound glitches
[fceu.git] / sound.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Ben Parnell
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 /********************************************************/
22 /*******                sound.c                         */
23 /*******                                                */
24 /*******  Sound emulation code and waveform synthesis   */
25 /*******  routines.  A few ideas were inspired          */
26 /*******  by code from Marat Fayzullin's EMUlib         */
27 /*******                                                */
28 /********************************************************/
29
30 #include <stdlib.h>
31 #include <stdio.h>
32
33 #include <string.h>
34
35 #include "types.h"
36 #include "x6502.h"
37
38 #include "fce.h"
39 #include "svga.h"
40 #include "sound.h"
41
42 uint32 soundtsinc;
43 uint32 soundtsi;
44
45 uint32 Wave[2048];
46 int32 WaveFinal[2048];
47 int16 WaveFinalMono[2048];
48
49 EXPSOUND GameExpSound={0,0,0};
50
51 uint8 trimode=0;
52 uint8 tricoop=0;
53 uint8 PSG[0x18];
54
55 uint8 decvolume[3];
56 uint8 realvolume[3];
57
58 static int32 count[5];
59 static int64 sqacc[2]={0,0};
60 uint8 sqnon=0;
61
62 uint32 soundtsoffs=0;
63
64 #undef printf
65 uint16 nreg;
66
67 int32 lengthcount[4];
68
69 extern int soundvol;
70
71 static const uint8 Slengthtable[0x20]=
72 {
73  0x5,0x7f,0xA,0x1,0x14,0x2,0x28,0x3,0x50,0x4,0x1E,0x5,0x7,0x6,0x0E,0x7,
74  0x6,0x08,0xC,0x9,0x18,0xa,0x30,0xb,0x60,0xc,0x24,0xd,0x8,0xe,0x10,0xf
75 };
76
77 static uint32 lengthtable[0x20];
78
79 static const uint32 SNoiseFreqTable[0x10]=
80 {
81  2,4,8,0x10,0x20,0x30,0x40,0x50,0x65,0x7f,0xbe,0xfe,0x17d,0x1fc,0x3f9,0x7f2
82 };
83 static uint32 NoiseFreqTable[0x10];
84
85 int64 nesincsizeLL;
86
87 static const uint8 NTSCPCMTable[0x10]=
88 {
89  0xd6,0xbe,0xaa,0xa0,0x8f,0x7f,0x71,0x6b,
90  0x5f,0x50,0x47,0x40,0x35,0x2a,0x24,0x1b
91 };
92
93 static const uint8 PALPCMTable[0x10]=   // These values are just guessed.
94 {
95  0xc6,0xb0,0x9d,0x94,0x84,0x75,0x68,0x63,
96  0x58,0x4a,0x41,0x3b,0x31,0x27,0x21,0x19
97 };
98
99 uint32 PSG_base;
100
101 // $4010        -        Frequency
102 // $4011        -        Actual data outputted
103 // $4012        -        Address register: $c000 + V*64
104 // $4013        -        Size register:  Size in bytes = (V+1)*64
105
106
107 static int64 PCMacc=0;
108 static int PCMfreq;
109 int32 PCMIRQCount;
110 uint8 PCMBitIndex=0;
111 uint32 PCMAddressIndex=0;
112 int32 PCMSizeIndex=0;
113 uint8 PCMBuffer=0;
114 int vdis=0;
115
116 static void Dummyfunc(void) {};
117
118 static void (*DoNoise)(void)=Dummyfunc;
119 static void (*DoTriangle)(void)=Dummyfunc;
120 static void (*DoPCM)(void)=Dummyfunc;
121 static void (*DoSQ1)(void)=Dummyfunc;
122 static void (*DoSQ2)(void)=Dummyfunc;
123
124 static void CalcDPCMIRQ(void)
125 {
126  uint32 freq;
127  uint32 honk;
128  uint32 cycles;
129
130  if(PAL)
131   freq=(PALPCMTable[PSG[0x10]&0xF]<<4);
132  else
133   freq=(NTSCPCMTable[PSG[0x10]&0xF]<<4);
134
135  cycles=(((PSG[0x13]<<4)+1));
136  cycles*=freq/14;
137  honk=((PSG[0x13]<<4)+1)*freq;
138  honk-=cycles;
139  //if(PAL) honk/=107;
140  //else honk/=(double)113.66666666;
141  PCMIRQCount=honk*48;
142  //PCMIRQCount=honk*3; //180;
143  //if(PAL) PCMIRQCount*=.93;
144  vdis=0;
145 }
146
147 static void PrepDPCM()
148 {
149  PCMAddressIndex=0x4000+(PSG[0x12]<<6);
150  PCMSizeIndex=(PSG[0x13]<<4)+1;
151  PCMBitIndex=0;
152  //PCMBuffer=ARead[0x8000+PCMAddressIndex](0x8000+PCMAddressIndex);
153  if(PAL)
154   PCMfreq=PALPCMTable[PSG[0x10]&0xF];
155  else
156   PCMfreq=NTSCPCMTable[PSG[0x10]&0xF];
157  PCMacc=(int64)PCMfreq<<50;
158 }
159
160 uint8 sweepon[2]={0,0};
161 int32 curfreq[2]={0,0};
162
163
164 uint8 SIRQStat=0;
165
166 uint8 SweepCount[2];
167 uint8 DecCountTo1[3];
168
169 uint8 fcnt=0;
170 int32 fhcnt=0;
171 int32 fhinc;
172
173 static uint8 laster;
174
175 /* Instantaneous?  Maybe the new freq value is being calculated all of the time... */
176 static int FASTAPASS(2) CheckFreq(uint32 cf, uint8 sr)
177 {
178  uint32 mod;
179  if(!(sr&0x8))
180  {
181   mod=cf>>(sr&7);
182   if((mod+cf)&0x800)
183    return(0);
184  }
185  return(1);
186 }
187
188 static DECLFW(Write0x11)
189 {
190  DoPCM();
191  PSG[0x11]=V&0x7F;
192 }
193
194 static uint8 DutyCount[2]={0,0};
195
196 static DECLFW(Write_PSG)
197 {
198  //if((A>=0x4004 && A<=0x4007) || A==0x4015)
199   //printf("$%04x:$%02x, %d\n",A,V,SOUNDTS);
200  A&=0x1f;
201  switch(A)
202  {
203   case 0x0:
204            DoSQ1();
205            if(V&0x10)
206             realvolume[0]=V&0xF;
207            break;
208   case 0x1:
209            sweepon[0]=V&0x80;
210            break;
211   case 0x2:
212            DoSQ1();
213            curfreq[0]&=0xFF00;
214            curfreq[0]|=V;
215            break;
216   case 0x3:
217            if(PSG[0x15]&1)
218            {
219             DoSQ1();
220             lengthcount[0]=lengthtable[(V>>3)&0x1f];
221             sqnon|=1;
222            }
223            sweepon[0]=PSG[1]&0x80;
224            curfreq[0]=PSG[0x2]|((V&7)<<8);
225            decvolume[0]=0xF;
226            DecCountTo1[0]=(PSG[0]&0xF)+1;
227            SweepCount[0]=((PSG[0x1]>>4)&7)+1;
228            DutyCount[0]=0;
229            sqacc[0]=((int64)curfreq[0]+1)<<50;
230            break;
231
232   case 0x4:
233            DoSQ2();
234            if(V&0x10)
235             realvolume[1]=V&0xF;
236            break;
237   case 0x5:
238           sweepon[1]=V&0x80;
239           break;
240   case 0x6:
241           DoSQ2();
242           curfreq[1]&=0xFF00;
243           curfreq[1]|=V;
244           break;
245   case 0x7:
246           if(PSG[0x15]&2)
247           {
248            DoSQ2();
249            lengthcount[1]=lengthtable[(V>>3)&0x1f];
250            sqnon|=2;
251           }
252           sweepon[1]=PSG[0x5]&0x80;
253           curfreq[1]=PSG[0x6]|((V&7)<<8);
254           decvolume[1]=0xF;
255           DecCountTo1[1]=(PSG[0x4]&0xF)+1;
256           SweepCount[1]=((PSG[0x5]>>4)&7)+1;
257           DutyCount[1]=0;
258           sqacc[1]=((int64)curfreq[1]+1)<<50;
259           break;
260   case 0x8:
261           DoTriangle();
262           if(laster&0x80)
263           {
264             tricoop=V&0x7F;
265             trimode=V&0x80;
266           }
267           if(!(V&0x7F))
268            tricoop=0;
269           laster=V&0x80;
270           break;
271   case 0xa:DoTriangle();
272            break;
273   case 0xb:
274           if(PSG[0x15]&0x4)
275           {
276            DoTriangle();
277            sqnon|=4;
278            lengthcount[2]=lengthtable[(V>>3)&0x1f];
279           }
280           laster=0x80;
281           tricoop=PSG[0x8]&0x7f;
282           trimode=PSG[0x8]&0x80;
283           break;
284   case 0xC:DoNoise();
285            if(V&0x10)
286             realvolume[2]=V&0xF;
287            break;
288   case 0xE:DoNoise();break;
289   case 0xF:
290            if(PSG[0x15]&8)
291            {
292             DoNoise();
293             sqnon|=8;
294             lengthcount[3]=lengthtable[(V>>3)&0x1f];
295            }
296            decvolume[2]=0xF;
297            DecCountTo1[2]=(PSG[0xC]&0xF)+1;
298            break;
299  case 0x10:DoPCM();
300            if(!(V&0x80))
301             X6502_IRQEnd(FCEU_IQDPCM);
302            break;
303  case 0x15:
304            {
305             int t=V^PSG[0x15];
306
307             if(t&1)
308              DoSQ1();
309             if(t&2)
310              DoSQ2();
311             if(t&4)
312              DoTriangle();
313             if(t&8)
314              DoNoise();
315             if(t&0x10)
316              DoPCM();
317             sqnon&=V;
318             if(V&0x10)
319             {
320              if(!(PSG[0x15]&0x10))
321              {
322               PrepDPCM();
323               CalcDPCMIRQ();
324              }
325              else if(vdis)
326               CalcDPCMIRQ();
327             }
328             else
329              PCMIRQCount=0;
330             X6502_IRQEnd(FCEU_IQDPCM);
331            }
332            break;
333  case 0x17:
334            V&=0xC0;
335            fcnt=0;
336            if(V&0x80)
337             FrameSoundUpdate();
338            fhcnt=fhinc;
339            X6502_IRQEnd(FCEU_IQFCOUNT);
340            SIRQStat&=~0x40;
341            break;
342  }
343  PSG[A]=V;
344 }
345
346 DECLFR(Read_PSG)
347 {
348    uint8 ret;
349    if(PSG[0x15]&0x10)
350     DoPCM();
351    ret=(PSG[0x15]&(sqnon|0x10))|SIRQStat;
352    SIRQStat&=~0x40;
353    X6502_IRQEnd(/*FCEU_IQDPCM|*/FCEU_IQFCOUNT);
354    return ret;
355 }
356
357 DECLFR(Read_PSGDummy)
358 {
359    uint8 ret;
360
361    ret=(PSG[0x15]&sqnon)|SIRQStat;
362    SIRQStat&=~0x40;
363    X6502_IRQEnd(/*FCEU_IQDPCM|*/FCEU_IQFCOUNT);
364    return ret;
365 }
366
367 static void FASTAPASS(1) FrameSoundStuff(int V)
368 {
369  int P;
370
371  DoSQ1();
372  DoSQ2();
373  DoNoise();
374
375  switch((V&1))
376  {
377   case 1:       /* Envelope decay, linear counter, length counter, freq sweep */
378         if(PSG[0x15]&4 && sqnon&4)
379          if(!(PSG[8]&0x80))
380          {
381           if(lengthcount[2]>0)
382           {
383             lengthcount[2]--;
384             if(lengthcount[2]<=0)
385              {
386               DoTriangle();
387               sqnon&=~4;
388              }
389            }
390          }
391
392         for(P=0;P<2;P++)
393         {
394          if(PSG[0x15]&(P+1) && sqnon&(P+1))
395          {
396           if(!(PSG[P<<2]&0x20))
397           {
398            if(lengthcount[P]>0)
399            {
400             lengthcount[P]--;
401             if(lengthcount[P]<=0)
402              {
403               sqnon&=~(P+1);
404              }
405            }
406           }
407          }
408                 /* Frequency Sweep Code Here */
409                 /* xxxx 0000 */
410                 /* xxxx = hz.  120/(x+1)*/
411           if(sweepon[P])
412           {
413            int32 mod=0;
414
415            if(SweepCount[P]>0) SweepCount[P]--;
416            if(SweepCount[P]<=0)
417            {
418             SweepCount[P]=((PSG[(P<<2)+0x1]>>4)&7)+1; //+1;
419             {
420              if(PSG[(P<<2)+0x1]&0x8)
421              {
422               mod-=(P^1)+((curfreq[P])>>(PSG[(P<<2)+0x1]&7));
423
424               if(curfreq[P] && (PSG[(P<<2)+0x1]&7)/* && sweepon[P]&0x80*/)
425               {
426                curfreq[P]+=mod;
427               }
428              }
429              else
430              {
431               mod=curfreq[P]>>(PSG[(P<<2)+0x1]&7);
432               if((mod+curfreq[P])&0x800)
433               {
434                sweepon[P]=0;
435                curfreq[P]=0;
436               }
437               else
438               {
439                if(curfreq[P] && (PSG[(P<<2)+0x1]&7)/* && sweepon[P]&0x80*/)
440                {
441                 curfreq[P]+=mod;
442                }
443               }
444              }
445             }
446            }
447           }
448          }
449
450        if(PSG[0x15]&0x8 && sqnon&8)
451         {
452          if(!(PSG[0xC]&0x20))
453          {
454           if(lengthcount[3]>0)
455           {
456            lengthcount[3]--;
457            if(lengthcount[3]<=0)
458            {
459             sqnon&=~8;
460            }
461           }
462          }
463         }
464
465   case 0:       /* Envelope decay + linear counter */
466          if(!trimode)
467          {
468            laster=0;
469            if(tricoop)
470            {
471             if(tricoop==1) DoTriangle();
472             tricoop--;
473            }
474          }
475
476         for(P=0;P<2;P++)
477         {
478           if(DecCountTo1[P]>0) DecCountTo1[P]--;
479           if(DecCountTo1[P]<=0)
480           {
481            DecCountTo1[P]=(PSG[P<<2]&0xF)+1;
482            if(decvolume[P] || PSG[P<<2]&0x20)
483            {
484             decvolume[P]--;
485             /* Step from 0 to full volume seems to take twice as long
486                as the other steps.  I don't know if this is the correct
487                way to double its length, though(or if it even matters).
488             */
489             if((PSG[P<<2]&0x20) && (decvolume[P]==0))
490              DecCountTo1[P]<<=1;
491             decvolume[P]&=15;
492            }
493           }
494           if(!(PSG[P<<2]&0x10))
495            realvolume[P]=decvolume[P];
496         }
497
498          if(DecCountTo1[2]>0) DecCountTo1[2]--;
499          if(DecCountTo1[2]<=0)
500          {
501           DecCountTo1[2]=(PSG[0xC]&0xF)+1;
502           if(decvolume[2] || PSG[0xC]&0x20)
503           {
504             decvolume[2]--;
505             /* Step from 0 to full volume seems to take twice as long
506                as the other steps.  I don't know if this is the correct
507                way to double its length, though(or if it even matters).
508             */
509             if((PSG[0xC]&0x20) && (decvolume[2]==0))
510              DecCountTo1[2]<<=1;
511             decvolume[2]&=15;
512           }
513          }
514          if(!(PSG[0xC]&0x10))
515           realvolume[2]=decvolume[2];
516
517         break;
518  }
519
520 }
521
522 void FrameSoundUpdate(void)
523 {
524  // Linear counter:  Bit 0-6 of $4008
525  // Length counter:  Bit 4-7 of $4003, $4007, $400b, $400f
526
527  if(fcnt==3)
528  {
529         if(PSG[0x17]&0x80)
530          fhcnt+=fhinc;
531         if(!(PSG[0x17]&0xC0))
532         {
533          SIRQStat|=0x40;
534          X6502_IRQBegin(FCEU_IQFCOUNT);
535         }
536  }
537  //if(SIRQStat&0x40) X6502_IRQBegin(FCEU_IQFCOUNT);
538  FrameSoundStuff(fcnt);
539  fcnt=(fcnt+1)&3;
540 }
541
542 static uint32 ChannelBC[5];
543
544 static uint32 RectAmp[2][8];
545
546 static void FASTAPASS(1) CalcRectAmp(int P)
547 {
548   static int tal[4]={1,2,4,6};
549   int V;
550   int x;
551   uint32 *b=RectAmp[P];
552   int m;
553
554   //if(PSG[P<<2]&0x10)
555    V=realvolume[P]<<4;
556   //V=(PSG[P<<2]&15)<<4;
557   //else
558   // V=decvolume[P]<<4;
559   m=tal[(PSG[P<<2]&0xC0)>>6];
560   for(x=0;x<m;x++,b++)
561    *b=0;
562   for(;x<8;x++,b++)
563    *b=V;
564 }
565
566 static void RDoPCM(void)
567 {
568    int32 V;
569    int32 start,end;
570    int64 freq;
571    uint32 out=PSG[0x11]<<3;
572
573    start=ChannelBC[4];
574    end=(SOUNDTS<<16)/soundtsinc;
575    if(end<=start) return;
576    ChannelBC[4]=end;
577
578    if(PSG[0x15]&0x10)
579    {
580       freq=PCMfreq;
581       freq<<=50;
582
583       for(V=start;V<end;V++)
584       {
585        PCMacc-=nesincsizeLL;
586        if(PCMacc<=0)
587        {
588         if(!PCMBitIndex)
589         {
590          PCMSizeIndex--;
591          if(!PCMSizeIndex)
592          {
593           if(PSG[0x10]&0x40)
594            PrepDPCM();
595           else
596           {
597            PSG[0x15]&=~0x10;
598            for(;V<end;V++)
599             Wave[V>>4]+=PSG[0x11]<<3;
600            goto endopcmo;
601           }
602          }
603          else
604          {
605           PCMBuffer=ARead[0x8000+PCMAddressIndex](0x8000+PCMAddressIndex);
606           PCMAddressIndex=(PCMAddressIndex+1)&0x7fff;
607          }
608         }
609
610         {
611          int t=(((PCMBuffer>>PCMBitIndex)&1)<<2)-2;
612          uint8 bah=PSG[0x11];
613
614          PCMacc+=freq;
615          PSG[0x11]+=t;
616          if(PSG[0x11]&0x80)
617           PSG[0x11]=bah;
618          else
619           out=PSG[0x11]<<3;
620         }
621         PCMBitIndex=(PCMBitIndex+1)&7;
622        }
623        Wave[V>>4]+=out; //(PSG[0x11]-64)<<3;
624       }
625    }
626    else
627    {
628      if((end-start)>64)
629      {
630       for(V=start;V<=(start|15);V++)
631        Wave[V>>4]+=out;
632       out<<=4;
633       for(V=(start>>4)+1;V<(end>>4);V++)
634        Wave[V]+=out;
635       out>>=4;
636       for(V=end&(~15);V<end;V++)
637        Wave[V>>4]+=out;
638      }
639      else
640       for(V=start;V<end;V++)
641        Wave[V>>4]+=out;
642    }
643     endopcmo:;
644 }
645
646 static void RDoSQ1(void)
647 {
648    int32 V;
649    int32 start,end;
650    int64 freq;
651
652    CalcRectAmp(0);
653    start=ChannelBC[0];
654    end=(SOUNDTS<<16)/soundtsinc;
655    if(end<=start) return;
656    ChannelBC[0]=end;
657
658    if(curfreq[0]<8 || curfreq[0]>0x7ff)
659     return;
660    if(!CheckFreq(curfreq[0],PSG[0x1]))
661     return;
662
663    if(PSG[0x15]&1 && sqnon&1)
664    {
665     uint32 out=RectAmp[0][DutyCount[0]];
666     freq=curfreq[0]+1;
667     {
668       freq<<=50;
669       for(V=start;V<end;V++)
670       {
671        Wave[V>>4]+=out;
672        sqacc[0]-=nesincsizeLL;
673        if(sqacc[0]<=0)
674        {
675         rea:
676         sqacc[0]+=freq;
677         DutyCount[0]++;
678         if(sqacc[0]<=0) goto rea;
679
680         DutyCount[0]&=7;
681         out=RectAmp[0][DutyCount[0]];
682        }
683
684       }
685      }
686     }
687 }
688
689 static void RDoSQ2(void)
690 {
691    int32 V;
692    int32 start,end;
693    int64 freq;
694
695    CalcRectAmp(1);
696    start=ChannelBC[1];
697    end=(SOUNDTS<<16)/soundtsinc;
698    if(end<=start) return;
699    ChannelBC[1]=end;
700
701    if(curfreq[1]<8 || curfreq[1]>0x7ff)
702     return;
703    if(!CheckFreq(curfreq[1],PSG[0x5]))
704     return;
705
706    if(PSG[0x15]&2 && sqnon&2)
707    {
708     uint32 out=RectAmp[1][DutyCount[1]];
709     freq=curfreq[1]+1;
710
711     {
712       freq<<=50;
713       for(V=start;V<end;V++)
714       {
715        Wave[V>>4]+=out;
716        sqacc[1]-=nesincsizeLL;
717        if(sqacc[1]<=0)
718        {
719         rea:
720         sqacc[1]+=freq;
721         DutyCount[1]++;
722         if(sqacc[1]<=0) goto rea;
723
724         DutyCount[1]&=7;
725         out=RectAmp[1][DutyCount[1]];
726        }
727
728       }
729      }
730     }
731 }
732
733
734 static void RDoTriangle(void)
735 {
736    static uint32 tcout=0;
737    int32 V;
738    int32 start,end; //,freq;
739    int64 freq=(((PSG[0xa]|((PSG[0xb]&7)<<8))+1));
740
741    start=ChannelBC[2];
742    end=(SOUNDTS<<16)/soundtsinc;
743    if(end<=start) return;
744    ChannelBC[2]=end;
745
746     if(! (PSG[0x15]&0x4 && sqnon&4 && tricoop) )
747     {   // Counter is halted, but we still need to output.
748      for(V=start;V<end;V++)
749        Wave[V>>4]+=tcout;
750     }
751     else if(freq<=4) // 55.9Khz - Might be barely audible on a real NES, but
752                // it's too costly to generate audio at this high of a frequency
753                // (55.9Khz * 32 for the stepping).
754                // The same could probably be said for ~27.8Khz, so we'll
755                // take care of that too.  We'll just output the average
756                // value(15/2 - scaled properly for our output format, of course).
757                // We'll also take care of ~18Khz and ~14Khz too, since they should be barely audible.
758                // (Some proof or anything to confirm/disprove this would be nice.).
759     {
760      for(V=start;V<end;V++)
761       Wave[V>>4]+=((0xF<<4)+(0xF<<2))>>1;
762     }
763     else
764     {
765      static int64 triacc=0;
766      static uint8 tc=0;
767
768       freq<<=49;
769       for(V=start;V<end;V++)
770       {
771        triacc-=nesincsizeLL;
772        if(triacc<=0)
773        {
774         rea:
775         triacc+=freq; //t;
776         tc=(tc+1)&0x1F;
777         if(triacc<=0) goto rea;
778
779         tcout=(tc&0xF);
780         if(tc&0x10) tcout^=0xF;
781         tcout=(tcout<<4)+(tcout<<2);
782        }
783        Wave[V>>4]+=tcout;
784       }
785     }
786 }
787
788 static void RDoNoise(void)
789 {
790    int32 inc,V;
791    int32 start,end;
792
793    start=ChannelBC[3];
794    end=(SOUNDTS<<16)/soundtsinc;
795    if(end<=start) return;
796    ChannelBC[3]=end;
797
798    if(PSG[0x15]&0x8 && sqnon&8)
799    {
800       uint32 outo;
801       uint32 amptab[2];
802       uint8 amplitude;
803
804       amplitude=realvolume[2];
805       //if(PSG[0xC]&0x10)
806       // amplitude=(PSG[0xC]&0xF);
807       //else
808       // amplitude=decvolume[2]&0xF;
809
810       inc=NoiseFreqTable[PSG[0xE]&0xF];
811       amptab[0]=((amplitude<<2)+amplitude+amplitude)<<1;
812       amptab[1]=0;
813       outo=amptab[nreg&1];
814
815       if(amplitude)
816       {
817        if(PSG[0xE]&0x80)        // "short" noise
818         for(V=start;V<end;V++)
819         {
820          Wave[V>>4]+=outo;
821          if(count[3]>=inc)
822          {
823           uint8 feedback;
824
825           feedback=((nreg>>8)&1)^((nreg>>14)&1);
826           nreg=(nreg<<1)+feedback;
827           nreg&=0x7fff;
828           outo=amptab[nreg&1];
829           count[3]-=inc;
830          }
831          count[3]+=0x1000;
832         }
833        else
834         for(V=start;V<end;V++)
835         {
836          Wave[V>>4]+=outo;
837          if(count[3]>=inc)
838          {
839           uint8 feedback;
840
841           feedback=((nreg>>13)&1)^((nreg>>14)&1);
842           nreg=(nreg<<1)+feedback;
843           nreg&=0x7fff;
844           outo=amptab[nreg&1];
845           count[3]-=inc;
846          }
847          count[3]+=0x1000;
848         }
849       }
850
851    }
852 }
853
854 void SetNESSoundMap(void)
855 {
856   SetWriteHandler(0x4000,0x4013,Write_PSG);
857   SetWriteHandler(0x4011,0x4011,Write0x11);
858   SetWriteHandler(0x4015,0x4015,Write_PSG);
859   SetWriteHandler(0x4017,0x4017,Write_PSG);
860   SetReadHandler(0x4015,0x4015,Read_PSG);
861 }
862
863 static int32 WaveNSF[256];
864
865 int32 highp;                   // 0 through 65536, 0 = no high pass, 65536 = max high pass
866
867 int32 lowp;                    // 0 through 65536, 65536 = max low pass(total attenuation)
868                                 // 65536 = no low pass
869 static void FilterSound(uint32 *in, int32 *out, int16 *outMono, int count)
870 {
871  static int64 acc=0, acc2=0;
872  //int index=0;
873  //int16* tmp;
874  //int16* outorig=out;
875  //int32 prev=-99999;
876  for(;count;count--,in++)//,out++)//,index++)
877  {
878   int64 diff;
879
880   diff=((int64)*in<<24)-acc;
881
882   acc+=(diff*highp)>>16;
883   acc2+=((diff-acc2)*lowp)>>16;
884   *in=0;
885
886   // don't change the sound here
887 //  *out=(acc2*(int64)FSettings.SoundVolume)>>(24+16);
888   // volume, 4 times louder by default??
889 //  *out = acc2 >> 24;
890  // just a bit louder.  Hope it's okay
891  /*
892   *out = acc2 >> 22;
893   if(*out<-32767) *out=-32767;
894   if(*out>32767) *out=32767;
895   // go one back
896
897   // do MONO
898   tmp=(int16 *)(out-1);
899   // don't do this the first time
900   if (prev == -99999) continue;
901   // the middle one should be interpolated
902   tmp[1]=(int16)((*out + prev) >> 1);
903   prev = *out;
904   */
905   //outMono[index] = (int16)*out;
906   *outMono = (int16)(acc2 >> 24);
907   //if(*outMono<-16384) *outMono=-16384;
908   //if(*outMono>16384) *outMono=16384;
909   outMono++;
910
911   // out=((int64)(acc2>>24)*(int64)FSettings.SoundVolume)>>16; //acc2>>24;
912
913  }
914  // do one more
915 }
916
917
918
919
920 int FlushEmulateSound(void)
921 {
922   int x;
923   uint32 end;
924
925   if(!timestamp) return(0);
926
927   if(!FSettings.SndRate || (soundvol == 0))
928   {
929    end=0;
930    goto nosoundo;
931   }
932
933   end=(SOUNDTS<<16)/soundtsinc;
934   DoSQ1();
935   DoSQ2();
936   DoTriangle();
937   DoNoise();
938   DoPCM();
939
940   if(GameExpSound.Fill)
941    GameExpSound.Fill(end&0xF);
942
943 //  FilterSound(Wave,WaveFinal,end>>4);
944   FilterSound(Wave,WaveFinal,WaveFinalMono,end>>4);
945 //  printf("count %d, num ints %d\n", end, (end >> 4));
946   if(FCEUGameInfo.type==GIT_NSF)
947   {
948    printf("IS NSF");
949    int x,s=0,si=end/1024;       // Only want 1/4 of the output buffer to be displayed
950    for(x=0;x<256;x++)
951    {
952     WaveNSF[x]=WaveFinal[s>>4];
953     s+=si;
954    }
955   }
956
957   if(end&0xF)
958    Wave[0]=Wave[(end>>4)];
959   Wave[(end>>4)]=0;
960
961   nosoundo:
962   for(x=0;x<5;x++)
963    ChannelBC[x]=end&0xF;
964   soundtsoffs=(soundtsinc*(end&0xF))>>16;
965   return(end>>4);
966 }
967
968 void GetSoundBuffer(int32 **W)
969 {
970  *W=WaveNSF;
971 }
972
973 void PowerSound(void)
974 {
975         int x;
976
977         SetNESSoundMap();
978
979         for(x=0;x<0x16;x++)
980          if(x!=0x14)
981           BWrite[0x4000+x](0x4000+x,0);
982         PSG[0x17]=0; //x40;
983         fhcnt=fhinc;
984         fcnt=0;
985         nreg=1;
986         soundtsoffs=0;
987 }
988
989 void ResetSound(void)
990 {
991         int x;
992         for(x=0;x<0x16;x++)
993          if(x!=1 && x!=5 && x!=0x14) BWrite[0x4000+x](0x4000+x,0);
994         PSG[0x17]=0;
995         fhcnt=fhinc;
996         fcnt=0;
997         nreg=1;
998 }
999
1000 void SetSoundVariables(void)
1001 {
1002   int x;
1003
1004   fhinc=PAL?16626:14915;        // *2 CPU clock rate
1005   fhinc*=24;
1006   for(x=0;x<0x20;x++)
1007    lengthtable[x]=Slengthtable[x]<<1;
1008
1009   if(FSettings.SndRate)
1010   {
1011    DoNoise=RDoNoise;
1012    DoTriangle=RDoTriangle;
1013    DoPCM=RDoPCM;
1014    DoSQ1=RDoSQ1;
1015    DoSQ2=RDoSQ2;
1016   }
1017   else
1018   {
1019    DoNoise=DoTriangle=DoPCM=DoSQ1=DoSQ2=Dummyfunc;
1020   }
1021
1022   if(!FSettings.SndRate) return;
1023   if(GameExpSound.RChange)
1024    GameExpSound.RChange();
1025
1026   nesincsizeLL=(int64)((int64)562949953421312*(long double)(PAL?PAL_CPU:NTSC_CPU)/(FSettings.SndRate OVERSAMPLE));
1027   PSG_base=(uint32)(PAL?(long double)PAL_CPU/16:(long double)NTSC_CPU/16);
1028
1029   for(x=0;x<0x10;x++)
1030   {
1031    long double z;
1032    z=SNoiseFreqTable[x]<<1;
1033    z=(PAL?PAL_CPU:NTSC_CPU)/z;
1034    z=(long double)((uint32)((FSettings.SndRate OVERSAMPLE)<<12))/z;
1035    NoiseFreqTable[x]=z;
1036   }
1037   soundtsinc=(uint32)((uint64)(PAL?(long double)PAL_CPU*65536:(long double)NTSC_CPU*65536)/(FSettings.SndRate OVERSAMPLE));
1038   memset(Wave,0,2048*4);
1039   for(x=0;x<5;x++)
1040    ChannelBC[x]=0;
1041   highp=(250<<16)/FSettings.SndRate;  // Arbitrary
1042   lowp=((int64)25000<<16)/FSettings.SndRate; // Arbitrary
1043
1044   if(highp>(1<<16)) highp=1<<16;
1045   if(lowp>(1<<16)) lowp=1<<16;
1046 }
1047
1048 void FixOldSaveStateSFreq(void)
1049 {
1050         int x;
1051         for(x=0;x<2;x++)
1052         {
1053          curfreq[x]=PSG[0x2+(x<<2)]|((PSG[0x3+(x<<2)]&7)<<8);
1054         }
1055 }
1056
1057 void FCEUI_Sound(int Rate)
1058 {
1059  FSettings.SndRate=Rate;
1060  SetSoundVariables();
1061 }
1062
1063 void FCEUI_SetSoundVolume(uint32 volume)
1064 {
1065  FSettings.SoundVolume=(volume<<16)/100;
1066 }