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:
parent
27bcb9ad94
commit
52c4a1dbba
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}
|
{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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
10
src/GBA.cpp
10
src/GBA.cpp
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue