Completed sound interpolation optimization. Now calculates

sound rates in response to GBA timer adjustments instead
of recalculating on every sample.
This commit is contained in:
DJRobX 2007-11-05 08:59:52 +00:00
parent b5745f7a39
commit db60506ec6
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}
EndProjectSection
EndProject
Project("{4CAA2610-1955-4629-BDC1-8133FE0B2087}") = "profiler", "..\profiler\profiler.aqt", "{7260A190-9B72-4227-B01C-29E53BA53413}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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