add setting to disable DC offset correction
This commit is contained in:
parent
38103d9c1f
commit
717e75f82d
|
@ -67,6 +67,7 @@ struct blip_t
|
||||||
int avail;
|
int avail;
|
||||||
int size;
|
int size;
|
||||||
int integrator;
|
int integrator;
|
||||||
|
unsigned char hipass;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int buf_t;
|
typedef int buf_t;
|
||||||
|
@ -119,6 +120,7 @@ blip_t* blip_new( int size )
|
||||||
{
|
{
|
||||||
m->factor = time_unit / blip_max_ratio;
|
m->factor = time_unit / blip_max_ratio;
|
||||||
m->size = size;
|
m->size = size;
|
||||||
|
m->hipass = 1;
|
||||||
blip_clear( m );
|
blip_clear( m );
|
||||||
check_assumptions();
|
check_assumptions();
|
||||||
}
|
}
|
||||||
|
@ -135,6 +137,10 @@ void blip_delete( blip_t* m )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void blip_set_dc( blip_t* m, unsigned char enable ) {
|
||||||
|
m->hipass=enable;
|
||||||
|
}
|
||||||
|
|
||||||
void blip_set_rates( blip_t* m, double clock_rate, double sample_rate )
|
void blip_set_rates( blip_t* m, double clock_rate, double sample_rate )
|
||||||
{
|
{
|
||||||
double factor = time_unit * sample_rate / clock_rate;
|
double factor = time_unit * sample_rate / clock_rate;
|
||||||
|
@ -231,7 +237,9 @@ int blip_read_samples( blip_t* m, short out [], int count, int stereo )
|
||||||
out += step;
|
out += step;
|
||||||
|
|
||||||
/* High-pass filter */
|
/* High-pass filter */
|
||||||
sum -= s << (delta_bits - bass_shift);
|
if (m->hipass) {
|
||||||
|
sum -= s << (delta_bits - bass_shift);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while ( in != end );
|
while ( in != end );
|
||||||
m->integrator = sum;
|
m->integrator = sum;
|
||||||
|
|
|
@ -5,6 +5,9 @@ Sample buffer that resamples from input clock rate to output sample rate */
|
||||||
#ifndef BLIP_BUF_H
|
#ifndef BLIP_BUF_H
|
||||||
#define BLIP_BUF_H
|
#define BLIP_BUF_H
|
||||||
|
|
||||||
|
// MODIFIED by tildearrow:
|
||||||
|
// - add option to disable high-pass filter
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +21,9 @@ so that there are blip_max_ratio clocks per sample. Returns pointer to new
|
||||||
buffer, or NULL if insufficient memory. */
|
buffer, or NULL if insufficient memory. */
|
||||||
blip_t* blip_new( int sample_count );
|
blip_t* blip_new( int sample_count );
|
||||||
|
|
||||||
|
/** (tildearrow) sets whether to enable high-pass filter. */
|
||||||
|
void blip_set_dc( blip_t*, unsigned char enable );
|
||||||
|
|
||||||
/** Sets approximate input clock rate and output sample rate. For every
|
/** Sets approximate input clock rate and output sample rate. For every
|
||||||
clock_rate input clocks, approximately sample_rate samples are generated. */
|
clock_rate input clocks, approximately sample_rate samples are generated. */
|
||||||
void blip_set_rates( blip_t*, double clock_rate, double sample_rate );
|
void blip_set_rates( blip_t*, double clock_rate, double sample_rate );
|
||||||
|
|
|
@ -4,6 +4,11 @@ Author : Shay Green <gblargg@gmail.com>
|
||||||
Website : http://www.slack.net/~ant/
|
Website : http://www.slack.net/~ant/
|
||||||
License : GNU Lesser General Public License (LGPL)
|
License : GNU Lesser General Public License (LGPL)
|
||||||
|
|
||||||
|
MODIFICATION DISCLAIMER
|
||||||
|
-----------------------
|
||||||
|
I have modified this library in order to add a function that disables the DC offset correction high-pass filter.
|
||||||
|
- tildearrow
|
||||||
|
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -96,8 +96,13 @@ void DivDispatchContainer::setRates(double gotRate) {
|
||||||
rateMemory=gotRate;
|
rateMemory=gotRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivDispatchContainer::setQuality(bool lowQual) {
|
void DivDispatchContainer::setQuality(bool lowQual, bool dcHiPass) {
|
||||||
lowQuality=lowQual;
|
lowQuality=lowQual;
|
||||||
|
hiPass=dcHiPass;
|
||||||
|
for (int i=0; i<DIV_MAX_OUTPUTS; i++) {
|
||||||
|
if (bb[i]==NULL) continue;
|
||||||
|
blip_set_dc(bb[i],dcHiPass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivDispatchContainer::grow(size_t size) {
|
void DivDispatchContainer::grow(size_t size) {
|
||||||
|
@ -123,6 +128,7 @@ void DivDispatchContainer::grow(size_t size) {
|
||||||
logE("not enough memory!"); \
|
logE("not enough memory!"); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
|
blip_set_dc(bb[i],hiPass); \
|
||||||
blip_set_rates(bb[i],dispatch->rate,rateMemory); \
|
blip_set_rates(bb[i],dispatch->rate,rateMemory); \
|
||||||
\
|
\
|
||||||
if (bbIn[i]==NULL) bbIn[i]=new short[bbInLen]; \
|
if (bbIn[i]==NULL) bbIn[i]=new short[bbInLen]; \
|
||||||
|
@ -621,6 +627,7 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
||||||
bbOut[i]=new short[bbInLen];
|
bbOut[i]=new short[bbInLen];
|
||||||
memset(bbIn[i],0,bbInLen*sizeof(short));
|
memset(bbIn[i],0,bbInLen*sizeof(short));
|
||||||
memset(bbOut[i],0,bbInLen*sizeof(short));
|
memset(bbOut[i],0,bbInLen*sizeof(short));
|
||||||
|
blip_set_dc(bb[i],hiPass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3353,7 +3353,7 @@ bool DivEngine::switchMaster(bool full) {
|
||||||
if (initAudioBackend()) {
|
if (initAudioBackend()) {
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
disCont[i].setRates(got.rate);
|
disCont[i].setRates(got.rate);
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality,dcHiPass);
|
||||||
}
|
}
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating audio!");
|
logE("error while activating audio!");
|
||||||
|
@ -3452,10 +3452,14 @@ void DivEngine::initDispatch(bool isRender) {
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
logV("initializing dispatch...");
|
logV("initializing dispatch...");
|
||||||
if (isRender) logI("render cores set");
|
if (isRender) logI("render cores set");
|
||||||
|
|
||||||
|
lowQuality=getConfInt("audioQuality",0);
|
||||||
|
dcHiPass=getConfInt("audioHiPass",1);
|
||||||
|
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
disCont[i].init(song.system[i],this,getChannelCount(song.system[i]),got.rate,song.systemFlags[i],isRender);
|
disCont[i].init(song.system[i],this,getChannelCount(song.system[i]),got.rate,song.systemFlags[i],isRender);
|
||||||
disCont[i].setRates(got.rate);
|
disCont[i].setRates(got.rate);
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality,dcHiPass);
|
||||||
}
|
}
|
||||||
if (song.patchbayAuto) {
|
if (song.patchbayAuto) {
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
|
@ -3534,7 +3538,6 @@ bool DivEngine::initAudioBackend() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lowQuality=getConfInt("audioQuality",0);
|
|
||||||
forceMono=getConfInt("forceMono",0);
|
forceMono=getConfInt("forceMono",0);
|
||||||
clampSamples=getConfInt("clampSamples",0);
|
clampSamples=getConfInt("clampSamples",0);
|
||||||
lowLatency=getConfInt("lowLatency",0);
|
lowLatency=getConfInt("lowLatency",0);
|
||||||
|
@ -3782,6 +3785,7 @@ bool DivEngine::init() {
|
||||||
logE("not enough memory!");
|
logE("not enough memory!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
blip_set_dc(samp_bb,0);
|
||||||
|
|
||||||
samp_bbOut=new short[32768];
|
samp_bbOut=new short[32768];
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ struct DivDispatchContainer {
|
||||||
short* bbInMapped[DIV_MAX_OUTPUTS];
|
short* bbInMapped[DIV_MAX_OUTPUTS];
|
||||||
short* bbIn[DIV_MAX_OUTPUTS];
|
short* bbIn[DIV_MAX_OUTPUTS];
|
||||||
short* bbOut[DIV_MAX_OUTPUTS];
|
short* bbOut[DIV_MAX_OUTPUTS];
|
||||||
bool lowQuality, dcOffCompensation;
|
bool lowQuality, dcOffCompensation, hiPass;
|
||||||
double rateMemory;
|
double rateMemory;
|
||||||
|
|
||||||
// used in multi-thread
|
// used in multi-thread
|
||||||
|
@ -213,7 +213,7 @@ struct DivDispatchContainer {
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
|
||||||
void setRates(double gotRate);
|
void setRates(double gotRate);
|
||||||
void setQuality(bool lowQual);
|
void setQuality(bool lowQual, bool dcHiPass);
|
||||||
void grow(size_t size);
|
void grow(size_t size);
|
||||||
void acquire(size_t offset, size_t count);
|
void acquire(size_t offset, size_t count);
|
||||||
void flush(size_t count);
|
void flush(size_t count);
|
||||||
|
@ -230,6 +230,7 @@ struct DivDispatchContainer {
|
||||||
lastAvail(0),
|
lastAvail(0),
|
||||||
lowQuality(false),
|
lowQuality(false),
|
||||||
dcOffCompensation(false),
|
dcOffCompensation(false),
|
||||||
|
hiPass(true),
|
||||||
rateMemory(0.0),
|
rateMemory(0.0),
|
||||||
cycles(0),
|
cycles(0),
|
||||||
size(0) {
|
size(0) {
|
||||||
|
@ -389,6 +390,7 @@ class DivEngine {
|
||||||
int chans;
|
int chans;
|
||||||
bool active;
|
bool active;
|
||||||
bool lowQuality;
|
bool lowQuality;
|
||||||
|
bool dcHiPass;
|
||||||
bool playing;
|
bool playing;
|
||||||
bool freelance;
|
bool freelance;
|
||||||
bool shallStop, shallStopSched;
|
bool shallStop, shallStopSched;
|
||||||
|
@ -1224,6 +1226,7 @@ class DivEngine {
|
||||||
chans(0),
|
chans(0),
|
||||||
active(false),
|
active(false),
|
||||||
lowQuality(false),
|
lowQuality(false),
|
||||||
|
dcHiPass(true),
|
||||||
playing(false),
|
playing(false),
|
||||||
freelance(false),
|
freelance(false),
|
||||||
shallStop(false),
|
shallStop(false),
|
||||||
|
|
|
@ -111,7 +111,7 @@ void DivEngine::runExportThread() {
|
||||||
if (initAudioBackend()) {
|
if (initAudioBackend()) {
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
disCont[i].setRates(got.rate);
|
disCont[i].setRates(got.rate);
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality,dcHiPass);
|
||||||
}
|
}
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating audio!");
|
logE("error while activating audio!");
|
||||||
|
@ -223,7 +223,7 @@ void DivEngine::runExportThread() {
|
||||||
if (initAudioBackend()) {
|
if (initAudioBackend()) {
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
disCont[i].setRates(got.rate);
|
disCont[i].setRates(got.rate);
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality,dcHiPass);
|
||||||
}
|
}
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating audio!");
|
logE("error while activating audio!");
|
||||||
|
@ -349,7 +349,7 @@ void DivEngine::runExportThread() {
|
||||||
if (initAudioBackend()) {
|
if (initAudioBackend()) {
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
disCont[i].setRates(got.rate);
|
disCont[i].setRates(got.rate);
|
||||||
disCont[i].setQuality(lowQuality);
|
disCont[i].setQuality(lowQuality,dcHiPass);
|
||||||
}
|
}
|
||||||
if (!output->setRun(true)) {
|
if (!output->setRun(true)) {
|
||||||
logE("error while activating audio!");
|
logE("error while activating audio!");
|
||||||
|
|
|
@ -1464,6 +1464,7 @@ class FurnaceGUI {
|
||||||
int mainFontSize, patFontSize, headFontSize, iconSize;
|
int mainFontSize, patFontSize, headFontSize, iconSize;
|
||||||
int audioEngine;
|
int audioEngine;
|
||||||
int audioQuality;
|
int audioQuality;
|
||||||
|
int audioHiPass;
|
||||||
int audioChans;
|
int audioChans;
|
||||||
int arcadeCore;
|
int arcadeCore;
|
||||||
int ym2612Core;
|
int ym2612Core;
|
||||||
|
@ -1656,6 +1657,7 @@ class FurnaceGUI {
|
||||||
iconSize(16),
|
iconSize(16),
|
||||||
audioEngine(DIV_AUDIO_SDL),
|
audioEngine(DIV_AUDIO_SDL),
|
||||||
audioQuality(0),
|
audioQuality(0),
|
||||||
|
audioHiPass(1),
|
||||||
audioChans(2),
|
audioChans(2),
|
||||||
arcadeCore(0),
|
arcadeCore(0),
|
||||||
ym2612Core(0),
|
ym2612Core(0),
|
||||||
|
|
|
@ -1060,6 +1060,12 @@ void FurnaceGUI::drawSettings() {
|
||||||
settingsChanged=true;
|
settingsChanged=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool audioHiPassB=settings.audioHiPass;
|
||||||
|
if (ImGui::Checkbox("DC offset correction",&audioHiPassB)) {
|
||||||
|
settings.audioHiPass=audioHiPassB;
|
||||||
|
settingsChanged=true;
|
||||||
|
}
|
||||||
|
|
||||||
// SUBSECTION METRONOME
|
// SUBSECTION METRONOME
|
||||||
CONFIG_SUBSECTION("Metronome");
|
CONFIG_SUBSECTION("Metronome");
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
|
@ -3574,6 +3580,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
settings.renderDriver=e->getConfString("renderDriver","");
|
settings.renderDriver=e->getConfString("renderDriver","");
|
||||||
settings.sdlAudioDriver=e->getConfString("sdlAudioDriver","");
|
settings.sdlAudioDriver=e->getConfString("sdlAudioDriver","");
|
||||||
settings.audioQuality=e->getConfInt("audioQuality",0);
|
settings.audioQuality=e->getConfInt("audioQuality",0);
|
||||||
|
settings.audioHiPass=e->getConfInt("audioHiPass",1);
|
||||||
settings.audioBufSize=e->getConfInt("audioBufSize",1024);
|
settings.audioBufSize=e->getConfInt("audioBufSize",1024);
|
||||||
settings.audioRate=e->getConfInt("audioRate",44100);
|
settings.audioRate=e->getConfInt("audioRate",44100);
|
||||||
settings.arcadeCore=e->getConfInt("arcadeCore",0);
|
settings.arcadeCore=e->getConfInt("arcadeCore",0);
|
||||||
|
@ -3756,6 +3763,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
clampSetting(settings.iconSize,2,48);
|
clampSetting(settings.iconSize,2,48);
|
||||||
clampSetting(settings.audioEngine,0,2);
|
clampSetting(settings.audioEngine,0,2);
|
||||||
clampSetting(settings.audioQuality,0,1);
|
clampSetting(settings.audioQuality,0,1);
|
||||||
|
clampSetting(settings.audioHiPass,0,1);
|
||||||
clampSetting(settings.audioBufSize,32,4096);
|
clampSetting(settings.audioBufSize,32,4096);
|
||||||
clampSetting(settings.audioRate,8000,384000);
|
clampSetting(settings.audioRate,8000,384000);
|
||||||
clampSetting(settings.audioChans,1,16);
|
clampSetting(settings.audioChans,1,16);
|
||||||
|
@ -3987,7 +3995,9 @@ void FurnaceGUI::commitSettings() {
|
||||||
settings.fdsCoreRender!=e->getConfInt("fdsCoreRender",0) ||
|
settings.fdsCoreRender!=e->getConfInt("fdsCoreRender",0) ||
|
||||||
settings.c64CoreRender!=e->getConfInt("c64CoreRender",0) ||
|
settings.c64CoreRender!=e->getConfInt("c64CoreRender",0) ||
|
||||||
settings.pokeyCoreRender!=e->getConfInt("pokeyCoreRender",1) ||
|
settings.pokeyCoreRender!=e->getConfInt("pokeyCoreRender",1) ||
|
||||||
settings.opnCoreRender!=e->getConfInt("opnCoreRender",1)
|
settings.opnCoreRender!=e->getConfInt("opnCoreRender",1) ||
|
||||||
|
settings.audioQuality!=e->getConfInt("audioQuality",0) ||
|
||||||
|
settings.audioHiPass!=e->getConfInt("audioHiPass",1)
|
||||||
);
|
);
|
||||||
|
|
||||||
e->setConf("mainFontSize",settings.mainFontSize);
|
e->setConf("mainFontSize",settings.mainFontSize);
|
||||||
|
@ -4001,6 +4011,7 @@ void FurnaceGUI::commitSettings() {
|
||||||
e->setConf("renderDriver",settings.renderDriver);
|
e->setConf("renderDriver",settings.renderDriver);
|
||||||
e->setConf("sdlAudioDriver",settings.sdlAudioDriver);
|
e->setConf("sdlAudioDriver",settings.sdlAudioDriver);
|
||||||
e->setConf("audioQuality",settings.audioQuality);
|
e->setConf("audioQuality",settings.audioQuality);
|
||||||
|
e->setConf("audioHiPass",settings.audioHiPass);
|
||||||
e->setConf("audioBufSize",settings.audioBufSize);
|
e->setConf("audioBufSize",settings.audioBufSize);
|
||||||
e->setConf("audioRate",settings.audioRate);
|
e->setConf("audioRate",settings.audioRate);
|
||||||
e->setConf("audioChans",settings.audioChans);
|
e->setConf("audioChans",settings.audioChans);
|
||||||
|
|
Loading…
Reference in a new issue