/******* routines. A few ideas were inspired */
/******* by code from Marat Fayzullin's EMUlib */
/******* */
-/********************************************************/
+/********************************************************/
#include <stdlib.h>
#include <stdio.h>
uint32 Wave[2048];
int32 WaveFinal[2048];
+int16 WaveFinalMono[2048];
EXPSOUND GameExpSound={0,0,0};
#undef printf
uint16 nreg;
-
-int32 lengthcount[4];
+
+int32 lengthcount[4];
+
+extern int soundvol;
static const uint8 Slengthtable[0x20]=
{
uint8 PCMBitIndex=0;
uint32 PCMAddressIndex=0;
int32 PCMSizeIndex=0;
-uint8 PCMBuffer=0;
+uint8 PCMBuffer=0;
int vdis=0;
static void Dummyfunc(void) {};
freq=(NTSCPCMTable[PSG[0x10]&0xF]<<4);
cycles=(((PSG[0x13]<<4)+1));
- cycles*=freq/14;
+ cycles*=freq/14;
honk=((PSG[0x13]<<4)+1)*freq;
- honk-=cycles;
+ honk-=cycles;
//if(PAL) honk/=107;
//else honk/=(double)113.66666666;
PCMIRQCount=honk*48;
static void PrepDPCM()
{
- PCMAddressIndex=0x4000+(PSG[0x12]<<6);
+ PCMAddressIndex=0x4000+(PSG[0x12]<<6);
PCMSizeIndex=(PSG[0x13]<<4)+1;
- PCMBitIndex=0;
+ PCMBitIndex=0;
//PCMBuffer=ARead[0x8000+PCMAddressIndex](0x8000+PCMAddressIndex);
if(PAL)
PCMfreq=PALPCMTable[PSG[0x10]&0xF];
curfreq[0]&=0xFF00;
curfreq[0]|=V;
break;
- case 0x3:
+ case 0x3:
if(PSG[0x15]&1)
{
DoSQ1();
lengthcount[0]=lengthtable[(V>>3)&0x1f];
- sqnon|=1;
+ sqnon|=1;
}
sweepon[0]=PSG[1]&0x80;
curfreq[0]=PSG[0x2]|((V&7)<<8);
sqacc[0]=((int64)curfreq[0]+1)<<50;
break;
- case 0x4:
+ case 0x4:
DoSQ2();
if(V&0x10)
realvolume[1]=V&0xF;
curfreq[1]&=0xFF00;
curfreq[1]|=V;
break;
- case 0x7:
+ case 0x7:
if(PSG[0x15]&2)
{
DoSQ2();
sqnon|=2;
}
sweepon[1]=PSG[0x5]&0x80;
- curfreq[1]=PSG[0x6]|((V&7)<<8);
+ curfreq[1]=PSG[0x6]|((V&7)<<8);
decvolume[1]=0xF;
DecCountTo1[1]=(PSG[0x4]&0xF)+1;
SweepCount[1]=((PSG[0x5]>>4)&7)+1;
DutyCount[1]=0;
sqacc[1]=((int64)curfreq[1]+1)<<50;
break;
- case 0x8:
+ case 0x8:
DoTriangle();
if(laster&0x80)
{
lengthcount[3]=lengthtable[(V>>3)&0x1f];
}
decvolume[2]=0xF;
- DecCountTo1[2]=(PSG[0xC]&0xF)+1;
+ DecCountTo1[2]=(PSG[0xC]&0xF)+1;
break;
case 0x10:DoPCM();
if(!(V&0x80))
X6502_IRQEnd(FCEU_IQDPCM);
break;
- case 0x15:
+ case 0x15:
{
int t=V^PSG[0x15];
X6502_IRQEnd(FCEU_IQDPCM);
}
break;
- case 0x17:
+ case 0x17:
V&=0xC0;
- fcnt=0;
+ fcnt=0;
if(V&0x80)
FrameSoundUpdate();
fhcnt=fhinc;
X6502_IRQEnd(FCEU_IQFCOUNT);
- SIRQStat&=~0x40;
+ SIRQStat&=~0x40;
break;
}
PSG[A]=V;
DoTriangle();
sqnon&=~4;
}
- }
+ }
}
for(P=0;P<2;P++)
{
if(lengthcount[P]>0)
{
- lengthcount[P]--;
+ lengthcount[P]--;
if(lengthcount[P]<=0)
{
sqnon&=~(P+1);
{
int32 mod=0;
- if(SweepCount[P]>0) SweepCount[P]--;
+ if(SweepCount[P]>0) SweepCount[P]--;
if(SweepCount[P]<=0)
{
SweepCount[P]=((PSG[(P<<2)+0x1]>>4)&7)+1; //+1;
{
if(PSG[(P<<2)+0x1]&0x8)
{
- mod-=(P^1)+((curfreq[P])>>(PSG[(P<<2)+0x1]&7));
+ mod-=(P^1)+((curfreq[P])>>(PSG[(P<<2)+0x1]&7));
if(curfreq[P] && (PSG[(P<<2)+0x1]&7)/* && sweepon[P]&0x80*/)
{
}
}
}
- }
+ }
}
if(PSG[0x15]&0x8 && sqnon&8)
case 0: /* Envelope decay + linear counter */
if(!trimode)
- {
+ {
laster=0;
if(tricoop)
{
uint32 out=PSG[0x11]<<3;
start=ChannelBC[4];
- end=(timestamp<<16)/soundtsinc;
+ end=(timestamp<<16)/soundtsinc;
if(end<=start) return;
ChannelBC[4]=end;
int64 freq=(((PSG[0xa]|((PSG[0xb]&7)<<8))+1));
start=ChannelBC[2];
- end=(timestamp<<16)/soundtsinc;
+ end=(timestamp<<16)/soundtsinc;
if(end<=start) return;
ChannelBC[2]=end;
}
else
{
- static int64 triacc=0;
- static uint8 tc=0;
+ static int64 triacc=0;
+ static uint8 tc=0;
freq<<=49;
for(V=start;V<end;V++)
int32 start,end;
start=ChannelBC[3];
- end=(timestamp<<16)/soundtsinc;
+ end=(timestamp<<16)/soundtsinc;
if(end<=start) return;
ChannelBC[3]=end;
uint32 outo;
uint32 amptab[2];
uint8 amplitude;
-
+
amplitude=realvolume[2];
//if(PSG[0xC]&0x10)
// amplitude=(PSG[0xC]&0xF);
- //else
+ //else
// amplitude=decvolume[2]&0xF;
- inc=NoiseFreqTable[PSG[0xE]&0xF];
+ inc=NoiseFreqTable[PSG[0xE]&0xF];
amptab[0]=((amplitude<<2)+amplitude+amplitude)<<1;
amptab[1]=0;
outo=amptab[nreg&1];
- if(amplitude)
+ if(amplitude)
{
- if(PSG[0xE]&0x80) // "short" noise
+ if(PSG[0xE]&0x80) // "short" noise
for(V=start;V<end;V++)
- {
+ {
Wave[V>>4]+=outo;
if(count[3]>=inc)
- {
- uint8 feedback;
+ {
+ uint8 feedback;
feedback=((nreg>>8)&1)^((nreg>>14)&1);
nreg=(nreg<<1)+feedback;
}
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_PSG);
SetReadHandler(0x4015,0x4015,Read_PSG);
}
static int32 WaveNSF[256];
-int64 highp; // 0 through 65536, 0 = no high pass, 65536 = max high pass
+int32 highp; // 0 through 65536, 0 = no high pass, 65536 = max high pass
-int64 lowp; // 0 through 65536, 65536 = max low pass(total attenuation)
+int32 lowp; // 0 through 65536, 65536 = max low pass(total attenuation)
// 65536 = no low pass
-static void FilterSound(uint32 *in, int32 *out, int count)
+static void FilterSound(uint32 *in, int32 *out, int16 *outMono, int count)
{
static int64 acc=0, acc2=0;
-
- for(;count;count--,in++,out++)
+ //int index=0;
+ //int16* tmp;
+ //int16* outorig=out;
+ //int32 prev=-99999;
+ for(;count;count--,in++)//,out++)//,index++)
{
int64 diff;
acc+=(diff*highp)>>16;
acc2+=((diff-acc2)*lowp)>>16;
*in=0;
- *out=(acc2*(int64)FSettings.SoundVolume)>>(24+16);
+
+ // don't change the sound here
+// *out=(acc2*(int64)FSettings.SoundVolume)>>(24+16);
+ // volume, 4 times louder by default??
+// *out = acc2 >> 24;
+ // just a bit louder. Hope it's okay
+ /*
+ *out = acc2 >> 22;
if(*out<-32767) *out=-32767;
if(*out>32767) *out=32767;
- //*out=((int64)(acc2>>24)*(int64)FSettings.SoundVolume)>>16; //acc2>>24;
+ // go one back
+
+ // do MONO
+ tmp=(int16 *)(out-1);
+ // don't do this the first time
+ if (prev == -99999) continue;
+ // the middle one should be interpolated
+ tmp[1]=(int16)((*out + prev) >> 1);
+ prev = *out;
+ */
+ //outMono[index] = (int16)*out;
+ *outMono = (int16)(acc2 >> 24);
+ //if(*outMono<-16384) *outMono=-16384;
+ //if(*outMono>16384) *outMono=16384;
+ outMono++;
+
+ // out=((int64)(acc2>>24)*(int64)FSettings.SoundVolume)>>16; //acc2>>24;
+
}
+ // do one more
}
+
+
+
int FlushEmulateSound(void)
{
uint32 end;
int x;
+
if(!timestamp) return(0);
- if(!FSettings.SndRate)
+ if(!FSettings.SndRate || (soundvol == 0))
{
end=0;
goto nosoundo;
if(GameExpSound.Fill)
GameExpSound.Fill(end&0xF);
- FilterSound(Wave,WaveFinal,end>>4);
-
+// FilterSound(Wave,WaveFinal,end>>4);
+ FilterSound(Wave,WaveFinal,WaveFinalMono,end>>4);
+// 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++)
{
if(end&0xF)
Wave[0]=Wave[(end>>4)];
- Wave[(end>>4)]=0;
+ Wave[(end>>4)]=0;
nosoundo:
for(x=0;x<5;x++)
ChannelBC[x]=end&0xF;
timestampbase+=timestamp;
- timestamp=(soundtsinc*(end&0xF))>>16;
+ timestamp=(soundtsinc*(end&0xF))>>16;
timestampbase-=timestamp;
return(end>>4);
}
void SetSoundVariables(void)
{
- int x;
+ int x;
fhinc=PAL?16626:14915; // *2 CPU clock rate
fhinc*=24;
DoPCM=RDoPCM;
DoSQ1=RDoSQ1;
DoSQ2=RDoSQ2;
- }
+ }
else
{
DoNoise=DoTriangle=DoPCM=DoSQ1=DoSQ2=Dummyfunc;