mirror of https://github.com/stella-emu/stella.git
Remove high frequency artifacts from Lanczos resampling.
Run the TIA signal through a high pass with 10Hz cutoff.
This commit is contained in:
parent
8298ad4d26
commit
a4d923cbe6
|
@ -0,0 +1,41 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony
|
||||||
|
// and the Stella Team
|
||||||
|
//
|
||||||
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "HighPass.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
HighPass::HighPass(float cutOffFrequency, float frequency)
|
||||||
|
: myLastValueIn(0),
|
||||||
|
myLastValueOut(0),
|
||||||
|
myAlpha(1.f / (1.f + 2.f*M_PI*cutOffFrequency/frequency))
|
||||||
|
{}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
float HighPass::apply(float valueIn)
|
||||||
|
{
|
||||||
|
float valueOut = myAlpha * (myLastValueOut + valueIn - myLastValueIn);
|
||||||
|
|
||||||
|
myLastValueIn = valueIn;
|
||||||
|
myLastValueOut = valueOut;
|
||||||
|
|
||||||
|
return valueOut;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony
|
||||||
|
// and the Stella Team
|
||||||
|
//
|
||||||
|
// See the file "License.txt" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef HIGH_PASS_HXX
|
||||||
|
#define HIGH_PASS_HXX
|
||||||
|
|
||||||
|
class HighPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
HighPass(float cutOffFrequency, float frequency);
|
||||||
|
|
||||||
|
float apply(float value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
float myLastValueIn;
|
||||||
|
|
||||||
|
float myLastValueOut;
|
||||||
|
|
||||||
|
float myAlpha;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
HighPass() = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HIGH_PASS_HXX
|
|
@ -25,6 +25,7 @@
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr float CLIPPING_FACTOR = 0.75;
|
constexpr float CLIPPING_FACTOR = 0.75;
|
||||||
|
constexpr float HIGH_PASS_CUT_OFF = 10;
|
||||||
|
|
||||||
uInt32 reducedDenominator(uInt32 n, uInt32 d)
|
uInt32 reducedDenominator(uInt32 n, uInt32 d)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +79,9 @@ LanczosResampler::LanczosResampler(
|
||||||
myCurrentFragment(nullptr),
|
myCurrentFragment(nullptr),
|
||||||
myFragmentIndex(0),
|
myFragmentIndex(0),
|
||||||
myIsUnderrun(true),
|
myIsUnderrun(true),
|
||||||
|
myHighPassL(HIGH_PASS_CUT_OFF, formatFrom.sampleRate),
|
||||||
|
myHighPassR(HIGH_PASS_CUT_OFF, formatFrom.sampleRate),
|
||||||
|
myHighPass(HIGH_PASS_CUT_OFF, formatFrom.sampleRate),
|
||||||
myTimeIndex(0)
|
myTimeIndex(0)
|
||||||
{
|
{
|
||||||
myPrecomputedKernels = make_unique<float[]>(myPrecomputedKernelCount * myKernelSize);
|
myPrecomputedKernels = make_unique<float[]>(myPrecomputedKernelCount * myKernelSize);
|
||||||
|
@ -184,11 +188,11 @@ inline void LanczosResampler::shiftSamples(uInt32 samplesToShift)
|
||||||
{
|
{
|
||||||
while (samplesToShift-- > 0) {
|
while (samplesToShift-- > 0) {
|
||||||
if (myFormatFrom.stereo) {
|
if (myFormatFrom.stereo) {
|
||||||
myBufferL->shift(myCurrentFragment[2*myFragmentIndex] / static_cast<float>(0x7fff));
|
myBufferL->shift(myHighPassL.apply(myCurrentFragment[2*myFragmentIndex] / static_cast<float>(0x7fff)));
|
||||||
myBufferR->shift(myCurrentFragment[2*myFragmentIndex + 1] / static_cast<float>(0x7fff));
|
myBufferR->shift(myHighPassR.apply(myCurrentFragment[2*myFragmentIndex + 1] / static_cast<float>(0x7fff)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
myBuffer->shift(myCurrentFragment[myFragmentIndex] / static_cast<float>(0x7fff));
|
myBuffer->shift(myHighPass.apply(myCurrentFragment[myFragmentIndex] / static_cast<float>(0x7fff)));
|
||||||
|
|
||||||
myFragmentIndex++;
|
myFragmentIndex++;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "Resampler.hxx"
|
#include "Resampler.hxx"
|
||||||
#include "ConvolutionBuffer.hxx"
|
#include "ConvolutionBuffer.hxx"
|
||||||
|
#include "HighPass.hxx"
|
||||||
|
|
||||||
class LanczosResampler : public Resampler
|
class LanczosResampler : public Resampler
|
||||||
{
|
{
|
||||||
|
@ -59,6 +60,10 @@ class LanczosResampler : public Resampler
|
||||||
uInt32 myFragmentIndex;
|
uInt32 myFragmentIndex;
|
||||||
bool myIsUnderrun;
|
bool myIsUnderrun;
|
||||||
|
|
||||||
|
HighPass myHighPassL;
|
||||||
|
HighPass myHighPassR;
|
||||||
|
HighPass myHighPass;
|
||||||
|
|
||||||
uInt32 myTimeIndex;
|
uInt32 myTimeIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ MODULE := src/common/audio
|
||||||
MODULE_OBJS := \
|
MODULE_OBJS := \
|
||||||
src/common/audio/SimpleResampler.o \
|
src/common/audio/SimpleResampler.o \
|
||||||
src/common/audio/ConvolutionBuffer.o \
|
src/common/audio/ConvolutionBuffer.o \
|
||||||
src/common/audio/LanczosResampler.o
|
src/common/audio/LanczosResampler.o \
|
||||||
|
src/common/audio/HighPass.o
|
||||||
|
|
||||||
MODULE_DIRS += \
|
MODULE_DIRS += \
|
||||||
src/emucore/tia
|
src/emucore/tia
|
||||||
|
|
Loading…
Reference in New Issue