Audio: Added cubic interpolation option
This commit is contained in:
parent
45602ed530
commit
5ff456bc09
9 changed files with 64 additions and 28 deletions
|
@ -20,6 +20,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
|
||||
#include "blargg_source.h"
|
||||
#include "Spc.h"
|
||||
#include "EmuSettings.h"
|
||||
|
||||
#ifdef BLARGG_ENABLE_OPTIMIZER
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
|
@ -131,6 +132,25 @@ static short const gauss [512] =
|
|||
1299,1300,1300,1301,1302,1302,1303,1303,1303,1304,1304,1304,1304,1304,1305,1305,
|
||||
};
|
||||
|
||||
inline int SPC_DSP::interpolate_cubic(voice_t const* v)
|
||||
{
|
||||
int const* in = &v->buf[(v->interp_pos >> 12) + v->buf_pos];
|
||||
|
||||
float v0 = in[0] / 32768.0;
|
||||
float v1 = in[1] / 32768.0;
|
||||
float v2 = in[2] / 32768.0;
|
||||
float v3 = in[3] / 32768.0;
|
||||
|
||||
float a = (v3 - v2) - (v0 - v1);
|
||||
float b = (v0 - v1) - a;
|
||||
float c = v2 - v0;
|
||||
float d = v1;
|
||||
|
||||
float ratio = (double)(v->interp_pos & 0xFFF) / 0x1000;
|
||||
|
||||
return (int)((d + ratio * (c + ratio * (b + ratio * a))) * 32768);
|
||||
}
|
||||
|
||||
inline int SPC_DSP::interpolate( voice_t const* v )
|
||||
{
|
||||
// Make pointers into gaussian based on fractional position between samples
|
||||
|
@ -451,7 +471,7 @@ VOICE_CLOCK( V3c )
|
|||
|
||||
// Gaussian interpolation
|
||||
{
|
||||
int output = interpolate( v );
|
||||
int output = _settings->GetAudioConfig().EnableCubicInterpolation ? interpolate_cubic(v) : interpolate( v );
|
||||
|
||||
// Noise
|
||||
if ( m.t_non & v->vbit )
|
||||
|
@ -812,9 +832,10 @@ inline void SPC_DSP::writeRam(uint16_t addr, uint8_t value) { _spc->DspWriteRam(
|
|||
|
||||
//// Setup
|
||||
|
||||
void SPC_DSP::init( Spc *spc, void* ram_64k )
|
||||
void SPC_DSP::init( Spc *spc, EmuSettings *settings, void* ram_64k )
|
||||
{
|
||||
_spc = spc;
|
||||
_settings = settings;
|
||||
m.ram = (uint8_t*) ram_64k;
|
||||
mute_voices( 0 );
|
||||
disable_surround( false );
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
extern "C" { typedef void (*dsp_copy_func_t)( unsigned char** io, void* state, size_t ); }
|
||||
|
||||
class Spc;
|
||||
class EmuSettings;
|
||||
class SPC_DSP {
|
||||
public:
|
||||
typedef BOOST::uint8_t uint8_t;
|
||||
|
@ -15,7 +16,7 @@ public:
|
|||
// Setup
|
||||
|
||||
// Initializes DSP and has it use the 64K RAM provided
|
||||
void init( Spc* spc, void* ram_64k );
|
||||
void init( Spc* spc, EmuSettings* settings, void* ram_64k );
|
||||
|
||||
// Sets destination for output samples. If out is NULL or out_size is 0,
|
||||
// doesn't generate any.
|
||||
|
@ -191,11 +192,13 @@ private:
|
|||
};
|
||||
state_t m;
|
||||
Spc* _spc;
|
||||
EmuSettings* _settings;
|
||||
|
||||
void init_counter();
|
||||
void run_counters();
|
||||
unsigned read_counter( int rate );
|
||||
|
||||
int interpolate_cubic(voice_t const* v);
|
||||
int interpolate( voice_t const* v );
|
||||
void run_envelope( voice_t* const v );
|
||||
void decode_brr( voice_t* v );
|
||||
|
|
|
@ -119,6 +119,8 @@ struct AudioConfig
|
|||
uint32_t SampleRate = 48000;
|
||||
uint32_t AudioLatency = 60;
|
||||
|
||||
bool EnableCubicInterpolation = true;
|
||||
|
||||
bool MuteSoundInBackground = false;
|
||||
bool ReduceSoundInBackground = true;
|
||||
bool ReduceSoundInFastForward = false;
|
||||
|
|
|
@ -25,7 +25,7 @@ Spc::Spc(Console* console)
|
|||
|
||||
_dsp.reset(new SPC_DSP());
|
||||
#ifndef DUMMYSPC
|
||||
_dsp->init(this, _ram);
|
||||
_dsp->init(this, _console->GetSettings().get(), _ram);
|
||||
#endif
|
||||
_dsp->reset();
|
||||
_dsp->set_output(_soundBuffer, Spc::SampleBufferSize >> 1);
|
||||
|
|
|
@ -42,6 +42,7 @@ static constexpr const char* MesenNtscFilter = "mesen-s_ntsc_filter";
|
|||
static constexpr const char* MesenRegion = "mesen-s_region";
|
||||
static constexpr const char* MesenAspectRatio = "mesen-s_aspect_ratio";
|
||||
static constexpr const char* MesenBlendHighRes = "mesen-s_blend_high_res";
|
||||
static constexpr const char* MesenCubicInterpolation = "mesen-s_cubic_interpolation";
|
||||
static constexpr const char* MesenOverscanVertical = "mesen-s_overscan_vertical";
|
||||
static constexpr const char* MesenOverscanHorizontal = "mesen-s_overscan_horizontal";
|
||||
static constexpr const char* MesenRamState = "mesen-s_ramstate";
|
||||
|
@ -114,6 +115,7 @@ extern "C" {
|
|||
{ MesenOverscanHorizontal, "Horizontal Overscan; None|8px|16px" },
|
||||
{ MesenAspectRatio, "Aspect Ratio; Auto|No Stretching|NTSC|PAL|4:3|16:9" },
|
||||
{ MesenBlendHighRes, "Blend Hi-Res Modes; disabled|enabled" },
|
||||
{ MesenCubicInterpolation, "Cubic Interpolation (Audio); disabled|enabled" },
|
||||
{ MesenOverclock, "Overclock; None|Low|Medium|High|Very High" },
|
||||
{ MesenOverclockType, "Overclock Type; Before NMI|After NMI" },
|
||||
{ MesenSuperFxOverclock, "Super FX Clock Speed; 100%|200%|300%|400%|500%|1000%" },
|
||||
|
@ -208,6 +210,7 @@ extern "C" {
|
|||
{
|
||||
struct retro_variable var = { };
|
||||
VideoConfig video = _console->GetSettings()->GetVideoConfig();
|
||||
AudioConfig audio = _console->GetSettings()->GetAudioConfig();
|
||||
EmulationConfig emulation = _console->GetSettings()->GetEmulationConfig();
|
||||
InputConfig input = _console->GetSettings()->GetInputConfig();
|
||||
video.Brightness = 0;
|
||||
|
@ -378,6 +381,11 @@ extern "C" {
|
|||
string value = string(var.value);
|
||||
video.BlendHighResolutionModes = (value == "enabled");
|
||||
}
|
||||
|
||||
if(readVariable(MesenCubicInterpolation, var)) {
|
||||
string value = string(var.value);
|
||||
audio.EnableCubicInterpolation = (value == "enabled");
|
||||
}
|
||||
|
||||
auto getKeyCode = [=](int port, int retroKey) {
|
||||
return (port << 8) | (retroKey + 1);
|
||||
|
@ -412,6 +420,7 @@ extern "C" {
|
|||
_console->GetSettings()->SetVideoConfig(video);
|
||||
_console->GetSettings()->SetEmulationConfig(emulation);
|
||||
_console->GetSettings()->SetInputConfig(input);
|
||||
_console->GetSettings()->SetAudioConfig(audio);
|
||||
|
||||
retro_system_av_info avInfo = {};
|
||||
_renderer->GetSystemAudioVideoInfo(avInfo);
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace Mesen.GUI.Config
|
|||
[ValidValues(11025, 22050, 32000, 44100, 48000, 96000)] public UInt32 SampleRate = 48000;
|
||||
[MinMax(15, 300)] public UInt32 AudioLatency = 60;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EnableCubicInterpolation = true;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool MuteSoundInBackground = false;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ReduceSoundInBackground = true;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ReduceSoundInFastForward = false;
|
||||
|
|
|
@ -119,32 +119,13 @@
|
|||
<Control ID="tpgGeneral">General</Control>
|
||||
<Control ID="tpgAdvanced">Advanced</Control>
|
||||
<Control ID="chkDisableDynamicSampleRate">Disable dynamic sample rate</Control>
|
||||
<Control ID="chkSwapDutyCycles">Swap square channels duty cycles (Mimics old clones)</Control>
|
||||
<Control ID="chkSilenceTriangleHighFreq">Mute ultrasonic frequencies on triangle channel (reduces popping)</Control>
|
||||
<Control ID="chkReduceDmcPopping">Reduce popping sounds on the DMC channel</Control>
|
||||
<Control ID="chkDisableNoiseModeFlag">Disable noise channel mode flag</Control>
|
||||
<Control ID="tpgEffects">Effects</Control>
|
||||
<Control ID="grpStereo">Stereo</Control>
|
||||
<Control ID="radStereoDisabled">Disabled</Control>
|
||||
<Control ID="radStereoDelay">Delay</Control>
|
||||
<Control ID="radStereoPanning">Panning</Control>
|
||||
<Control ID="lblStereoDelayMs">ms</Control>
|
||||
<Control ID="lblStereoPanningAngle">(Angle in degrees)</Control>
|
||||
<Control ID="radStereoCombFilter">Comb Filter</Control>
|
||||
<Control ID="lblStereoCombFilterMs">ms</Control>
|
||||
<Control ID="lblStereoCombFilterDelay">Delay:</Control>
|
||||
<Control ID="lblStereoCombFilterStrength">Strength:</Control>
|
||||
<Control ID="chkCrossFeedEnabled">Enable Crossfeed:</Control>
|
||||
<Control ID="grpReverb">Reverb</Control>
|
||||
<Control ID="chkReverbEnabled">Enable Reverb</Control>
|
||||
<Control ID="lblReverbDelay">Delay:</Control>
|
||||
<Control ID="lblReverbStrength">Strength:</Control>
|
||||
<Control ID="chkMuteSoundInBackground">Mute sound when in background</Control>
|
||||
<Control ID="chkReduceSoundInBackground">Reduce volume when in background</Control>
|
||||
<Control ID="chkReduceSoundInFastForward">Reduce volume during fast forward/rewind</Control>
|
||||
<Control ID="trkVolumeReduction">Volume Reduction (%)</Control>
|
||||
<Control ID="lblVolumeReductionSettings">Volume Reduction Settings</Control>
|
||||
<Control ID="chkEnableAudio">Enable Audio</Control>
|
||||
<Control ID="chkEnableCubicInterpolation">Enable cubic interpolation</Control>
|
||||
<Control ID="lblSampleRate">Sample Rate:</Control>
|
||||
<Control ID="lblLatencyMs">ms</Control>
|
||||
<Control ID="lblLatencyWarning">Low values may cause sound problems</Control>
|
||||
|
|
24
UI/Forms/Config/frmAudioConfig.Designer.cs
generated
24
UI/Forms/Config/frmAudioConfig.Designer.cs
generated
|
@ -76,6 +76,7 @@
|
|||
this.tpgAdvanced = new System.Windows.Forms.TabPage();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkDisableDynamicSampleRate = new Mesen.GUI.Controls.ctrlRiskyOption();
|
||||
this.chkEnableCubicInterpolation = new System.Windows.Forms.CheckBox();
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tpgGeneral.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
|
@ -298,6 +299,7 @@
|
|||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudLatency.IsHex = false;
|
||||
this.nudLatency.Location = new System.Drawing.Point(3, 3);
|
||||
this.nudLatency.Maximum = new decimal(new int[] {
|
||||
300,
|
||||
|
@ -890,11 +892,13 @@
|
|||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 1;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkDisableDynamicSampleRate, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkDisableDynamicSampleRate, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkEnableCubicInterpolation, 0, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(478, 346);
|
||||
|
@ -903,12 +907,22 @@
|
|||
// chkDisableDynamicSampleRate
|
||||
//
|
||||
this.chkDisableDynamicSampleRate.Checked = false;
|
||||
this.chkDisableDynamicSampleRate.Location = new System.Drawing.Point(0, 0);
|
||||
this.chkDisableDynamicSampleRate.Location = new System.Drawing.Point(0, 23);
|
||||
this.chkDisableDynamicSampleRate.Name = "chkDisableDynamicSampleRate";
|
||||
this.chkDisableDynamicSampleRate.Size = new System.Drawing.Size(463, 24);
|
||||
this.chkDisableDynamicSampleRate.TabIndex = 5;
|
||||
this.chkDisableDynamicSampleRate.Text = "Disable dynamic sample rate";
|
||||
//
|
||||
// chkEnableCubicInterpolation
|
||||
//
|
||||
this.chkEnableCubicInterpolation.AutoSize = true;
|
||||
this.chkEnableCubicInterpolation.Location = new System.Drawing.Point(3, 3);
|
||||
this.chkEnableCubicInterpolation.Name = "chkEnableCubicInterpolation";
|
||||
this.chkEnableCubicInterpolation.Size = new System.Drawing.Size(148, 17);
|
||||
this.chkEnableCubicInterpolation.TabIndex = 6;
|
||||
this.chkEnableCubicInterpolation.Text = "Enable cubic interpolation";
|
||||
this.chkEnableCubicInterpolation.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// frmAudioConfig
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -938,6 +952,7 @@
|
|||
this.tlpEqualizer.ResumeLayout(false);
|
||||
this.tpgAdvanced.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@ -994,5 +1009,6 @@
|
|||
private System.Windows.Forms.TabPage tpgAdvanced;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private Controls.ctrlRiskyOption chkDisableDynamicSampleRate;
|
||||
}
|
||||
private System.Windows.Forms.CheckBox chkEnableCubicInterpolation;
|
||||
}
|
||||
}
|
|
@ -30,6 +30,8 @@ namespace Mesen.GUI.Forms.Config
|
|||
AddBinding(nameof(AudioConfig.SampleRate), cboSampleRate);
|
||||
AddBinding(nameof(AudioConfig.AudioDevice), cboAudioDevice);
|
||||
AddBinding(nameof(AudioConfig.DisableDynamicSampleRate), chkDisableDynamicSampleRate);
|
||||
|
||||
AddBinding(nameof(AudioConfig.EnableCubicInterpolation), chkEnableCubicInterpolation);
|
||||
|
||||
AddBinding(nameof(AudioConfig.EnableEqualizer), chkEnableEqualizer);
|
||||
AddBinding(nameof(AudioConfig.Band1Gain), trkBand1Gain);
|
||||
|
|
Loading…
Add table
Reference in a new issue