spu: interpolation is now an emulator option, defaulting to linear, and it is bound to the win32 gui. choosing interpolation:none can net you a small framerate boost.
This commit is contained in:
parent
1a6079ce4d
commit
6365f26d7d
|
@ -355,6 +355,7 @@ extern struct TCommonSettings {
|
||||||
, BootFromFirmware(false)
|
, BootFromFirmware(false)
|
||||||
, DebugConsole(false)
|
, DebugConsole(false)
|
||||||
, wifiBridgeAdapterNum(0)
|
, wifiBridgeAdapterNum(0)
|
||||||
|
, spuInterpolationMode(SPUInterpolation_Linear)
|
||||||
{
|
{
|
||||||
strcpy(ARM9BIOS, "biosnds9.bin");
|
strcpy(ARM9BIOS, "biosnds9.bin");
|
||||||
strcpy(ARM7BIOS, "biosnds7.bin");
|
strcpy(ARM7BIOS, "biosnds7.bin");
|
||||||
|
@ -374,6 +375,7 @@ extern struct TCommonSettings {
|
||||||
bool DebugConsole;
|
bool DebugConsole;
|
||||||
|
|
||||||
int wifiBridgeAdapterNum;
|
int wifiBridgeAdapterNum;
|
||||||
|
SPUInterpolationMode spuInterpolationMode;
|
||||||
} CommonSettings;
|
} CommonSettings;
|
||||||
|
|
||||||
extern char ROMserial[20];
|
extern char ROMserial[20];
|
||||||
|
|
|
@ -41,7 +41,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
//#undef FORCEINLINE
|
//#undef FORCEINLINE
|
||||||
//#define FORCEINLINE
|
//#define FORCEINLINE
|
||||||
#undef SPU_INTERPOLATE
|
|
||||||
|
|
||||||
SPU_struct *SPU_core = 0;
|
SPU_struct *SPU_core = 0;
|
||||||
SPU_struct *SPU_user = 0;
|
SPU_struct *SPU_user = 0;
|
||||||
|
@ -52,19 +51,24 @@ extern SoundInterface_struct *SNDCoreList[];
|
||||||
#define CHANSTAT_STOPPED 0
|
#define CHANSTAT_STOPPED 0
|
||||||
#define CHANSTAT_PLAY 1
|
#define CHANSTAT_PLAY 1
|
||||||
|
|
||||||
//static FORCEINLINE u32 sputrunc(float f) { return u32floor(f); }
|
|
||||||
static FORCEINLINE int sputrunc(double d) { return (int)d; }
|
|
||||||
|
static FORCEINLINE u32 sputrunc(float f) { return u32floor(f); }
|
||||||
|
static FORCEINLINE u32 sputrunc(double d) { return u32floor(d); }
|
||||||
static FORCEINLINE s32 spudivide(s32 val) {
|
static FORCEINLINE s32 spudivide(s32 val) {
|
||||||
//return val / 127; //more accurate
|
//return val / 127; //more accurate
|
||||||
return val >> 7; //faster
|
return val >> 7; //faster
|
||||||
}
|
}
|
||||||
|
|
||||||
const s8 indextbl[8] =
|
//const int shift = (FORMAT == 0 ? 2 : 1);
|
||||||
|
static const int format_shift[] = { 2, 1, 3, 0 };
|
||||||
|
|
||||||
|
static const s8 indextbl[8] =
|
||||||
{
|
{
|
||||||
-1, -1, -1, -1, 2, 4, 6, 8
|
-1, -1, -1, -1, 2, 4, 6, 8
|
||||||
};
|
};
|
||||||
|
|
||||||
const u16 adpcmtbl[89] =
|
static const u16 adpcmtbl[89] =
|
||||||
{
|
{
|
||||||
0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010,
|
0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0010,
|
||||||
0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025,
|
0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F, 0x0022, 0x0025,
|
||||||
|
@ -78,7 +82,7 @@ const u16 adpcmtbl[89] =
|
||||||
0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF
|
0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF
|
||||||
};
|
};
|
||||||
|
|
||||||
const s16 wavedutytbl[8][8] = {
|
static const s16 wavedutytbl[8][8] = {
|
||||||
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF },
|
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF },
|
||||||
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF },
|
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF },
|
||||||
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
|
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF },
|
||||||
|
@ -89,10 +93,10 @@ const s16 wavedutytbl[8][8] = {
|
||||||
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF }
|
{ -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF, -0x7FFF }
|
||||||
};
|
};
|
||||||
|
|
||||||
s32 precalcdifftbl[89][16];
|
static s32 precalcdifftbl[89][16];
|
||||||
u8 precalcindextbl[89][8];
|
static u8 precalcindextbl[89][8];
|
||||||
|
|
||||||
FILE *spufp=NULL;
|
static FILE *spufp=NULL;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -129,12 +133,12 @@ public:
|
||||||
void lock() {
|
void lock() {
|
||||||
lockCount++;
|
lockCount++;
|
||||||
}
|
}
|
||||||
|
int lockCount;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u32 raw_len;
|
|
||||||
s8* raw_copy; //for memcmp
|
s8* raw_copy; //for memcmp
|
||||||
|
u32 raw_len;
|
||||||
s16* decoded; //s16 decoded samples
|
s16* decoded; //s16 decoded samples
|
||||||
ADPCMCacheItem *next, *prev; //double linked list
|
ADPCMCacheItem *next, *prev; //double linked list
|
||||||
int lockCount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//notes on the cache:
|
//notes on the cache:
|
||||||
|
@ -577,6 +581,7 @@ void SPU_struct::WriteWord(u32 addr, u16 val)
|
||||||
case 0xA:
|
case 0xA:
|
||||||
thischan.loopstart = val;
|
thischan.loopstart = val;
|
||||||
thischan.totlength = thischan.length + thischan.loopstart;
|
thischan.totlength = thischan.length + thischan.loopstart;
|
||||||
|
thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -627,6 +632,7 @@ void SPU_struct::WriteLong(u32 addr, u32 val)
|
||||||
case 0xC:
|
case 0xC:
|
||||||
thischan.length = val & 0x3FFFFF;
|
thischan.length = val & 0x3FFFFF;
|
||||||
thischan.totlength = thischan.length + thischan.loopstart;
|
thischan.totlength = thischan.length + thischan.loopstart;
|
||||||
|
thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,66 +650,69 @@ void SPU_WriteLong(u32 addr, u32 val)
|
||||||
T1WriteLong(MMU.ARM7_REG, addr, val);
|
T1WriteLong(MMU.ARM7_REG, addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SPU_INTERPOLATE
|
|
||||||
static FORCEINLINE s32 Interpolate(s32 a, s32 b, float ratio)
|
|
||||||
{
|
|
||||||
//ratio = ratio - (int)ratio;
|
|
||||||
//double ratio2 = ((1.0f - cos(ratio * 3.14f)) / 2.0f);
|
|
||||||
////double ratio2 = (1.0f - cos_lut[((int)(ratio*256.0))&0xFF]) / 2.0f;
|
|
||||||
//return (((1-ratio2)*a) + (ratio2*b));
|
|
||||||
|
|
||||||
//linear interpolation
|
|
||||||
ratio = ratio - sputrunc(ratio);
|
|
||||||
return (1-ratio)*a + ratio*b;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static FORCEINLINE void Fetch8BitData(channel_struct *chan, s32 *data)
|
template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE s32 Interpolate(s32 a, s32 b, double _ratio)
|
||||||
{
|
{
|
||||||
#ifdef SPU_INTERPOLATE
|
float ratio = (float)_ratio;
|
||||||
u32 loc = sputrunc(chan->sampcnt);
|
if(INTERPOLATE_MODE == SPUInterpolation_Cosine)
|
||||||
s32 a = (s32)(chan->buf8[loc] << 8);
|
{
|
||||||
if(loc < (chan->totlength << 2) - 1) {
|
//why did we change it away from the lookup table? somebody should research that
|
||||||
s32 b = (s32)(chan->buf8[loc + 1] << 8);
|
ratio = ratio - (int)ratio;
|
||||||
a = Interpolate(a, b, chan->sampcnt);
|
double ratio2 = ((1.0 - cos(ratio * 3.14)) * 0.5);
|
||||||
|
//double ratio2 = (1.0f - cos_lut[((int)(ratio*256.0))&0xFF]) / 2.0f;
|
||||||
|
return (((1-ratio2)*a) + (ratio2*b));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//linear interpolation
|
||||||
|
ratio = ratio - sputrunc(ratio);
|
||||||
|
return s32floor((1-ratio)*a + ratio*b);
|
||||||
}
|
}
|
||||||
*data = a;
|
|
||||||
#else
|
|
||||||
*data = (s32)chan->buf8[sputrunc(chan->sampcnt)] << 8;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<bool ADPCM_CACHED> static FORCEINLINE void Fetch16BitData(const channel_struct * const chan, s32 *data)
|
template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE void Fetch8BitData(channel_struct *chan, s32 *data)
|
||||||
|
{
|
||||||
|
u32 loc = sputrunc(chan->sampcnt);
|
||||||
|
if(INTERPOLATE_MODE != SPUInterpolation_None)
|
||||||
|
{
|
||||||
|
s32 a = (s32)(chan->buf8[loc] << 8);
|
||||||
|
if(loc < (chan->totlength << 2) - 1) {
|
||||||
|
s32 b = (s32)(chan->buf8[loc + 1] << 8);
|
||||||
|
a = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
|
||||||
|
}
|
||||||
|
*data = a;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*data = (s32)chan->buf8[loc] << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<SPUInterpolationMode INTERPOLATE_MODE, bool ADPCM_CACHED> static FORCEINLINE void Fetch16BitData(const channel_struct * const chan, s32 *data)
|
||||||
{
|
{
|
||||||
const s16* const buf16 = ADPCM_CACHED ? chan->cacheItem->decoded : chan->buf16;
|
const s16* const buf16 = ADPCM_CACHED ? chan->cacheItem->decoded : chan->buf16;
|
||||||
#ifdef SPU_INTERPOLATE
|
|
||||||
const int shift = ADPCM_CACHED ? 3 : 1;
|
const int shift = ADPCM_CACHED ? 3 : 1;
|
||||||
int loc = sputrunc(chan->sampcnt);
|
if(INTERPOLATE_MODE != SPUInterpolation_None)
|
||||||
s32 a = (s32)buf16[loc], b;
|
|
||||||
if(loc < (int)(chan->totlength << shift) - 1)
|
|
||||||
{
|
{
|
||||||
b = (s32)buf16[loc + 1];
|
u32 loc = sputrunc(chan->sampcnt);
|
||||||
a = Interpolate(a, b, chan->sampcnt);
|
s32 a = (s32)buf16[loc], b;
|
||||||
|
if(loc < (chan->totlength << shift) - 1)
|
||||||
|
{
|
||||||
|
s32 b = (s32)buf16[loc + 1];
|
||||||
|
a = Interpolate<INTERPOLATE_MODE>(a, b, chan->sampcnt);
|
||||||
|
}
|
||||||
|
*data = a;
|
||||||
}
|
}
|
||||||
*data = a;
|
else
|
||||||
#else
|
*data = (s32)buf16[sputrunc(chan->sampcnt)];
|
||||||
*data = (s32)buf16[sputrunc(chan->sampcnt)];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<SPUInterpolationMode INTERPOLATE_MODE, bool ADPCM_CACHED> static FORCEINLINE void FetchADPCMData(channel_struct * const chan, s32 * const data)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<bool ADPCM_CACHED> static FORCEINLINE void FetchADPCMData(channel_struct * const chan, s32 * const data)
|
|
||||||
{
|
{
|
||||||
if(ADPCM_CACHED)
|
if(ADPCM_CACHED)
|
||||||
{
|
{
|
||||||
return Fetch16BitData<true>(chan, data);
|
return Fetch16BitData<INTERPOLATE_MODE,true>(chan, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No sense decoding, just return the last sample
|
// No sense decoding, just return the last sample
|
||||||
|
@ -725,15 +734,12 @@ template<bool ADPCM_CACHED> static FORCEINLINE void FetchADPCMData(channel_struc
|
||||||
chan->lastsampcnt = sputrunc(chan->sampcnt);
|
chan->lastsampcnt = sputrunc(chan->sampcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SPU_INTERPOLATE
|
if(INTERPOLATE_MODE != SPUInterpolation_None)
|
||||||
*data = Interpolate((s32)chan->pcm16b_last,(s32)chan->pcm16b,chan->sampcnt);
|
*data = Interpolate<INTERPOLATE_MODE>((s32)chan->pcm16b_last,(s32)chan->pcm16b,chan->sampcnt);
|
||||||
#else
|
else
|
||||||
*data = (s32)chan->pcm16b;
|
*data = (s32)chan->pcm16b;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static FORCEINLINE void FetchPSGData(channel_struct *chan, s32 *data)
|
static FORCEINLINE void FetchPSGData(channel_struct *chan, s32 *data)
|
||||||
{
|
{
|
||||||
if(chan->num < 8)
|
if(chan->num < 8)
|
||||||
|
@ -781,16 +787,12 @@ static FORCEINLINE void MixL(SPU_struct* SPU, channel_struct *chan, s32 data)
|
||||||
SPU->sndbuf[SPU->bufpos<<1] += data;
|
SPU->sndbuf[SPU->bufpos<<1] += data;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static FORCEINLINE void MixR(SPU_struct* SPU, channel_struct *chan, s32 data)
|
static FORCEINLINE void MixR(SPU_struct* SPU, channel_struct *chan, s32 data)
|
||||||
{
|
{
|
||||||
data = (spudivide(data * chan->vol)) >> chan->datashift;
|
data = (spudivide(data * chan->vol)) >> chan->datashift;
|
||||||
SPU->sndbuf[(SPU->bufpos<<1)+1] += data;
|
SPU->sndbuf[(SPU->bufpos<<1)+1] += data;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static FORCEINLINE void MixLR(SPU_struct* SPU, channel_struct *chan, s32 data)
|
static FORCEINLINE void MixLR(SPU_struct* SPU, channel_struct *chan, s32 data)
|
||||||
{
|
{
|
||||||
data = (spudivide(data * chan->vol)) >> chan->datashift;
|
data = (spudivide(data * chan->vol)) >> chan->datashift;
|
||||||
|
@ -806,14 +808,12 @@ template<int FORMAT> static FORCEINLINE void TestForLoop(SPU_struct *SPU, channe
|
||||||
|
|
||||||
chan->sampcnt += chan->sampinc;
|
chan->sampcnt += chan->sampinc;
|
||||||
|
|
||||||
if (chan->sampcnt > (double)((chan->length + chan->loopstart) << shift))
|
if (chan->sampcnt > chan->double_totlength_shifted)
|
||||||
{
|
{
|
||||||
// Do we loop? Or are we done?
|
// Do we loop? Or are we done?
|
||||||
if (chan->repeat == 1)
|
if (chan->repeat == 1)
|
||||||
{
|
{
|
||||||
chan->sampcnt = (double)(chan->loopstart << shift); // Is this correct?
|
chan->sampcnt = (double)(chan->loopstart << shift); // Is this correct?
|
||||||
//TODO: ADPCM RESCAN?
|
|
||||||
//this might would help in case streaming adpcm sounds arent working well
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -826,13 +826,11 @@ template<int FORMAT> static FORCEINLINE void TestForLoop(SPU_struct *SPU, channe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
|
static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
|
||||||
{
|
{
|
||||||
chan->sampcnt += chan->sampinc;
|
chan->sampcnt += chan->sampinc;
|
||||||
|
|
||||||
if (chan->sampcnt > (double)((chan->length + chan->loopstart) << 3))
|
if (chan->sampcnt > chan->double_totlength_shifted)
|
||||||
{
|
{
|
||||||
// Do we loop? Or are we done?
|
// Do we loop? Or are we done?
|
||||||
if (chan->repeat == 1)
|
if (chan->repeat == 1)
|
||||||
|
@ -841,6 +839,8 @@ static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
|
||||||
chan->pcm16b = (s16)((chan->buf8[1] << 8) | chan->buf8[0]);
|
chan->pcm16b = (s16)((chan->buf8[1] << 8) | chan->buf8[0]);
|
||||||
chan->index = chan->buf8[2] & 0x7F;
|
chan->index = chan->buf8[2] & 0x7F;
|
||||||
chan->lastsampcnt = 7;
|
chan->lastsampcnt = 7;
|
||||||
|
//TODO: ADPCM RESCAN?
|
||||||
|
//this might would help in case streaming adpcm sounds arent working well
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -852,273 +852,87 @@ static FORCEINLINE void TestForLoop2(SPU_struct *SPU, channel_struct *chan)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
template<int CHANNELS> FORCEINLINE static void SPU_Mix(SPU_struct* SPU, channel_struct *chan, s32 data)
|
||||||
|
|
||||||
static void SPU_ChanUpdate8LR(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
{
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
switch(CHANNELS)
|
||||||
{
|
{
|
||||||
s32 data;
|
case 0: MixL(SPU, chan, data); break;
|
||||||
|
case 1: MixLR(SPU, chan, data); break;
|
||||||
// fetch data from source address
|
case 2: MixR(SPU, chan, data); break;
|
||||||
Fetch8BitData(chan, &data);
|
|
||||||
|
|
||||||
MixLR(SPU, chan, data);
|
|
||||||
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
|
||||||
TestForLoop<0>(SPU, chan);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS, bool CACHED>
|
||||||
|
FORCEINLINE static void _____SPU_ChanUpdate(SPU_struct* const SPU, channel_struct* const chan)
|
||||||
static void SPU_ChanUpdate8NoMix(SPU_struct *SPU, channel_struct *chan)
|
|
||||||
{
|
{
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
||||||
{
|
{
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
if(CHANNELS != -1)
|
||||||
TestForLoop<0>(SPU, chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SPU_ChanUpdate8L(SPU_struct *SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
s32 data;
|
|
||||||
|
|
||||||
// fetch data from source address
|
|
||||||
Fetch8BitData(chan, &data);
|
|
||||||
|
|
||||||
MixL(SPU, chan, data);
|
|
||||||
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
|
||||||
TestForLoop<0>(SPU, chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void SPU_ChanUpdate8R(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
s32 data;
|
|
||||||
|
|
||||||
// fetch data from source address
|
|
||||||
Fetch8BitData(chan, &data);
|
|
||||||
|
|
||||||
MixR(SPU, chan, data);
|
|
||||||
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
|
||||||
TestForLoop<0>(SPU, chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void SPU_ChanUpdate16NoMix(SPU_struct *SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
|
||||||
TestForLoop<1>(SPU, chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void SPU_ChanUpdate16LR(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
s32 data;
|
|
||||||
|
|
||||||
// fetch data from source address
|
|
||||||
Fetch16BitData<false>(chan, &data);
|
|
||||||
|
|
||||||
MixLR(SPU, chan, data);
|
|
||||||
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
|
||||||
TestForLoop<1>(SPU, chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void SPU_ChanUpdate16L(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
s32 data;
|
|
||||||
|
|
||||||
// fetch data from source address
|
|
||||||
Fetch16BitData<false>(chan, &data);
|
|
||||||
|
|
||||||
MixL(SPU, chan, data);
|
|
||||||
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
|
||||||
TestForLoop<1>(SPU, chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void SPU_ChanUpdate16R(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
s32 data;
|
|
||||||
|
|
||||||
// fetch data from source address
|
|
||||||
Fetch16BitData<false>(chan, &data);
|
|
||||||
|
|
||||||
MixR(SPU, chan, data);
|
|
||||||
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
|
||||||
TestForLoop<1>(SPU, chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void SPU_ChanUpdateADPCMNoMix(SPU_struct *SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
|
||||||
TestForLoop2(SPU, chan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int CHANNELS, bool CACHED> FORCEINLINE static void SPU_ChanUpdateADPCM_generic(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
s32 data;
|
|
||||||
|
|
||||||
FetchADPCMData<CACHED>(chan, &data);
|
|
||||||
|
|
||||||
switch(CHANNELS)
|
|
||||||
{
|
{
|
||||||
case 0: MixL(SPU, chan, data); break;
|
s32 data;
|
||||||
case 1: MixLR(SPU, chan, data); break;
|
switch(FORMAT)
|
||||||
case 2: MixR(SPU, chan, data); break;
|
{
|
||||||
|
case 0: Fetch8BitData<INTERPOLATE_MODE>(chan, &data); break;
|
||||||
|
case 1: Fetch16BitData<INTERPOLATE_MODE,false>(chan, &data); break;
|
||||||
|
case 2: FetchADPCMData<INTERPOLATE_MODE,CACHED>(chan, &data); break;
|
||||||
|
case 3: FetchPSGData(chan, &data); break;
|
||||||
|
}
|
||||||
|
SPU_Mix<CHANNELS>(SPU, chan, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if we're passed the length and need to loop, etc.
|
switch(FORMAT) {
|
||||||
TestForLoop2(SPU, chan);
|
case 0: case 1: TestForLoop<FORMAT>(SPU, chan); break;
|
||||||
|
case 2: TestForLoop2(SPU, chan); break;
|
||||||
|
case 3: chan->sampcnt += chan->sampinc; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SPU_ChanUpdateADPCMLR(SPU_struct* SPU, channel_struct *chan)
|
template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE, int CHANNELS>
|
||||||
|
FORCEINLINE static void ____SPU_ChanUpdate(SPU_struct* const SPU, channel_struct* const chan)
|
||||||
{
|
{
|
||||||
if(chan->cacheItem) SPU_ChanUpdateADPCM_generic<1,true>(SPU,chan);
|
if(FORMAT == 2 && chan->cacheItem)
|
||||||
else SPU_ChanUpdateADPCM_generic<1,false>(SPU,chan);
|
_____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,CHANNELS,true>(SPU,chan);
|
||||||
|
else _____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,CHANNELS,false>(SPU,chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SPU_ChanUpdateADPCML(SPU_struct* SPU, channel_struct *chan)
|
template<int FORMAT, SPUInterpolationMode INTERPOLATE_MODE>
|
||||||
|
FORCEINLINE static void ___SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
|
||||||
{
|
{
|
||||||
if(chan->cacheItem) SPU_ChanUpdateADPCM_generic<0,true>(SPU,chan);
|
if(!actuallyMix)
|
||||||
else SPU_ChanUpdateADPCM_generic<0,false>(SPU,chan);
|
____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,-1>(SPU,chan);
|
||||||
|
else if (chan->pan == 0)
|
||||||
|
____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,0>(SPU,chan);
|
||||||
|
else if (chan->pan == 127)
|
||||||
|
____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,2>(SPU,chan);
|
||||||
|
else
|
||||||
|
____SPU_ChanUpdate<FORMAT,INTERPOLATE_MODE,1>(SPU,chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SPU_ChanUpdateADPCMR(SPU_struct* SPU, channel_struct *chan)
|
template<SPUInterpolationMode INTERPOLATE_MODE>
|
||||||
|
FORCEINLINE static void __SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
|
||||||
{
|
{
|
||||||
if(chan->cacheItem) SPU_ChanUpdateADPCM_generic<2,true>(SPU,chan);
|
switch(chan->format)
|
||||||
else SPU_ChanUpdateADPCM_generic<2,false>(SPU,chan);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void SPU_ChanUpdatePSGNoMix(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
{
|
||||||
chan->sampcnt += chan->sampinc;
|
case 0: ___SPU_ChanUpdate<0,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
|
||||||
|
case 1: ___SPU_ChanUpdate<1,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
|
||||||
|
case 2: ___SPU_ChanUpdate<2,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
|
||||||
|
case 3: ___SPU_ChanUpdate<3,INTERPOLATE_MODE>(actuallyMix, SPU, chan); break;
|
||||||
|
default: assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCEINLINE static void _SPU_ChanUpdate(const bool actuallyMix, SPU_struct* const SPU, channel_struct* const chan)
|
||||||
static void SPU_ChanUpdatePSGLR(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
{
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
switch(CommonSettings.spuInterpolationMode)
|
||||||
{
|
{
|
||||||
s32 data;
|
case SPUInterpolation_None: __SPU_ChanUpdate<SPUInterpolation_None>(actuallyMix, SPU, chan); break;
|
||||||
|
case SPUInterpolation_Linear: __SPU_ChanUpdate<SPUInterpolation_Linear>(actuallyMix, SPU, chan); break;
|
||||||
// fetch data from source address
|
case SPUInterpolation_Cosine: __SPU_ChanUpdate<SPUInterpolation_Cosine>(actuallyMix, SPU, chan); break;
|
||||||
FetchPSGData(chan, &data);
|
default: assert(false);
|
||||||
|
|
||||||
MixLR(SPU, chan, data);
|
|
||||||
|
|
||||||
chan->sampcnt += chan->sampinc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void SPU_ChanUpdatePSGL(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
s32 data;
|
|
||||||
|
|
||||||
// fetch data from source address
|
|
||||||
FetchPSGData(chan, &data);
|
|
||||||
|
|
||||||
MixL(SPU, chan, data);
|
|
||||||
|
|
||||||
chan->sampcnt += chan->sampinc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void SPU_ChanUpdatePSGR(SPU_struct* SPU, channel_struct *chan)
|
|
||||||
{
|
|
||||||
for (; SPU->bufpos < SPU->buflength; SPU->bufpos++)
|
|
||||||
{
|
|
||||||
s32 data;
|
|
||||||
|
|
||||||
// fetch data from source address
|
|
||||||
FetchPSGData(chan, &data);
|
|
||||||
|
|
||||||
MixR(SPU, chan, data);
|
|
||||||
|
|
||||||
chan->sampcnt += chan->sampinc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void (*SPU_ChanUpdate[4][4])(SPU_struct* SPU, channel_struct *chan) = {
|
|
||||||
{ // 8-bit PCM
|
|
||||||
SPU_ChanUpdate8L,
|
|
||||||
SPU_ChanUpdate8LR,
|
|
||||||
SPU_ChanUpdate8R,
|
|
||||||
SPU_ChanUpdate8NoMix
|
|
||||||
},
|
|
||||||
{ // 16-bit PCM
|
|
||||||
SPU_ChanUpdate16L,
|
|
||||||
SPU_ChanUpdate16LR,
|
|
||||||
SPU_ChanUpdate16R,
|
|
||||||
SPU_ChanUpdate16NoMix,
|
|
||||||
},
|
|
||||||
{ // IMA-ADPCM
|
|
||||||
SPU_ChanUpdateADPCML,
|
|
||||||
SPU_ChanUpdateADPCMLR,
|
|
||||||
SPU_ChanUpdateADPCMR,
|
|
||||||
SPU_ChanUpdateADPCMNoMix
|
|
||||||
},
|
|
||||||
{ // PSG/White Noise
|
|
||||||
SPU_ChanUpdatePSGL,
|
|
||||||
SPU_ChanUpdatePSGLR,
|
|
||||||
SPU_ChanUpdatePSGR,
|
|
||||||
SPU_ChanUpdatePSGNoMix
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<bool actuallyMix>
|
template<bool actuallyMix>
|
||||||
static void SPU_MixAudio(SPU_struct *SPU, int length)
|
static void SPU_MixAudio(SPU_struct *SPU, int length)
|
||||||
{
|
{
|
||||||
|
@ -1152,14 +966,7 @@ static void SPU_MixAudio(SPU_struct *SPU, int length)
|
||||||
SPU->buflength = length;
|
SPU->buflength = length;
|
||||||
|
|
||||||
// Mix audio
|
// Mix audio
|
||||||
if(!actuallyMix)
|
_SPU_ChanUpdate(actuallyMix, SPU, chan);
|
||||||
SPU_ChanUpdate[chan->format][3](SPU,chan);
|
|
||||||
else if (chan->pan == 0)
|
|
||||||
SPU_ChanUpdate[chan->format][0](SPU,chan);
|
|
||||||
else if (chan->pan == 127)
|
|
||||||
SPU_ChanUpdate[chan->format][2](SPU,chan);
|
|
||||||
else
|
|
||||||
SPU_ChanUpdate[chan->format][1](SPU,chan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert from 32-bit->16-bit
|
// convert from 32-bit->16-bit
|
||||||
|
@ -1488,6 +1295,7 @@ bool spu_loadstate(std::istream* is, int size)
|
||||||
read16le(&chan.loopstart,is);
|
read16le(&chan.loopstart,is);
|
||||||
read32le(&chan.length,is);
|
read32le(&chan.length,is);
|
||||||
chan.totlength = chan.length + chan.loopstart;
|
chan.totlength = chan.length + chan.loopstart;
|
||||||
|
chan.double_totlength_shifted = (double)(chan.totlength << format_shift[chan.format]);
|
||||||
if(version == 0)
|
if(version == 0)
|
||||||
{
|
{
|
||||||
u64 temp;
|
u64 temp;
|
||||||
|
|
|
@ -27,7 +27,14 @@
|
||||||
#define SNDCORE_DUMMY 0
|
#define SNDCORE_DUMMY 0
|
||||||
#define SNDCORE_FILEWRITE 1
|
#define SNDCORE_FILEWRITE 1
|
||||||
|
|
||||||
typedef struct
|
enum SPUInterpolationMode
|
||||||
|
{
|
||||||
|
SPUInterpolation_None = 0,
|
||||||
|
SPUInterpolation_Linear = 1,
|
||||||
|
SPUInterpolation_Cosine = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SoundInterface_struct
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
const char *Name;
|
const char *Name;
|
||||||
|
@ -38,7 +45,7 @@ typedef struct
|
||||||
void (*MuteAudio)();
|
void (*MuteAudio)();
|
||||||
void (*UnMuteAudio)();
|
void (*UnMuteAudio)();
|
||||||
void (*SetVolume)(int volume);
|
void (*SetVolume)(int volume);
|
||||||
} SoundInterface_struct;
|
};
|
||||||
|
|
||||||
extern SoundInterface_struct SNDDummy;
|
extern SoundInterface_struct SNDDummy;
|
||||||
extern SoundInterface_struct SNDFile;
|
extern SoundInterface_struct SNDFile;
|
||||||
|
@ -64,6 +71,7 @@ struct channel_struct
|
||||||
u16 loopstart;
|
u16 loopstart;
|
||||||
u32 length;
|
u32 length;
|
||||||
u32 totlength;
|
u32 totlength;
|
||||||
|
double double_totlength_shifted;
|
||||||
union {
|
union {
|
||||||
s8 *buf8;
|
s8 *buf8;
|
||||||
s16 *buf16;
|
s16 *buf16;
|
||||||
|
|
|
@ -98,7 +98,7 @@ void Vector4Copy(float *dst, const float *src);
|
||||||
|
|
||||||
} //extern "C"
|
} //extern "C"
|
||||||
|
|
||||||
//this function is an unreliable, inaccurate floor.
|
//these functions are an unreliable, inaccurate floor.
|
||||||
//it should only be used for positive numbers
|
//it should only be used for positive numbers
|
||||||
//this isnt as fast as it could be if we used a visual c++ intrinsic, but those appear not to be universally available
|
//this isnt as fast as it could be if we used a visual c++ intrinsic, but those appear not to be universally available
|
||||||
FORCEINLINE u32 u32floor(float f)
|
FORCEINLINE u32 u32floor(float f)
|
||||||
|
@ -109,6 +109,14 @@ FORCEINLINE u32 u32floor(float f)
|
||||||
return (u32)f;
|
return (u32)f;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
FORCEINLINE u32 u32floor(double d)
|
||||||
|
{
|
||||||
|
#ifndef NOSSE2
|
||||||
|
__asm cvttsd2si eax, d;
|
||||||
|
#else
|
||||||
|
return (u32)d;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//same as above but works for negative values too.
|
//same as above but works for negative values too.
|
||||||
//be sure that the results are the same thing as floorf!
|
//be sure that the results are the same thing as floorf!
|
||||||
|
|
|
@ -1833,6 +1833,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
||||||
LOG("Init sound core\n");
|
LOG("Init sound core\n");
|
||||||
sndcoretype = GetPrivateProfileInt("Sound","SoundCore", SNDCORE_DIRECTX, IniName);
|
sndcoretype = GetPrivateProfileInt("Sound","SoundCore", SNDCORE_DIRECTX, IniName);
|
||||||
sndbuffersize = GetPrivateProfileInt("Sound","SoundBufferSize", 735 * 4, IniName);
|
sndbuffersize = GetPrivateProfileInt("Sound","SoundBufferSize", 735 * 4, IniName);
|
||||||
|
CommonSettings.spuInterpolationMode = (SPUInterpolationMode)GetPrivateProfileInt("Sound","SPUInterpolation", 1, IniName);
|
||||||
|
|
||||||
EnterCriticalSection(&win_sync);
|
EnterCriticalSection(&win_sync);
|
||||||
int spu_ret = SPU_ChangeSoundCore(sndcoretype, sndbuffersize);
|
int spu_ret = SPU_ChangeSoundCore(sndcoretype, sndbuffersize);
|
||||||
|
@ -3914,6 +3915,13 @@ LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARA
|
||||||
SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_SETCURSEL, i, 0);
|
SendDlgItemMessage(hDlg, IDC_SOUNDCORECB, CB_SETCURSEL, i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//setup interpolation combobox
|
||||||
|
SendDlgItemMessage(hDlg, IDC_SPU_INTERPOLATION_CB, CB_RESETCONTENT, 0, 0);
|
||||||
|
SendDlgItemMessage(hDlg, IDC_SPU_INTERPOLATION_CB, CB_ADDSTRING, 0, (LPARAM)"None (fastest, sounds bad)");
|
||||||
|
SendDlgItemMessage(hDlg, IDC_SPU_INTERPOLATION_CB, CB_ADDSTRING, 0, (LPARAM)"Linear (typical, sounds good)");
|
||||||
|
SendDlgItemMessage(hDlg, IDC_SPU_INTERPOLATION_CB, CB_ADDSTRING, 0, (LPARAM)"Cosine (slowest, sounds best)");
|
||||||
|
SendDlgItemMessage(hDlg, IDC_SPU_INTERPOLATION_CB, CB_SETCURSEL, (int)CommonSettings.spuInterpolationMode, 0);
|
||||||
|
|
||||||
// Setup Sound Buffer Size Edit Text
|
// Setup Sound Buffer Size Edit Text
|
||||||
sprintf(tempstr, "%d", sndbuffersize);
|
sprintf(tempstr, "%d", sndbuffersize);
|
||||||
SetDlgItemText(hDlg, IDC_SOUNDBUFFERET, tempstr);
|
SetDlgItemText(hDlg, IDC_SOUNDBUFFERET, tempstr);
|
||||||
|
@ -3969,6 +3977,10 @@ LRESULT CALLBACK SoundSettingsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARA
|
||||||
WritePrivateProfileString("Sound", "Volume", tempstr, IniName);
|
WritePrivateProfileString("Sound", "Volume", tempstr, IniName);
|
||||||
SPU_SetVolume(sndvolume);
|
SPU_SetVolume(sndvolume);
|
||||||
|
|
||||||
|
//write interpolation type
|
||||||
|
CommonSettings.spuInterpolationMode = (SPUInterpolationMode)SendDlgItemMessage(hDlg, IDC_SPU_INTERPOLATION_CB, CB_GETCURSEL, 0, 0);
|
||||||
|
WritePrivateProfileInt("Sound","SPUInterpolation",(int)CommonSettings.spuInterpolationMode, IniName);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
case IDCANCEL:
|
case IDCANCEL:
|
||||||
|
|
|
@ -239,6 +239,7 @@
|
||||||
#define IDC_EDIT11 1004
|
#define IDC_EDIT11 1004
|
||||||
#define IDC_GI_GAMECODE 1004
|
#define IDC_GI_GAMECODE 1004
|
||||||
#define IDC_ROTATE90 1004
|
#define IDC_ROTATE90 1004
|
||||||
|
#define IDC_SPU_INTERPOLATION_CB 1004
|
||||||
#define IDC_ARM7BIOS 1005
|
#define IDC_ARM7BIOS 1005
|
||||||
#define IDC_EDIT07 1005
|
#define IDC_EDIT07 1005
|
||||||
#define IDC_ROTATE180 1005
|
#define IDC_ROTATE180 1005
|
||||||
|
|
|
@ -3377,7 +3377,7 @@ FONT 8, "MS Sans Serif", 0, 0, 1
|
||||||
|
|
||||||
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
IDD_SOUNDSETTINGS DIALOGEX 0, 0, 174, 96
|
IDD_SOUNDSETTINGS DIALOGEX 0, 0, 174, 127
|
||||||
STYLE DS_CENTER | DS_MODALFRAME | DS_SETFONT | WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU
|
STYLE DS_CENTER | DS_MODALFRAME | DS_SETFONT | WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU
|
||||||
CAPTION "Sound Settings"
|
CAPTION "Sound Settings"
|
||||||
FONT 8, "MS Sans Serif", 0, 0, 1
|
FONT 8, "MS Sans Serif", 0, 0, 1
|
||||||
|
@ -3385,13 +3385,15 @@ FONT 8, "MS Sans Serif", 0, 0, 1
|
||||||
GROUPBOX "Sound Core Settings", -1, 3, 2, 168, 28
|
GROUPBOX "Sound Core Settings", -1, 3, 2, 168, 28
|
||||||
LTEXT "Sound Core", -1, 10, 14, 40, 10, SS_LEFT
|
LTEXT "Sound Core", -1, 10, 14, 40, 10, SS_LEFT
|
||||||
COMBOBOX IDC_SOUNDCORECB, 54, 13, 110, 33, WS_TABSTOP | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST
|
COMBOBOX IDC_SOUNDCORECB, 54, 13, 110, 33, WS_TABSTOP | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST
|
||||||
GROUPBOX "Other Settings", -1, 3, 31, 168, 43
|
GROUPBOX "Other Settings", -1, 3, 31, 168, 61
|
||||||
LTEXT "Buffer Size", -1, 10, 42, 60, 10, SS_LEFT
|
LTEXT "Buffer Size", -1, 10, 62, 60, 10, SS_LEFT
|
||||||
EDITTEXT IDC_SOUNDBUFFERET, 136, 41, 28, 13
|
EDITTEXT IDC_SOUNDBUFFERET, 55, 61, 42, 13
|
||||||
LTEXT "Volume", -1, 10, 57, 30, 10, SS_LEFT
|
LTEXT "Volume", -1, 10, 77, 30, 10, SS_LEFT
|
||||||
CONTROL "", IDC_SLVOLUME, TRACKBAR_CLASS, 0, 40, 57, 128, 10
|
CONTROL "", IDC_SLVOLUME, TRACKBAR_CLASS, 0, 40, 77, 128, 10
|
||||||
DEFPUSHBUTTON "&OK", IDOK, 82, 78, 40, 14, BS_DEFPUSHBUTTON
|
DEFPUSHBUTTON "&OK", IDOK, 82, 97, 40, 14, BS_DEFPUSHBUTTON
|
||||||
PUSHBUTTON "&Cancel", IDCANCEL, 127, 78, 40, 14, BS_PUSHBUTTON
|
PUSHBUTTON "&Cancel", IDCANCEL, 127, 97, 40, 14, BS_PUSHBUTTON
|
||||||
|
LTEXT "Interpolation", -1, 9, 46, 40, 8, SS_LEFT
|
||||||
|
COMBOBOX IDC_SPU_INTERPOLATION_CB, 55, 42, 110, 33, WS_TABSTOP | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue