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:
parent
b5745f7a39
commit
db60506ec6
2
VBA.sln
2
VBA.sln
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
10
src/GBA.cpp
10
src/GBA.cpp
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue