Skip to content

Commit

Permalink
Fix issue #17 Loading IR seems to create DC issues
Browse files Browse the repository at this point in the history
  • Loading branch information
brummer10 committed Aug 3, 2024
1 parent 6019f91 commit 6879ae2
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Ratatouille/ParallelThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class ParallelThread
while (!getState()) {
pthread_mutex_lock(&pWaitProc);
if (pthread_cond_timedwait(&pProcCond, &pWaitProc, getTimeOut()) == ETIMEDOUT) {
pthread_mutex_unlock(&pWaitProc);;
pthread_mutex_unlock(&pWaitProc);
maxDuration +=1;
//fprintf(stderr, "%s wait for process %i\n", threadName.c_str(), maxDuration);
if (maxDuration > 2) {
Expand Down Expand Up @@ -179,7 +179,7 @@ class ParallelThread
while (pWait.load(std::memory_order_acquire)) {
pthread_mutex_lock(&pWaitProc);
if (pthread_cond_timedwait(&pProcCond, &pWaitProc, getTimeOut()) == ETIMEDOUT) {
pthread_mutex_unlock(&pWaitProc);;
pthread_mutex_unlock(&pWaitProc);
maxDuration +=1;
//fprintf(stderr, "%s wait for data %i\n", threadName.c_str(), maxDuration);
if (maxDuration > 5) {
Expand Down
24 changes: 17 additions & 7 deletions Ratatouille/Ratatouille.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ class Xratatouille
cdeleay::Dsp* cdelay;
ModelerSelector slotA;
ModelerSelector slotB;
DoubleThreadConvolver conv;
DoubleThreadConvolver conv1;
SingleThreadConvolver conv;
SingleThreadConvolver conv1;
ParallelThread xrworker;
ParallelThread pro;
DenormalProtection MXCSR;
Expand Down Expand Up @@ -237,8 +237,8 @@ Xratatouille::Xratatouille() :
cdelay(cdeleay::plugin()),
slotA(&Sync),
slotB(&Sync),
conv(DoubleThreadConvolver()),
conv1(DoubleThreadConvolver()),
conv(SingleThreadConvolver()),
conv1(SingleThreadConvolver()),
rt_prio(0),
rt_policy(0),
input0(NULL),
Expand Down Expand Up @@ -300,7 +300,6 @@ void Xratatouille::init_dsp_(uint32_t rate)
if (!rt_policy) rt_policy = 1; //SCHED_FIFO;
pro.setThreadName("RT");
pro.setPriority(rt_prio, rt_policy);
pro.process.set<&Xratatouille::processSlotB>(*this);

model_file = "None";
model_file1 = "None";
Expand Down Expand Up @@ -693,6 +692,7 @@ void Xratatouille::run_dsp_(uint32_t n_samples)
// process slot B in parallel
_bufb = bufb;
if (_neuralB.load(std::memory_order_acquire) && pro.getProcess()) {
pro.process.set<&Xratatouille::processSlotB>(*this);
pro.runProcess();
} else {
processSlotB();
Expand Down Expand Up @@ -739,13 +739,23 @@ void Xratatouille::run_dsp_(uint32_t n_samples)
memcpy(bufa, output0, n_samples*sizeof(float));
memcpy(bufb, output0, n_samples*sizeof(float));

// process conv1 in parallel
_bufb = bufb;
if (!_execute.load(std::memory_order_acquire) && conv1.is_runnable()) {
if (pro.getProcess()) {
pro.process.set<&Xratatouille::processConv1>(*this);
pro.runProcess();
} else {
processConv1();
}
}
// process conv
if (!_execute.load(std::memory_order_acquire) && conv.is_runnable())
conv.compute(n_samples, bufa, bufa);

// process conv1
// wait for parallel processed conv1 when needed
if (!_execute.load(std::memory_order_acquire) && conv1.is_runnable())
conv1.compute(n_samples, bufb, bufb);
pro.processWait();

// mix output when needed
if ((!_execute.load(std::memory_order_acquire) && conv.is_runnable()) && conv1.is_runnable()) {
Expand Down
105 changes: 105 additions & 0 deletions Ratatouille/fftconvolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,108 @@ void DoubleThreadConvolver::compute(int32_t count, float* input, float* output)
{
if (ready) process(input, output, count);
}

/****************************************************************
** SingleThreadConvolver
*/

bool SingleThreadConvolver::get_buffer(std::string fname, float **buffer, uint32_t *rate, int *asize)
{
Audiofile audio;
if (audio.open_read(fname)) {
fprintf(stderr, "Unable to open %s\n", fname.c_str() );
*buffer = 0;
return false;
}
*rate = audio.rate();
*asize = audio.size();
const int limit = 2000000; // arbitrary size limit
if (*asize > limit) {
fprintf(stderr, "too many samples (%i), truncated to %i\n"
, audio.size(), limit);
*asize = limit;
}
if (*asize * audio.chan() == 0) {
fprintf(stderr, "No samples found\n");
*buffer = 0;
audio.close();
return false;
}
float* cbuffer = new float[*asize * audio.chan()];
if (audio.read(cbuffer, *asize) != static_cast<int>(*asize)) {
delete[] cbuffer;
fprintf(stderr, "Error reading file\n");
*buffer = 0;
audio.close();
return false;
}
if (audio.chan() > 1) {
//fprintf(stderr,"only taking first channel of %i channels in impulse response\n", audio.chan());
float *abuffer = new float[*asize];
for (int i = 0; i < *asize; i++) {
abuffer[i] = cbuffer[i * audio.chan()];
}
delete[] cbuffer;
cbuffer = NULL;
cbuffer = abuffer;
}
*buffer = cbuffer;
audio.close();
if (*rate != samplerate) {
*buffer = resamp.process(*rate, *asize, *buffer, samplerate, asize);
if (!*buffer) {
printf("no buffer\n");
return false;
}
//fprintf(stderr, "FFTConvolver: resampled from %i to %i\n", *rate, samplerate);
}
return true;
}

void SingleThreadConvolver::normalize(float* buffer, int asize) {
if (!norm) return;
double gain = 0.0;
// get gain factor from file buffer
for (int i = 0; i < asize; i++) {
double v = buffer[i] ;
gain += v*v;
}
// apply gain factor when needed
if (gain != 0.0) {
gain = 1.0 / gain;

for (int i = 0; i < asize; i++) {
buffer[i] *= gain;
}
}
}

void SingleThreadConvolver::set_normalisation(uint32_t norm_) {
norm = norm_;
}

bool SingleThreadConvolver::configure(std::string fname, float gain, unsigned int delay, unsigned int offset,
unsigned int length, unsigned int size, unsigned int bufsize)
{
filename = fname;
float* abuf = NULL;
uint32_t arate = 0;
int asize = 0;
if (!get_buffer(fname, &abuf, &arate, &asize)) {
return false;
}
normalize(abuf, asize);

if (init(1024, abuf, asize)) {
ready = true;
delete[] abuf;
return true;
}
delete[] abuf;
return false;
}

void SingleThreadConvolver::compute(int32_t count, float* input, float* output)
{
if (ready) process(input, output, count);
}
48 changes: 47 additions & 1 deletion Ratatouille/fftconvolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,53 @@ class DoubleThreadConvolver: public fftconvolver::TwoStageFFTConvolver
std::string filename;
ParallelThread pro;
std::atomic<bool> setWait;
std::chrono::microseconds timeoutPeriod;
bool get_buffer(std::string fname, float **buffer, uint32_t* rate, int* size);
void normalize(float* buffer, int asize);
};

class SingleThreadConvolver: public fftconvolver::FFTConvolver
{
public:
bool start(int32_t policy, int32_t priority) {
return ready;}

void set_normalisation(uint32_t norm);

bool configure(std::string fname, float gain, unsigned int delay, unsigned int offset,
unsigned int length, unsigned int size, unsigned int bufsize);

void compute(int32_t count, float* input, float *output);

bool checkstate() { return true;}

inline void set_not_runnable() { ready = false;}

inline bool is_runnable() { return ready;}

inline void set_buffersize(uint32_t sz) { buffersize = sz;}

inline void set_samplerate(uint32_t sr) { samplerate = sr;}

int stop_process() {
ready = false;
return 0;}

int cleanup () {
reset();
return 0;}

SingleThreadConvolver()
: resamp(), ready(false), samplerate(0) { norm = 0;}

~SingleThreadConvolver() { reset();}

private:
gx_resample::BufferResampler resamp;
volatile bool ready;
uint32_t buffersize;
uint32_t samplerate;
uint32_t norm;
std::string filename;
bool get_buffer(std::string fname, float **buffer, uint32_t* rate, int* size);
void normalize(float* buffer, int asize);
};
Expand Down

0 comments on commit 6879ae2

Please sign in to comment.