[DEV] cotinue update

This commit is contained in:
Edouard DUPIN 2015-04-19 21:01:40 +02:00
parent e83c228ca1
commit e912b34365
7 changed files with 190 additions and 217 deletions

View File

@ -28,6 +28,7 @@
audio::algo::chunkware::Compressor::Compressor() :
AttRelEnvelope(10.0, 100.0),
m_isConfigured(false),
m_threshdB(0.0),
m_ratio(1.0),
m_overThresholdEnvelopeDB(DC_OFFSET) {
@ -42,12 +43,24 @@ void audio::algo::chunkware::Compressor::setRatio(double _ratio) {
m_ratio = _ratio;
}
void audio::algo::chunkware::Compressor::initRuntime() {
void audio::algo::chunkware::Compressor::init() {
m_overThresholdEnvelopeDB = DC_OFFSET;
m_isConfigured = true;
}
std::vector<enum audio::format> audio::algo::chunkware::Compressor::getSupportedFormat() {
std::vector<enum audio::format> out = getNativeSupportedFormat();
out.push_back(audio::format_int16);
return out;
}
void audio::algo::chunkware::Compressor::process(audio::format _format, void* _output, const void* _input, size_t _nbChunk, int8_t _nbChannel) {
std::vector<enum audio::format> audio::algo::chunkware::Compressor::getNativeSupportedFormat() {
std::vector<enum audio::format> out;
out.push_back(audio::format_double);
return out;
}
void audio::algo::chunkware::Compressor::process(void* _output, const void* _input, size_t _nbChunk, int8_t _nbChannel, enum audio::format _format) {
// TODO : Check init ...
if (_nbChannel != 1) {
AA_CHUNK_ERROR("Can not compress with Other than single channel: " << _nbChannel);
@ -57,12 +70,16 @@ void audio::algo::chunkware::Compressor::process(audio::format _format, void* _o
{
const int16_t* input = reinterpret_cast<const int16_t*>(_input);
int16_t* output = reinterpret_cast<int16_t*>(_output);
double vals[_nbChannel];
for (size_t iii=0; iii<_nbChunk ; ++iii) {
double val = input[iii];
val /= 32768.0;
processMono(val);
val *= 32768.0;
output[iii] = int16_t(std::avg(-32768.0, val*32768.0, 32767.0));
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
vals[kkk] = double(input[iii*_nbChannel+kkk]) / 32768.0;
}
processDouble(vals, vals, _nbChannel);
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
vals[kkk] *= 32768.0;
output[iii*_nbChannel+kkk] = int16_t(std::avg(-32768.0, vals[kkk], 32767.0));
}
}
}
break;
@ -71,8 +88,7 @@ void audio::algo::chunkware::Compressor::process(audio::format _format, void* _o
const double* input = reinterpret_cast<const double*>(_input);
double* output = reinterpret_cast<double*>(_output);
for (size_t iii=0; iii<_nbChunk ; ++iii) {
output[iii] = input[iii];
processMono(output[iii]);
processDouble(&output[iii*_nbChannel], &input[iii*_nbChannel], _nbChannel);
//AA_CHUNK_INFO(" in=" << input[iii] << " => " << output[iii]);
}
}
@ -84,45 +100,17 @@ void audio::algo::chunkware::Compressor::process(audio::format _format, void* _o
}
void audio::algo::chunkware::Compressor::processMono(double& _in) {
double rect1 = std::abs(_in); // rectify input
rect1 += DC_OFFSET;
double keydB = lin2dB(rect1);
// threshold
double overdB = keydB - m_threshdB; //delta over threshold
if ( overdB < 0.0 ) {
overdB = 0.0;
void audio::algo::chunkware::Compressor::processDouble(double* _out, const double* _in, int8_t _nbChannel) {
double keyLink = 0;
// get greater value;
for (int8_t iii=0; iii<_nbChannel; ++iii) {
double absValue = std::abs(_in[iii]);
keyLink = std::max(keyLink, absValue);
}
// attack/release
overdB += DC_OFFSET; // add DC offset to avoid denormal
AttRelEnvelope::run(overdB, m_overThresholdEnvelopeDB); // run attack/release envelope
overdB = m_overThresholdEnvelopeDB - DC_OFFSET; // subtract DC offset
/* REGARDING THE DC OFFSET: In this case, since the offset is added before
* the attack/release processes, the envelope will never fall below the offset,
* thereby avoiding denormals. However, to prevent the offset from causing
* constant gain reduction, we must subtract it from the envelope, yielding
* a minimum value of 0dB.
*/
// transfer function
double gr = overdB * ( m_ratio - 1.0 ); // gain reduction (dB)
gr = dB2lin(gr); // convert dB -> linear
// output gain
_in *= gr; // apply gain reduction to input
processDouble(_out, _in, _nbChannel, keyLink);
}
void audio::algo::chunkware::Compressor::process(double& _in1, double& _in2) {
// create sidechain
double rect1 = std::abs(_in1); // rectify input
double rect2 = std::abs(_in2);
/* if desired, one could use another EnvelopeDetector to smooth
* the rectified signal.
*/
double link = std::max(rect1, rect2); // link channels with greater of 2
process(_in1, _in2, link); // rest of process
}
void audio::algo::chunkware::Compressor::process(double& _in1, double& _in2, double _keyLinked) {
_keyLinked = std::abs(_keyLinked); // rectify (just in case)
void audio::algo::chunkware::Compressor::processDouble(double* _out, const double* _in, int8_t _nbChannel, double _keyLinked) {
// convert key to dB
_keyLinked += DC_OFFSET; // add DC offset to avoid log(0)
double keydB = lin2dB(_keyLinked); // convert linear -> dB
@ -145,7 +133,8 @@ void audio::algo::chunkware::Compressor::process(double& _in1, double& _in2, dou
double gr = overdB * (m_ratio - 1.0); // gain reduction (dB)
gr = dB2lin(gr); // convert dB -> linear
// output gain
_in1 *= gr; // apply gain reduction to input
_in2 *= gr;
for (int8_t iii=0; iii<_nbChannel; ++iii) {
_out[iii] = _in[iii] * gr;
}
}

View File

@ -36,9 +36,46 @@ namespace audio {
namespace algo {
namespace chunkware {
class Compressor : public audio::algo::chunkware::AttRelEnvelope {
protected:
bool m_isConfigured;
public:
Compressor();
virtual ~Compressor() {}
public:
/**
* @brief Initialize the Algorithm
*/
virtual void init();
/**
* @brief Get list of format suported in input.
* @return list of supported format
*/
std::vector<enum audio::format> getSupportedFormat();
/**
* @brief Get list of algorithm format suported. No format convertion.
* @return list of supported format
*/
std::vector<enum audio::format> getNativeSupportedFormat();
/**
* @brief Main input algo process.
* @param[in,out] _output Output data.
* @param[in] _input Input data.
* @param[in] _nbChunk Number of chunk in the input buffer.
* @param[in] _nbChannel Number of channel in the stream.
* @param[in] _format Input data format.
*/
void process(void* _output, const void* _input, size_t _nbChunk, int8_t _nbChannel = 2, enum audio::format _format = audio::format_double);
protected:
virtual void processDouble(double* _out, const double* _in, int8_t _nbChannel);
void processDouble(double* _out, const double* _in, int8_t _nbChannel, double _value);
/*
void process(float* _out, const float* _in, int8_t _nbChannel);
void process(int16_16_t* _out, const int16_16_t* _in, int8_t _nbChannel);
void process(int16_32_t* _out, const int16_32_t* _in, int8_t _nbChannel);
void process(int24_32_t* _out, const int24_32_t* _in, int8_t _nbChannel);
void process(int32_32_t* _out, const int32_32_t* _in, int8_t _nbChannel);
void process(int32_64_t* _out, const int32_64_t* _in, int8_t _nbChannel);
*/
protected:
double m_threshdB;//!< threshold (dB)
public:
@ -53,18 +90,7 @@ namespace audio {
virtual double getRatio() const {
return m_ratio;
}
public:
void process(audio::format _format, void* _output, const void* _input, size_t _nbChunk, int8_t _nbChannel);
// call before runtime (in resume())
virtual void initRuntime();
protected:
// runtime
// compressor runtime process
void processMono(double& _in);
// compressor runtime process
void process(double& _in1, double& _in2);
// with stereo-linked key in
void process(double& _in1, double& _in2, double _keyLinked);
// runtime variables
double m_overThresholdEnvelopeDB; //!< over-threshold envelope (dB)
};

View File

@ -47,11 +47,12 @@ void audio::algo::chunkware::CompressorRms::initRuntime() {
m_averageSuares = DC_OFFSET;
}
void audio::algo::chunkware::CompressorRms::process(double& _in1, double& _in2) {
void audio::algo::chunkware::CompressorRms::processDouble(double* _out, const double* _in, int8_t _nbChannel) {
double sum = 0.0;
// create sidechain
double inSq1 = _in1 * _in1; // square input
double inSq2 = _in2 * _in2;
double sum = inSq1 + inSq2; // power summing
for (int8_t iii=0; iii<_nbChannel; ++iii) {
sum += _in[iii] * _in[iii]; // square input
}
sum += DC_OFFSET; // DC offset, to prevent denormal
m_averager.run(sum, m_averageSuares); // average of squares
double rms = sqrt(m_averageSuares); // rms (sort of ...)
@ -62,5 +63,5 @@ void audio::algo::chunkware::CompressorRms::process(double& _in1, double& _in2)
* giving comparable results.
*/
// rest of process
audio::algo::chunkware::Compressor::process(_in1, _in2, rms);
processDouble(_out, _in, _nbChannel, rms);
}

View File

@ -43,9 +43,9 @@ namespace audio {
virtual double getWindow() const {
return m_averager.getTc();
}
// runtime process
virtual void initRuntime(); // call before runtime (in resume())
void process(double& _in1, double& _in2); // compressor runtime process
public:
virtual void init();
void processDouble(double* _out, const double* _in, int8_t _nbChannel);
protected:
audio::algo::chunkware::EnvelopeDetector m_averager; //!< averager
double m_averageSuares; //!< average of squares

View File

@ -28,6 +28,7 @@
#include <audio/algo/chunkware/debug.h>
audio::algo::chunkware::Limiter::Limiter() :
m_isConfigured(false),
m_threshdB(0.0),
m_threshold(1.0),
m_peakHold(0),
@ -39,8 +40,8 @@ audio::algo::chunkware::Limiter::Limiter() :
m_bufferMask(BUFFER_SIZE-1),
m_cursor(0) {
setAttack(1.0);
m_outputBuffer[ 0 ].resize(BUFFER_SIZE, 0.0);
m_outputBuffer[ 1 ].resize(BUFFER_SIZE, 0.0);
m_outputBuffer.resize(1);
m_outputBuffer[0].resize(BUFFER_SIZE, 0.0);
}
void audio::algo::chunkware::Limiter::setThreshold(double _dB) {
@ -64,13 +65,17 @@ void audio::algo::chunkware::Limiter::setSampleRate(double _sampleRate) {
m_release.setSampleRate(_sampleRate);
}
void audio::algo::chunkware::Limiter::initRuntime() {
void audio::algo::chunkware::Limiter::init(int8_t _nbChannel) {
m_peakTimer = 0;
m_maxPeak = m_threshold;
m_overThresholdEnvelope = m_threshold;
m_cursor = 0;
m_outputBuffer[ 0 ].assign(BUFFER_SIZE, 0.0);
m_outputBuffer[ 1 ].assign(BUFFER_SIZE, 0.0);
m_outputBuffer.resize(_nbChannel);
for (int8_t iii=0; iii<_nbChannel; ++iii) {
m_outputBuffer[iii].resize(BUFFER_SIZE, 0.0);
m_outputBuffer[iii].assign(BUFFER_SIZE, 0.0);
}
m_isConfigured = true;
}
void audio::algo::chunkware::FastEnvelope::setCoef() {
@ -78,22 +83,41 @@ void audio::algo::chunkware::FastEnvelope::setCoef() {
m_coefficient = std::pow(0.01, (1000.0 / (m_timeMs * m_sampleRate)));
}
void audio::algo::chunkware::Limiter::process(audio::format _format, void* _output, const void* _input, size_t _nbChunk, int8_t _nbChannel) {
std::vector<enum audio::format> audio::algo::chunkware::Limiter::getSupportedFormat() {
std::vector<enum audio::format> out = getNativeSupportedFormat();
out.push_back(audio::format_int16);
return out;
}
std::vector<enum audio::format> audio::algo::chunkware::Limiter::getNativeSupportedFormat() {
std::vector<enum audio::format> out;
out.push_back(audio::format_double);
return out;
}
void audio::algo::chunkware::Limiter::process(void* _output, const void* _input, size_t _nbChunk, int8_t _nbChannel, enum audio::format _format) {
// TODO : Check init ...
if (_nbChannel != 1) {
AA_CHUNK_ERROR("Can not compress with Other than single channel: " << _nbChannel);
if (_nbChannel != m_outputBuffer.size()) {
AA_CHUNK_ERROR("Can not compress with Other than nb channel configured ... channel: " << _nbChannel << " != " << m_outputBuffer.size());
}
if (m_isConfigured == false) {
AA_CHUNK_ERROR("Algo is not initialized...");
}
switch (_format) {
case audio::format_int16:
{
const int16_t* input = reinterpret_cast<const int16_t*>(_input);
int16_t* output = reinterpret_cast<int16_t*>(_output);
double vals[_nbChannel];
for (size_t iii=0; iii<_nbChunk ; ++iii) {
double val = input[iii];
val /= 32768.0;
processMono(val);
val *= 32768.0;
output[iii] = int16_t(std::avg(-32768.0, val*32768.0, 32767.0));
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
vals[kkk] = double(input[iii*_nbChannel+kkk]) / 32768.0;
}
processDouble(vals, vals, _nbChannel);
for (int8_t kkk=0; kkk<_nbChannel ; ++kkk) {
vals[kkk] *= 32768.0;
output[iii*_nbChannel+kkk] = int16_t(std::avg(-32768.0, vals[kkk], 32767.0));
}
}
}
break;
@ -102,114 +126,24 @@ void audio::algo::chunkware::Limiter::process(audio::format _format, void* _outp
const double* input = reinterpret_cast<const double*>(_input);
double* output = reinterpret_cast<double*>(_output);
for (size_t iii=0; iii<_nbChunk ; ++iii) {
output[iii] = input[iii];
processMono(output[iii]);
processDouble(&output[iii*_nbChannel], &input[iii*_nbChannel], _nbChannel);
//AA_CHUNK_INFO(" in=" << input[iii] << " => " << output[iii]);
}
}
break;
default:
AA_CHUNK_ERROR("Can not compress with unsupported format : " << _format);
return;
AA_CHUNK_ERROR("Can not Limit with unsupported format : " << _format);
break;
}
}
void audio::algo::chunkware::Limiter::processMono(double& _in) {
double keyLink = std::abs(_in); // rectify input
// threshold
// we always want to feed the sidechain AT LEATS the threshold value
if (keyLink < m_threshold) {
keyLink = m_threshold;
void audio::algo::chunkware::Limiter::processDouble(double* _out, const double* _in, int8_t _nbChannel) {
double keyLink = 0;
// get greater value;
for (int8_t iii=0; iii<_nbChannel; ++iii) {
double absValue = std::abs(_in[iii]);
keyLink = std::max(keyLink, absValue);
}
// test:
// a) whether peak timer has "expired"
// b) whether new peak is greater than previous max peak
if ((++m_peakTimer >= m_peakHold) || (keyLink > m_maxPeak)) {
// if either condition is met:
m_peakTimer = 0; // reset peak timer
m_maxPeak = keyLink; // assign new peak to max peak
}
/* REGARDING THE MAX PEAK: This method assumes that the only important
* sample in a look-ahead buffer would be the highest peak. As such,
* instead of storing all samples in a look-ahead buffer, it only stores
* the max peak, and compares all incoming samples to that one.
* The max peak has a hold time equal to what the look-ahead buffer
* would have been, which is tracked by a timer (counter). When this
* timer expires, the sample would have exited from the buffer. Therefore,
* a new sample must be assigned to the max peak. We assume that the next
* highest sample in our theoretical buffer is the current input sample.
* In reality, we know this is probably NOT the case, and that there has
* been another sample, slightly lower than the one before it, that has
* passed the input. If we do not account for this possibility, our gain
* reduction could be insufficient, resulting in an "over" at the output.
* To remedy this, we simply apply a suitably long release stage in the
* envelope follower.
*/
// attack/release
if (m_maxPeak > m_overThresholdEnvelope) {
// run attack phase
m_attack.run(m_maxPeak, m_overThresholdEnvelope);
} else {
// run release phase
m_release.run(m_maxPeak, m_overThresholdEnvelope);
}
/* REGARDING THE ATTACK: This limiter achieves "look-ahead" detection
* by allowing the envelope follower to attack the max peak, which is
* held for the duration of the attack phase -- unless a new, higher
* peak is detected. The output signal is buffered so that the gain
* reduction is applied in advance of the "offending" sample.
*/
/* NOTE: a DC offset is not necessary for the envelope follower,
* as neither the max peak nor envelope should fall below the
* threshold (which is assumed to be around 1.0 linear).
*/
// gain reduction
double gR = m_threshold / m_overThresholdEnvelope;
// unload current buffer index
// (m_cursor - delay) & m_bufferMask gets sample from [delay] samples ago
// m_bufferMask variable wraps index
unsigned int delayIndex = (m_cursor - m_peakHold) & m_bufferMask;
double delay1 = m_outputBuffer[0][delayIndex];
//double delay2 = m_outputBuffer[1][delayIndex];
// load current buffer index and advance current index
// m_bufferMask wraps m_cursor index
m_outputBuffer[0][m_cursor] = _in;
//m_outputBuffer[1][m_cursor] = _in2;
++m_cursor &= m_bufferMask;
// output gain
_in = delay1 * gR; // apply gain reduction to input
//_in2 = delay2 * gR;
/* REGARDING THE GAIN REDUCTION: Due to the logarithmic nature
* of the attack phase, the sidechain will never achieve "full"
* attack. (Actually, it is only guaranteed to achieve 99% of
* the input value over the given time constant.) As such, the
* limiter cannot achieve "brick-wall" limiting. There are 2
* workarounds:
*
* 1) Set the threshold slightly lower than the desired threshold.
* i.e. 0.0dB -> -0.1dB or even -0.5dB
*
* 2) Clip the output at the threshold, as such:
*
* if (in1 > m_threshold) in1 = m_threshold;
* else if (in1 < -m_threshold) in1 = -m_threshold;
*
* if (in2 > m_threshold) in2 = m_threshold;
* else if (in2 < -m_threshold) in2 = -m_threshold;
*
* (... or replace with your favorite branchless clipper ...)
*/
}
void audio::algo::chunkware::Limiter::process(double& _in1, double& _in2) {
// create sidechain
double rect1 = fabs(_in1); // rectify input
double rect2 = fabs(_in2);
double keyLink = std::max(rect1, rect2); // link channels with greater of 2
// threshold
// we always want to feed the sidechain AT LEATS the threshold value
if (keyLink < m_threshold) {
keyLink = m_threshold;
@ -262,16 +196,19 @@ void audio::algo::chunkware::Limiter::process(double& _in1, double& _in2) {
// (m_cursor - delay) & m_bufferMask gets sample from [delay] samples ago
// m_bufferMask variable wraps index
unsigned int delayIndex = (m_cursor - m_peakHold) & m_bufferMask;
double delay1 = m_outputBuffer[0][delayIndex];
double delay2 = m_outputBuffer[1][delayIndex];
// load current buffer index and advance current index
// m_bufferMask wraps m_cursor index
m_outputBuffer[0][m_cursor] = _in1;
m_outputBuffer[1][m_cursor] = _in2;
double delay[_nbChannel];
for (int8_t iii=0; iii<_nbChannel; ++iii) {
delay[iii] = m_outputBuffer[iii][delayIndex];
// load current buffer index and advance current index
// m_bufferMask wraps m_cursor index
m_outputBuffer[iii][m_cursor] = _in[iii];
}
++m_cursor &= m_bufferMask;
// output gain
_in1 = delay1 * gR; // apply gain reduction to input
_in2 = delay2 * gR;
for (int8_t iii=0; iii<_nbChannel; ++iii) {
// apply gain reduction to input
_out[iii] = delay[iii] * gR;
}
/* REGARDING THE GAIN REDUCTION: Due to the logarithmic nature
* of the attack phase, the sidechain will never achieve "full"
* attack. (Actually, it is only guaranteed to achieve 99% of
@ -292,4 +229,4 @@ void audio::algo::chunkware::Limiter::process(double& _in1, double& _in2) {
*
* (... or replace with your favorite branchless clipper ...)
*/
}
}

View File

@ -40,7 +40,7 @@ namespace audio {
// class for faster attack/release
class FastEnvelope : public audio::algo::chunkware::EnvelopeDetector {
public:
FastEnvelope(double _ms = 1.0, double _sampleRate = 44100.0) :
FastEnvelope(double _ms = 1.0, double _sampleRate = 48000.0) :
EnvelopeDetector(_ms, _sampleRate) {
}
@ -56,7 +56,41 @@ namespace audio {
public:
Limiter();
virtual ~Limiter() {}
public:
/**
* @brief Initialize the Algorithm
* @param[in] _nbChannel Number of channel in the stream.
*/
virtual void init(int8_t _nbChannel);
/**
* @brief Get list of format suported in input.
* @return list of supported format
*/
std::vector<enum audio::format> getSupportedFormat();
/**
* @brief Get list of algorithm format suported. No format convertion.
* @return list of supported format
*/
std::vector<enum audio::format> getNativeSupportedFormat();
/**
* @brief Main input algo process.
* @param[in,out] _output Output data.
* @param[in] _input Input data.
* @param[in] _nbChunk Number of chunk in the input buffer.
* @param[in] _nbChannel Number of channel in the stream.
* @param[in] _format Input data format.
*/
void process(void* _output, const void* _input, size_t _nbChunk, int8_t _nbChannel = 2, enum audio::format _format = audio::format_double);
protected:
void processDouble(double* _out, const double* _in, int8_t _nbChannel);
/*
void process(float* _out, const float* _in, int8_t _nbChannel);
void process(int16_16_t* _out, const int16_16_t* _in, int8_t _nbChannel);
void process(int16_32_t* _out, const int16_32_t* _in, int8_t _nbChannel);
void process(int24_32_t* _out, const int24_32_t* _in, int8_t _nbChannel);
void process(int32_32_t* _out, const int32_32_t* _in, int8_t _nbChannel);
void process(int32_64_t* _out, const int32_64_t* _in, int8_t _nbChannel);
*/
protected:
double m_threshdB; //!< threshold (dB)
public:
@ -91,49 +125,35 @@ namespace audio {
protected:
public:
// sample rate dependencies
/**
* @brief Set sample rate.
* @param[in] _sampleRate New sample rate value.
*/
virtual void setSampleRate(double _sampleRate);
/**
* @brief Get current sample rate.
* @return Vlue of the sample rate.
*/
virtual double getSampleRate() {
return m_attack.getSampleRate();
}
// runtime
// call before runtime (in resume())
virtual void initRuntime();
void process(audio::format _format, void* _output, const void* _input, size_t _nbChunk, int8_t _nbChannel);
protected:
/*
void process(double* _out, const double* _in, int8_t _nbChannel);
void process(float* _out, const float* _in, int8_t _nbChannel);
void process(int16_16_t* _out, const int16_16_t* _in, int8_t _nbChannel);
void process(int16_32_t* _out, const int16_32_t* _in, int8_t _nbChannel);
void process(int24_32_t* _out, const int24_32_t* _in, int8_t _nbChannel);
void process(int32_32_t* _out, const int32_32_t* _in, int8_t _nbChannel);
void process(int32_64_t* _out, const int32_64_t* _in, int8_t _nbChannel);
*/
// limiter runtime process
void process(double& _in1, double& _in2);
void processMono(double& _in);
private:
// transfer function
double m_threshold; //!< threshold (linear)
// max peak
unsigned int m_peakTimer; //!< peak hold timer
uint32_t m_peakTimer; //!< peak hold timer
double m_maxPeak; //!< max peak
// attack/release envelope
audio::algo::chunkware::FastEnvelope m_attack; //!< attack
audio::algo::chunkware::FastEnvelope m_release; //!< release
double m_overThresholdEnvelope; //!< over-threshold envelope (linear)
// buffer
// BUFFER_SIZE default can handle up to ~10ms at 96kHz
// change this if you require more
static const int BUFFER_SIZE = 1024; //!< buffer size (always a power of 2!)
unsigned int m_bufferMask; //!< buffer mask
unsigned int m_cursor; //!< cursor
std::vector< double > m_outputBuffer[2]; //!< output buffer
uint32_t m_bufferMask; //!< buffer mask
uint32_t m_cursor; //!< cursor
std::vector<std::vector<double> > m_outputBuffer; //!< output buffer
};
}
}

View File

@ -110,7 +110,7 @@ int main(int _argc, const char** _argv) {
algo.setThreshold(0);
algo.setAttack(0.1);
algo.setRelease(2);
algo.initRuntime();
algo.init(1);
int32_t lastPourcent = -1;
for (int32_t iii=0; iii<output.size()/blockSize; ++iii) {
if (lastPourcent != 100*iii / (output.size()/blockSize)) {
@ -120,7 +120,7 @@ int main(int _argc, const char** _argv) {
APPL_VERBOSE("Process : " << iii*blockSize << "/" << int32_t(output.size()/blockSize)*blockSize);
}
std11::chrono::steady_clock::time_point timeStart = std11::chrono::steady_clock::now();
algo.process(audio::format_double, &output[iii*blockSize], &inputData[iii*blockSize], blockSize, 1);
algo.process(&output[iii*blockSize], &inputData[iii*blockSize], blockSize, 1, audio::format_double);
if (perf == true) {
std11::chrono::steady_clock::time_point timeEnd = std11::chrono::steady_clock::now();
std11::chrono::nanoseconds time = timeEnd - timeStart;