some warnings fixed, nsf fixed, palettes, more code backported
[fceu.git] / sound.c
diff --git a/sound.c b/sound.c
index 8cdde0e..7d56a2d 100644 (file)
--- a/sound.c
+++ b/sound.c
@@ -59,6 +59,8 @@ static int32 count[5];
 static int64 sqacc[2]={0,0};
 uint8 sqnon=0;
 
+uint32 soundtsoffs=0;
+
 #undef printf
 uint16 nreg;
 
@@ -81,6 +83,7 @@ static const uint32 SNoiseFreqTable[0x10]=
 static uint32 NoiseFreqTable[0x10];
 
 int64 nesincsizeLL;
+int64 nesincsize;
 
 static const uint8 NTSCPCMTable[0x10]=
 {
@@ -194,7 +197,7 @@ static uint8 DutyCount[2]={0,0};
 static DECLFW(Write_PSG)
 {
  //if((A>=0x4004 && A<=0x4007) || A==0x4015)
-  //printf("$%04x:$%02x, %d\n",A,V,timestamp);
+  //printf("$%04x:$%02x, %d\n",A,V,SOUNDTS);
  A&=0x1f;
  switch(A)
  {
@@ -328,15 +331,6 @@ static DECLFW(Write_PSG)
             X6502_IRQEnd(FCEU_IQDPCM);
           }
            break;
- case 0x17:
-          V&=0xC0;
-           fcnt=0;
-           if(V&0x80)
-            FrameSoundUpdate();
-           fhcnt=fhinc;
-           X6502_IRQEnd(FCEU_IQFCOUNT);
-          SIRQStat&=~0x40;
-           break;
  }
  PSG[A]=V;
 }
@@ -569,7 +563,7 @@ static void RDoPCM(void)
    uint32 out=PSG[0x11]<<3;
 
    start=ChannelBC[4];
-   end=(timestamp<<16)/soundtsinc;
+   end=(SOUNDTS<<16)/soundtsinc;
    if(end<=start) return;
    ChannelBC[4]=end;
 
@@ -649,7 +643,7 @@ static void RDoSQ1(void)
 
    CalcRectAmp(0);
    start=ChannelBC[0];
-   end=(timestamp<<16)/soundtsinc;
+   end=(SOUNDTS<<16)/soundtsinc;
    if(end<=start) return;
    ChannelBC[0]=end;
 
@@ -692,7 +686,7 @@ static void RDoSQ2(void)
 
    CalcRectAmp(1);
    start=ChannelBC[1];
-   end=(timestamp<<16)/soundtsinc;
+   end=(SOUNDTS<<16)/soundtsinc;
    if(end<=start) return;
    ChannelBC[1]=end;
 
@@ -737,7 +731,7 @@ static void RDoTriangle(void)
    int64 freq=(((PSG[0xa]|((PSG[0xb]&7)<<8))+1));
 
    start=ChannelBC[2];
-   end=(timestamp<<16)/soundtsinc;
+   end=(SOUNDTS<<16)/soundtsinc;
    if(end<=start) return;
    ChannelBC[2]=end;
 
@@ -789,7 +783,7 @@ static void RDoNoise(void)
    int32 start,end;
 
    start=ChannelBC[3];
-   end=(timestamp<<16)/soundtsinc;
+   end=(SOUNDTS<<16)/soundtsinc;
    if(end<=start) return;
    ChannelBC[3]=end;
 
@@ -849,16 +843,30 @@ static void RDoNoise(void)
    }
 }
 
+DECLFW(Write_IRQFM)
+{
+ PSG[0x17]=V;
+ V=(V&0xC0)>>6;
+ fcnt=0;
+ if(V&0x2)
+  FrameSoundUpdate();
+ fcnt=1;
+ fhcnt=fhinc;
+ X6502_IRQEnd(FCEU_IQFCOUNT);
+ SIRQStat&=~0x40;
+ //IRQFrameMode=V; // IRQFrameMode is PSG[0x17] upper bits
+}
+
 void SetNESSoundMap(void)
 {
   SetWriteHandler(0x4000,0x4013,Write_PSG);
   SetWriteHandler(0x4011,0x4011,Write0x11);
   SetWriteHandler(0x4015,0x4015,Write_PSG);
-  SetWriteHandler(0x4017,0x4017,Write_PSG);
+  SetWriteHandler(0x4017,0x4017,Write_IRQFM);
   SetReadHandler(0x4015,0x4015,Read_PSG);
 }
 
-static int32 WaveNSF[256];
+static int32 WaveNSF[2048];
 
 int32 highp;                   // 0 through 65536, 0 = no high pass, 65536 = max high pass
 
@@ -915,11 +923,11 @@ static void FilterSound(uint32 *in, int32 *out, int16 *outMono, int count)
 
 
 
+static int32 inbuf=0;
 int FlushEmulateSound(void)
 {
-  uint32 end;
   int x;
-
+  uint32 end;
 
   if(!timestamp) return(0);
 
@@ -929,7 +937,7 @@ int FlushEmulateSound(void)
    goto nosoundo;
   }
 
-  end=(timestamp<<16)/soundtsinc;
+  end=(SOUNDTS<<16)/soundtsinc;
   DoSQ1();
   DoSQ2();
   DoTriangle();
@@ -944,12 +952,12 @@ int FlushEmulateSound(void)
 //  printf("count %d, num ints %d\n", end, (end >> 4));
   if(FCEUGameInfo.type==GIT_NSF)
   {
-   printf("IS NSF");
-   int x,s=0,si=end/1024;       // Only want 1/4 of the output buffer to be displayed
-   for(x=0;x<256;x++)
+   int x;//,s=0,si=end/1024;
+   for(x=0;x<1024;x++)
    {
-    WaveNSF[x]=WaveFinal[s>>4];
-    s+=si;
+    //WaveNSF[x]=WaveFinal[s>>4];
+    WaveNSF[x]=WaveFinalMono[x];
+    //s+=si;
    }
   }
 
@@ -960,15 +968,16 @@ int FlushEmulateSound(void)
   nosoundo:
   for(x=0;x<5;x++)
    ChannelBC[x]=end&0xF;
-  timestampbase+=timestamp;
-  timestamp=(soundtsinc*(end&0xF))>>16;
-  timestampbase-=timestamp;
-  return(end>>4);
+  soundtsoffs=(soundtsinc*(end&0xF))>>16;
+  end>>=4;
+  inbuf=end;
+  return(end);
 }
 
-void GetSoundBuffer(int32 **W)
+int GetSoundBuffer(int32 **W)
 {
  *W=WaveNSF;
+ return inbuf;
 }
 
 void PowerSound(void)
@@ -984,6 +993,7 @@ void PowerSound(void)
         fhcnt=fhinc;
         fcnt=0;
         nreg=1;
+        soundtsoffs=0;
 }
 
 void ResetSound(void)
@@ -1023,7 +1033,8 @@ void SetSoundVariables(void)
   if(GameExpSound.RChange)
    GameExpSound.RChange();
 
-  nesincsizeLL=(int64)((int64)562949953421312*(long double)(PAL?PAL_CPU:NTSC_CPU)/(FSettings.SndRate OVERSAMPLE));
+  nesincsizeLL=(int64)((int64)562949953421312*(double)(PAL?PAL_CPU:NTSC_CPU)/(FSettings.SndRate OVERSAMPLE));
+  nesincsize=(int64)(((int64)1<<17)*(double)(PAL?PAL_CPU:NTSC_CPU)/(FSettings.SndRate * 16));
   PSG_base=(uint32)(PAL?(long double)PAL_CPU/16:(long double)NTSC_CPU/16);
 
   for(x=0;x<0x10;x++)
@@ -1062,5 +1073,5 @@ void FCEUI_Sound(int Rate)
 
 void FCEUI_SetSoundVolume(uint32 volume)
 {
- FSettings.SoundVolume=(volume<<16)/100;
+ FSettings.SoundVolume=volume;
 }