Completed sound interpolation optimization. Now calculates

sound rates in response to GBA timer adjustments instead
of recalculating on every sample.



git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@18 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
DJRobX 2007-11-05 08:59:52 +00:00
parent 27bcb9ad94
commit 52c4a1dbba
8 changed files with 40 additions and 110 deletions

View File

@ -13,8 +13,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "libpng\libpng.vcp
{34DC39BF-F93A-4573-85BF-789B90B63179} = {34DC39BF-F93A-4573-85BF-789B90B63179} {34DC39BF-F93A-4573-85BF-789B90B63179} = {34DC39BF-F93A-4573-85BF-789B90B63179}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{4CAA2610-1955-4629-BDC1-8133FE0B2087}") = "profiler", "..\profiler\profiler.aqt", "{7260A190-9B72-4227-B01C-29E53BA53413}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32

View File

@ -1632,6 +1632,14 @@
<File <File
RelativePath=".\libresample-0.1.3\src\filterkit.c" RelativePath=".\libresample-0.1.3\src\filterkit.c"
> >
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
DebugInformationFormat="4"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\libresample-0.1.3\src\resample.c" RelativePath=".\libresample-0.1.3\src\resample.c"

View File

@ -2568,7 +2568,8 @@ void CPUUpdateRegister(u32 address, u16 value)
break; break;
case 0x100: case 0x100:
timer0Reload = value; timer0Reload = value;
break; interp_rate();
break;
case 0x102: case 0x102:
timer0Ticks = timer0ClockReload = TIMER_TICKS[value & 3]; timer0Ticks = timer0ClockReload = TIMER_TICKS[value & 3];
if(!timer0On && (value & 0x80)) { if(!timer0On && (value & 0x80)) {
@ -2584,11 +2585,13 @@ void CPUUpdateRegister(u32 address, u16 value)
timer0On = value & 0x80 ? true : false; timer0On = value & 0x80 ? true : false;
TM0CNT = value & 0xC7; TM0CNT = value & 0xC7;
UPDATE_REG(0x102, TM0CNT); UPDATE_REG(0x102, TM0CNT);
interp_rate();
// CPUUpdateTicks(); // CPUUpdateTicks();
break; break;
case 0x104: case 0x104:
timer1Reload = value; timer1Reload = value;
break; interp_rate();
break;
case 0x106: case 0x106:
timer1Ticks = timer1ClockReload = TIMER_TICKS[value & 3]; timer1Ticks = timer1ClockReload = TIMER_TICKS[value & 3];
if(!timer1On && (value & 0x80)) { if(!timer1On && (value & 0x80)) {
@ -2604,7 +2607,8 @@ void CPUUpdateRegister(u32 address, u16 value)
timer1On = value & 0x80 ? true : false; timer1On = value & 0x80 ? true : false;
TM1CNT = value & 0xC7; TM1CNT = value & 0xC7;
UPDATE_REG(0x106, TM1CNT); UPDATE_REG(0x106, TM1CNT);
break; interp_rate();
break;
case 0x108: case 0x108:
timer2Reload = value; timer2Reload = value;
break; break;

View File

@ -659,11 +659,11 @@ int openLinkLog(void){
char filename[20]; char filename[20];
if(linklog){ if(linklog){
sprintf(filename, "vbalog%1d.txt", vbaid+1); sprintf(filename, "vbalog%1d.txt", vbaid+1);
if((linklogfile=fopen(filename, "wt"))==NULL){ if((linklogfile=fopen(filename, "at"))==NULL){
linklog=false; linklog=false;
return 0; return 0;
} }
fprintf(linklogfile, "GBA0 GBA1 GBA2 GBA3 clocks between transfers\n"); fprintf(linklogfile, "----- Log opened -----\n");
} }
return 1; return 1;
} }

View File

@ -363,18 +363,22 @@ void interp_switch(int which)
delete interp[i]; delete interp[i];
interp[i] = get_filter(which); interp[i] = get_filter(which);
} }
interp_rate();
interpolation = which; interpolation = which;
} }
void interp_rate()
{
interp[0]->rate(calc_rate(soundDSATimer));
interp[1]->rate(calc_rate(soundDSBTimer));
}
void interp_reset(int ch) void interp_reset(int ch)
{ {
setSoundFn(); setSoundFn();
#ifdef ENHANCED_RATE
interp[ch]->reset(); interp[ch]->reset();
#else interp_rate();
interp[ch]->reset(calc_rate(ch ? soundDSATimer : soundDSBTimer));
#endif
} }
@ -588,7 +592,6 @@ void soundEvent(u32 address, u16 data)
data &= 0xFF0F; data &= 0xFF0F;
soundControl = data & 0x770F;; soundControl = data & 0x770F;;
if(data & 0x0800) { if(data & 0x0800) {
interp_reset(0);
soundDSFifoAWriteIndex = 0; soundDSFifoAWriteIndex = 0;
soundDSFifoAIndex = 0; soundDSFifoAIndex = 0;
soundDSFifoACount = 0; soundDSFifoACount = 0;
@ -598,7 +601,6 @@ void soundEvent(u32 address, u16 data)
soundDSAEnabled = (data & 0x0300) ? true : false; soundDSAEnabled = (data & 0x0300) ? true : false;
soundDSATimer = (data & 0x0400) ? 1 : 0; soundDSATimer = (data & 0x0400) ? 1 : 0;
if(data & 0x8000) { if(data & 0x8000) {
interp_reset(1);
soundDSFifoBWriteIndex = 0; soundDSFifoBWriteIndex = 0;
soundDSFifoBIndex = 0; soundDSFifoBIndex = 0;
soundDSFifoBCount = 0; soundDSFifoBCount = 0;
@ -607,7 +609,12 @@ void soundEvent(u32 address, u16 data)
} }
soundDSBEnabled = (data & 0x3000) ? true : false; soundDSBEnabled = (data & 0x3000) ? true : false;
soundDSBTimer = (data & 0x4000) ? 1 : 0; soundDSBTimer = (data & 0x4000) ? 1 : 0;
*((u16 *)&ioMem[address]) = data; if (data & 0x8000)
{
interp_reset(0);
interp_reset(1);
}
*((u16 *)&ioMem[address]) = data;
break; break;
case FIFOA_L: case FIFOA_L:
case FIFOA_H: case FIFOA_H:
@ -704,7 +711,6 @@ void soundDirectSoundATimer()
soundEvent(FIFOA_H, (u16)0); soundEvent(FIFOA_H, (u16)0);
} }
} }
soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]); soundDSAValue = (soundDSFifoA[soundDSFifoAIndex]);
interp_push(0, (s8)soundDSAValue << 8); interp_push(0, (s8)soundDSAValue << 8);
soundDSFifoAIndex = (++soundDSFifoAIndex) & 31; soundDSFifoAIndex = (++soundDSFifoAIndex) & 31;

View File

@ -96,5 +96,7 @@ extern Gb_Apu * apu;
extern const BOOST::uint8_t sound_data [Gb_Apu::register_count]; extern const BOOST::uint8_t sound_data [Gb_Apu::register_count];
extern void interp_rate();
#endif // VBA_SOUND_H #endif // VBA_SOUND_H

View File

@ -202,20 +202,14 @@ public:
foo_null() : sample(0) {} foo_null() : sample(0) {}
~foo_null() {} ~foo_null() {}
#ifdef ENHANCED_RATE
void reset() {} void reset() {}
#endif
void push(int psample) void push(int psample)
{ {
sample = psample; sample = psample;
} }
#ifdef ENHANCED_RATE
int pop(double rate)
#else
int pop() int pop()
#endif
{ {
return sample; return sample;
} }
@ -240,14 +234,8 @@ public:
~foo_linear() {} ~foo_linear() {}
#ifdef ENHANCED_RATE
void reset() void reset()
{ {
#else
void reset(double rate)
{
foo_interpolate::reset(rate);
#endif
position = 0; position = 0;
samples.clear(); samples.clear();
} }
@ -258,14 +246,8 @@ public:
samples.push_back(sample); samples.push_back(sample);
} }
#ifdef ENHANCED_RATE
int pop(double rate)
{
int lrate;
#else
int pop() int pop()
{ {
#endif
int ret; int ret;
if (position > 0x7fff) if (position > 0x7fff)
@ -281,18 +263,9 @@ public:
ret += smp(1) * position; ret += smp(1) * position;
ret >>= 15; ret >>= 15;
#ifdef ENHANCED_RATE
// wahoo, takes care of drifting // wahoo, takes care of drifting
if (samples.size() > 2)
{
rate += (.5 / 32768.);
}
lrate = (int)(32768. * rate);
#else
if (samples.size() > 2) if (samples.size() > 2)
position+=1; position+=1;
#endif
position += lrate; position += lrate;
return ret; return ret;
@ -332,14 +305,8 @@ public:
samples.push_back(sample); samples.push_back(sample);
} }
#ifdef ENHANCED_RATE
int pop(double rate)
{
int lrate;
#else
int pop() int pop()
{ {
#endif
int ret; int ret;
if (position > 0x7fff) if (position > 0x7fff)
@ -368,14 +335,8 @@ public:
// wahoo, takes care of drifting // wahoo, takes care of drifting
if (samples.size() > 8) if (samples.size() > 8)
{ {
#ifdef ENHANCED_RATE
rate += (.5 / 32768.);
}
lrate = (int)(32768. * rate);
#else
position+=1; position+=1;
} }
#endif
position += lrate; position += lrate;
return ret; return ret;
@ -401,14 +362,8 @@ public:
~foo_fir() {} ~foo_fir() {}
#ifdef ENHANCED_RATE
void reset() void reset()
{ {
#else
void reset(double rate)
{
foo_interpolate::reset(rate);
#endif
position = 0; position = 0;
samples.clear(); samples.clear();
} }
@ -418,14 +373,8 @@ public:
samples.push_back(sample); samples.push_back(sample);
} }
#ifdef ENHANCED_RATE
int pop(double rate)
{
int lrate;
#else
int pop() int pop()
{ {
#endif
int ret; int ret;
if (position > 0x7fff) if (position > 0x7fff)
@ -450,21 +399,11 @@ public:
if (ret > 32767) ret = 32767; if (ret > 32767) ret = 32767;
else if (ret < -32768) ret = -32768; else if (ret < -32768) ret = -32768;
#ifdef ENHANCED_RATE
// wahoo, takes care of drifting // wahoo, takes care of drifting
if (samples.size() > 16)
{
rate += (.5 / 32768.);
}
lrate = (int)(32768. * rate);
position += lrate;
#else
if (samples.size() > 16) if (samples.size() > 16)
position+=1; position+=1;
position+=9929; position+=lrate;
#endif
return ret; return ret;
} }
}; };
@ -483,22 +422,11 @@ public:
~foo_libresample() ~foo_libresample()
{ {
#ifdef ENHANCED_RATE
reset(); reset();
#else
reset(1);
#endif
} }
#ifdef ENHANCED_RATE
void reset() void reset()
{ {
#else
void reset(double rate)
{
foo_interpolate::reset(rate);
#endif
samples.clear(); samples.clear();
if (resampler) if (resampler)
{ {
@ -512,13 +440,8 @@ public:
samples.push_back(float(sample)); samples.push_back(float(sample));
} }
#ifdef ENHANCED_RATE
int pop(double rate)
{
#else
int pop() int pop()
{ {
#endif
int ret; int ret;
if (!resampler) if (!resampler)
{ {
@ -536,11 +459,7 @@ public:
in[used] = samples[used]; in[used] = samples[used];
} }
#ifdef ENHANCED_RATE returned = resample_process(resampler, 32767 / lrate, in, count, 0, &used, &out, 1);
returned = resample_process(resampler, 1. / rate, in, count, 0, &used, &out, 1);
#else
returned = resample_process(resampler, lrate / 32767, in, count, 0, &used, &out, 1);
#endif
if (used) if (used)
{ {
samples.erase(used); samples.erase(used);

View File

@ -1,8 +1,8 @@
#ifndef __SND_INTERP_H__ #ifndef __SND_INTERP_H__
#define __SND_INTERP_H__ #define __SND_INTERP_H__
// simple interface that could easily be recycled #include <stdio.h>
#define ENHANCED_RATE #include <windows.h>
class foo_interpolate class foo_interpolate
{ {
@ -10,24 +10,17 @@ public:
foo_interpolate() {} foo_interpolate() {}
virtual ~foo_interpolate() {}; virtual ~foo_interpolate() {};
#ifdef ENHANCED_RATE
virtual void reset() = 0; virtual void reset() = 0;
#else
long lrate; long lrate;
virtual void reset(double rate) virtual void rate(double rate)
{ {
lrate = (int)(32768. * rate); lrate = (int)(32768. * rate);
}; };
#endif
virtual void push(int sample) = 0; virtual void push(int sample) = 0;
#ifdef ENHANCED_RATE
virtual int pop(double rate) = 0;
#else
virtual int pop() = 0; virtual int pop() = 0;
#endif
}; };
extern foo_interpolate * get_filter(int which); extern foo_interpolate * get_filter(int which);