mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-24 07:27:44 +01:00
merge to 2967 in vamp vendor branch
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2975 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
301009848c
commit
3b0e89d43c
3 changed files with 338 additions and 82 deletions
|
|
@ -22,7 +22,9 @@ vamp-sdk/RealTime.cpp
|
|||
Import('env install_prefix libraries')
|
||||
vampsdk = env.Copy()
|
||||
|
||||
vampsdk.Append (CPPATH='#libs/vamp-sdk/vamp', CXXFLAGS="-Ilibs/vamp-sdk")
|
||||
# HAVE_FFTW3 is used to help improve some performance aspects of VAMP's InputDomainAdapter
|
||||
|
||||
vampsdk.Append (CPPATH='#libs/vamp-sdk/vamp', CXXFLAGS="-Ilibs/vamp-sdk -DHAVE_FFTW3")
|
||||
|
||||
libvampsdk = vampsdk.SharedLibrary('vampsdk', vampsdk_files)
|
||||
libvamphostsdk = vampsdk.SharedLibrary('vamphostsdk', vamphostsdk_files)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
Centre for Digital Music, Queen Mary, University of London.
|
||||
Copyright 2006-2007 Chris Cannam and QMUL.
|
||||
This file by Mark Levy, Copyright 2007 QMUL.
|
||||
This file by Mark Levy and Chris Cannam.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
|
@ -62,15 +62,168 @@ public:
|
|||
FeatureSet getRemainingFeatures();
|
||||
|
||||
protected:
|
||||
class RingBuffer
|
||||
{
|
||||
public:
|
||||
RingBuffer(int n) :
|
||||
m_buffer(new float[n+1]), m_writer(0), m_reader(0), m_size(n+1) { }
|
||||
virtual ~RingBuffer() { delete[] m_buffer; }
|
||||
|
||||
int getSize() const { return m_size-1; }
|
||||
void reset() { m_writer = 0; m_reader = 0; }
|
||||
|
||||
int getReadSpace() const {
|
||||
int writer = m_writer, reader = m_reader, space;
|
||||
if (writer > reader) space = writer - reader;
|
||||
else if (writer < reader) space = (writer + m_size) - reader;
|
||||
else space = 0;
|
||||
return space;
|
||||
}
|
||||
|
||||
int getWriteSpace() const {
|
||||
int writer = m_writer;
|
||||
int reader = m_reader;
|
||||
int space = (reader + m_size - writer - 1);
|
||||
if (space >= m_size) space -= m_size;
|
||||
return space;
|
||||
}
|
||||
|
||||
int peek(float *destination, int n) const {
|
||||
|
||||
int available = getReadSpace();
|
||||
|
||||
if (n > available) {
|
||||
for (int i = available; i < n; ++i) {
|
||||
destination[i] = 0.f;
|
||||
}
|
||||
n = available;
|
||||
}
|
||||
if (n == 0) return n;
|
||||
|
||||
int reader = m_reader;
|
||||
int here = m_size - reader;
|
||||
const float *const bufbase = m_buffer + reader;
|
||||
|
||||
if (here >= n) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
destination[i] = bufbase[i];
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < here; ++i) {
|
||||
destination[i] = bufbase[i];
|
||||
}
|
||||
float *const destbase = destination + here;
|
||||
const int nh = n - here;
|
||||
for (int i = 0; i < nh; ++i) {
|
||||
destbase[i] = m_buffer[i];
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int skip(int n) {
|
||||
|
||||
int available = getReadSpace();
|
||||
if (n > available) {
|
||||
n = available;
|
||||
}
|
||||
if (n == 0) return n;
|
||||
|
||||
int reader = m_reader;
|
||||
reader += n;
|
||||
while (reader >= m_size) reader -= m_size;
|
||||
m_reader = reader;
|
||||
return n;
|
||||
}
|
||||
|
||||
int write(const float *source, int n) {
|
||||
|
||||
int available = getWriteSpace();
|
||||
if (n > available) {
|
||||
n = available;
|
||||
}
|
||||
if (n == 0) return n;
|
||||
|
||||
int writer = m_writer;
|
||||
int here = m_size - writer;
|
||||
float *const bufbase = m_buffer + writer;
|
||||
|
||||
if (here >= n) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
bufbase[i] = source[i];
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < here; ++i) {
|
||||
bufbase[i] = source[i];
|
||||
}
|
||||
const int nh = n - here;
|
||||
const float *const srcbase = source + here;
|
||||
float *const buf = m_buffer;
|
||||
for (int i = 0; i < nh; ++i) {
|
||||
buf[i] = srcbase[i];
|
||||
}
|
||||
}
|
||||
|
||||
writer += n;
|
||||
while (writer >= m_size) writer -= m_size;
|
||||
m_writer = writer;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int zero(int n) {
|
||||
|
||||
int available = getWriteSpace();
|
||||
if (n > available) {
|
||||
n = available;
|
||||
}
|
||||
if (n == 0) return n;
|
||||
|
||||
int writer = m_writer;
|
||||
int here = m_size - writer;
|
||||
float *const bufbase = m_buffer + writer;
|
||||
|
||||
if (here >= n) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
bufbase[i] = 0.f;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < here; ++i) {
|
||||
bufbase[i] = 0.f;
|
||||
}
|
||||
const int nh = n - here;
|
||||
for (int i = 0; i < nh; ++i) {
|
||||
m_buffer[i] = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
writer += n;
|
||||
while (writer >= m_size) writer -= m_size;
|
||||
m_writer = writer;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
protected:
|
||||
float *m_buffer;
|
||||
int m_writer;
|
||||
int m_reader;
|
||||
int m_size;
|
||||
|
||||
private:
|
||||
RingBuffer(const RingBuffer &); // not provided
|
||||
RingBuffer &operator=(const RingBuffer &); // not provided
|
||||
};
|
||||
|
||||
Plugin *m_plugin;
|
||||
size_t m_inputStepSize;
|
||||
size_t m_inputBlockSize;
|
||||
size_t m_stepSize;
|
||||
size_t m_blockSize;
|
||||
size_t m_channels;
|
||||
vector<vector<float> > m_queue;
|
||||
float **m_buffers; // in fact an array of pointers into the queue
|
||||
size_t m_inputPos; // start position in the queue of next input block
|
||||
vector<RingBuffer *> m_queue;
|
||||
float **m_buffers;
|
||||
float m_inputSampleRate;
|
||||
RealTime m_timestamp;
|
||||
OutputList m_outputs;
|
||||
|
|
@ -121,8 +274,8 @@ PluginBufferingAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) :
|
|||
m_stepSize(0),
|
||||
m_blockSize(0),
|
||||
m_channels(0),
|
||||
m_queue(0),
|
||||
m_buffers(0),
|
||||
m_inputPos(0),
|
||||
m_inputSampleRate(inputSampleRate),
|
||||
m_timestamp()
|
||||
{
|
||||
|
|
@ -132,8 +285,12 @@ PluginBufferingAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) :
|
|||
PluginBufferingAdapter::Impl::~Impl()
|
||||
{
|
||||
// the adapter will delete the plugin
|
||||
|
||||
delete [] m_buffers;
|
||||
|
||||
for (size_t i = 0; i < m_channels; ++i) {
|
||||
delete m_queue[i];
|
||||
delete[] m_buffers[i];
|
||||
}
|
||||
delete[] m_buffers;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
|
@ -184,9 +341,13 @@ PluginBufferingAdapter::Impl::initialise(size_t channels, size_t stepSize, size_
|
|||
std::cerr << "PluginBufferingAdapter::initialise: plugin's preferred stepSize greater than blockSize, giving up!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_queue.resize(m_channels);
|
||||
m_buffers = new float*[m_channels];
|
||||
|
||||
m_buffers = new float *[m_channels];
|
||||
|
||||
for (size_t i = 0; i < m_channels; ++i) {
|
||||
m_queue.push_back(new RingBuffer(m_blockSize + m_inputBlockSize));
|
||||
m_buffers[i] = new float[m_blockSize];
|
||||
}
|
||||
|
||||
return m_plugin->initialise(m_channels, m_stepSize, m_blockSize);
|
||||
}
|
||||
|
|
@ -212,23 +373,22 @@ PluginBufferingAdapter::Impl::process(const float *const *inputBuffers,
|
|||
|
||||
// queue the new input
|
||||
|
||||
//std::cerr << "unread " << m_queue[0].size() - m_inputPos << " samples" << std::endl;
|
||||
//std::cerr << "queueing " << m_inputBlockSize - (m_queue[0].size() - m_inputPos) << " samples" << std::endl;
|
||||
|
||||
for (size_t i = 0; i < m_channels; ++i)
|
||||
for (size_t j = m_queue[0].size() - m_inputPos; j < m_inputBlockSize; ++j)
|
||||
m_queue[i].push_back(inputBuffers[i][j]);
|
||||
|
||||
m_inputPos += m_inputStepSize;
|
||||
for (size_t i = 0; i < m_channels; ++i) {
|
||||
int written = m_queue[i]->write(inputBuffers[i], m_inputBlockSize);
|
||||
if (written < int(m_inputBlockSize) && i == 0) {
|
||||
std::cerr << "WARNING: PluginBufferingAdapter::Impl::process: "
|
||||
<< "Buffer overflow: wrote " << written
|
||||
<< " of " << m_inputBlockSize
|
||||
<< " input samples (for plugin step size "
|
||||
<< m_stepSize << ", block size " << m_blockSize << ")"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// process as much as we can
|
||||
while (m_queue[0].size() >= m_blockSize)
|
||||
{
|
||||
|
||||
while (m_queue[0]->getReadSpace() >= int(m_blockSize)) {
|
||||
processBlock(allFeatureSets, timestamp);
|
||||
m_inputPos -= m_stepSize;
|
||||
|
||||
//std::cerr << m_queue[0].size() << " samples still left in queue" << std::endl;
|
||||
//std::cerr << "inputPos = " << m_inputPos << std::endl;
|
||||
}
|
||||
|
||||
return allFeatureSets;
|
||||
|
|
@ -240,67 +400,67 @@ PluginBufferingAdapter::Impl::getRemainingFeatures()
|
|||
FeatureSet allFeatureSets;
|
||||
|
||||
// process remaining samples in queue
|
||||
while (m_queue[0].size() >= m_blockSize)
|
||||
{
|
||||
while (m_queue[0]->getReadSpace() >= int(m_blockSize)) {
|
||||
processBlock(allFeatureSets, m_timestamp);
|
||||
}
|
||||
|
||||
// pad any last samples remaining and process
|
||||
if (m_queue[0].size() > 0)
|
||||
{
|
||||
for (size_t i = 0; i < m_channels; ++i)
|
||||
while (m_queue[i].size() < m_blockSize)
|
||||
m_queue[i].push_back(0.0);
|
||||
if (m_queue[0]->getReadSpace() > 0) {
|
||||
for (size_t i = 0; i < m_channels; ++i) {
|
||||
m_queue[i]->zero(m_blockSize - m_queue[i]->getReadSpace());
|
||||
}
|
||||
processBlock(allFeatureSets, m_timestamp);
|
||||
}
|
||||
|
||||
// get remaining features
|
||||
|
||||
FeatureSet featureSet = m_plugin->getRemainingFeatures();
|
||||
|
||||
for (map<int, FeatureList>::iterator iter = featureSet.begin();
|
||||
iter != featureSet.end(); ++iter)
|
||||
{
|
||||
iter != featureSet.end(); ++iter) {
|
||||
FeatureList featureList = iter->second;
|
||||
for (size_t i = 0; i < featureList.size(); ++i)
|
||||
allFeatureSets[iter->first].push_back(featureList[i]);
|
||||
for (size_t i = 0; i < featureList.size(); ++i) {
|
||||
allFeatureSets[iter->first].push_back(featureList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return allFeatureSets;
|
||||
}
|
||||
|
||||
void
|
||||
PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets, RealTime timestamp)
|
||||
PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets,
|
||||
RealTime timestamp)
|
||||
{
|
||||
//std::cerr << m_queue[0].size() << " samples left in queue" << std::endl;
|
||||
|
||||
// point the buffers to the head of the queue
|
||||
for (size_t i = 0; i < m_channels; ++i)
|
||||
m_buffers[i] = &m_queue[i][0];
|
||||
|
||||
for (size_t i = 0; i < m_channels; ++i) {
|
||||
m_queue[i]->peek(m_buffers[i], m_blockSize);
|
||||
}
|
||||
|
||||
FeatureSet featureSet = m_plugin->process(m_buffers, m_timestamp);
|
||||
|
||||
for (map<int, FeatureList>::iterator iter = featureSet.begin();
|
||||
iter != featureSet.end(); ++iter)
|
||||
{
|
||||
iter != featureSet.end(); ++iter) {
|
||||
|
||||
FeatureList featureList = iter->second;
|
||||
int outputNo = iter->first;
|
||||
|
||||
for (size_t i = 0; i < featureList.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < featureList.size(); ++i) {
|
||||
|
||||
// make sure the timestamp is set
|
||||
switch (m_outputs[outputNo].sampleType)
|
||||
{
|
||||
switch (m_outputs[outputNo].sampleType) {
|
||||
|
||||
case OutputDescriptor::OneSamplePerStep:
|
||||
// use our internal timestamp - OK????
|
||||
featureList[i].timestamp = m_timestamp;
|
||||
break;
|
||||
|
||||
case OutputDescriptor::FixedSampleRate:
|
||||
// use our internal timestamp
|
||||
featureList[i].timestamp = m_timestamp;
|
||||
break;
|
||||
|
||||
case OutputDescriptor::VariableSampleRate:
|
||||
break; // plugin must set timestamp
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -310,14 +470,17 @@ PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets, RealTime
|
|||
}
|
||||
|
||||
// step forward
|
||||
for (size_t i = 0; i < m_channels; ++i)
|
||||
m_queue[i].erase(m_queue[i].begin(), m_queue[i].begin() + m_stepSize);
|
||||
|
||||
for (size_t i = 0; i < m_channels; ++i) {
|
||||
m_queue[i]->skip(m_stepSize);
|
||||
}
|
||||
|
||||
// fake up the timestamp each time we step forward
|
||||
//std::cerr << m_timestamp;
|
||||
long frame = RealTime::realTime2Frame(m_timestamp, int(m_inputSampleRate + 0.5));
|
||||
m_timestamp = RealTime::frame2RealTime(frame + m_stepSize, int(m_inputSampleRate + 0.5));
|
||||
//std::cerr << "--->" << m_timestamp << std::endl;
|
||||
|
||||
long frame = RealTime::realTime2Frame(m_timestamp,
|
||||
int(m_inputSampleRate + 0.5));
|
||||
m_timestamp = RealTime::frame2RealTime(frame + m_stepSize,
|
||||
int(m_inputSampleRate + 0.5));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,28 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
/**
|
||||
* If you want to compile using FFTW instead of the built-in FFT
|
||||
* implementation for the PluginInputDomainAdapter, define HAVE_FFTW3
|
||||
* in the Makefile.
|
||||
*
|
||||
* Remember that FFTW is licensed under the GPL (unlike this SDK, which
|
||||
* is licensed liberally in order to permit closed-source usage), so
|
||||
* you should not define this symbol unless your code is also under the
|
||||
* GPL. Also, parties redistributing this SDK for use in other
|
||||
* programs should be careful _not_ to define this symbol in order not
|
||||
* to affect the stated license of this SDK.
|
||||
*
|
||||
* Note: This code uses FFTW_MEASURE, and will perform badly on its
|
||||
* first invocation unless the host has saved and restored FFTW wisdom
|
||||
* (see the FFTW documentation).
|
||||
*/
|
||||
#ifdef HAVE_FFTW3
|
||||
#include <fftw3.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Vamp {
|
||||
|
||||
namespace HostExt {
|
||||
|
|
@ -58,15 +80,22 @@ public:
|
|||
protected:
|
||||
Plugin *m_plugin;
|
||||
float m_inputSampleRate;
|
||||
size_t m_channels;
|
||||
size_t m_blockSize;
|
||||
int m_channels;
|
||||
int m_blockSize;
|
||||
float **m_freqbuf;
|
||||
|
||||
double *m_ri;
|
||||
double *m_window;
|
||||
|
||||
#ifdef HAVE_FFTW3
|
||||
fftw_plan m_plan;
|
||||
fftw_complex *m_cbuf;
|
||||
#else
|
||||
double *m_ro;
|
||||
double *m_io;
|
||||
|
||||
void fft(unsigned int n, bool inverse,
|
||||
double *ri, double *ii, double *ro, double *io);
|
||||
#endif
|
||||
|
||||
size_t makeBlockSizeAcceptable(size_t) const;
|
||||
};
|
||||
|
|
@ -117,7 +146,16 @@ PluginInputDomainAdapter::Impl::Impl(Plugin *plugin, float inputSampleRate) :
|
|||
m_inputSampleRate(inputSampleRate),
|
||||
m_channels(0),
|
||||
m_blockSize(0),
|
||||
m_freqbuf(0)
|
||||
m_freqbuf(0),
|
||||
m_ri(0),
|
||||
m_window(0),
|
||||
#ifdef HAVE_FFTW3
|
||||
m_plan(0),
|
||||
m_cbuf(0)
|
||||
#else
|
||||
m_ro(0),
|
||||
m_io(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -126,23 +164,38 @@ PluginInputDomainAdapter::Impl::~Impl()
|
|||
// the adapter will delete the plugin
|
||||
|
||||
if (m_channels > 0) {
|
||||
for (size_t c = 0; c < m_channels; ++c) {
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
delete[] m_freqbuf[c];
|
||||
}
|
||||
delete[] m_freqbuf;
|
||||
#ifdef HAVE_FFTW3
|
||||
if (m_plan) {
|
||||
fftw_destroy_plan(m_plan);
|
||||
fftw_free(m_ri);
|
||||
fftw_free(m_cbuf);
|
||||
m_plan = 0;
|
||||
}
|
||||
#else
|
||||
delete[] m_ri;
|
||||
delete[] m_ro;
|
||||
delete[] m_io;
|
||||
#endif
|
||||
delete[] m_window;
|
||||
}
|
||||
}
|
||||
|
||||
// for some visual studii apparently
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979232846
|
||||
#endif
|
||||
|
||||
bool
|
||||
PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, size_t blockSize)
|
||||
{
|
||||
if (m_plugin->getInputDomain() == TimeDomain) {
|
||||
|
||||
m_blockSize = blockSize;
|
||||
m_channels = channels;
|
||||
m_blockSize = int(blockSize);
|
||||
m_channels = int(channels);
|
||||
|
||||
return m_plugin->initialise(channels, stepSize, blockSize);
|
||||
}
|
||||
|
|
@ -158,25 +211,48 @@ PluginInputDomainAdapter::Impl::initialise(size_t channels, size_t stepSize, siz
|
|||
}
|
||||
|
||||
if (m_channels > 0) {
|
||||
for (size_t c = 0; c < m_channels; ++c) {
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
delete[] m_freqbuf[c];
|
||||
}
|
||||
delete[] m_freqbuf;
|
||||
#ifdef HAVE_FFTW3
|
||||
if (m_plan) {
|
||||
fftw_destroy_plan(m_plan);
|
||||
fftw_free(m_ri);
|
||||
fftw_free(m_cbuf);
|
||||
m_plan = 0;
|
||||
}
|
||||
#else
|
||||
delete[] m_ri;
|
||||
delete[] m_ro;
|
||||
delete[] m_io;
|
||||
#endif
|
||||
delete[] m_window;
|
||||
}
|
||||
|
||||
m_blockSize = blockSize;
|
||||
m_channels = channels;
|
||||
m_blockSize = int(blockSize);
|
||||
m_channels = int(channels);
|
||||
|
||||
m_freqbuf = new float *[m_channels];
|
||||
for (size_t c = 0; c < m_channels; ++c) {
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
m_freqbuf[c] = new float[m_blockSize + 2];
|
||||
}
|
||||
m_window = new double[m_blockSize];
|
||||
|
||||
for (int i = 0; i < m_blockSize; ++i) {
|
||||
// Hanning window
|
||||
m_window[i] = (0.50 - 0.50 * cos((2.0 * M_PI * i) / m_blockSize));
|
||||
}
|
||||
|
||||
#ifdef HAVE_FFTW3
|
||||
m_ri = (double *)fftw_malloc(blockSize * sizeof(double));
|
||||
m_cbuf = (fftw_complex *)fftw_malloc((blockSize/2 + 1) * sizeof(fftw_complex));
|
||||
m_plan = fftw_plan_dft_r2c_1d(blockSize, m_ri, m_cbuf, FFTW_MEASURE);
|
||||
#else
|
||||
m_ri = new double[m_blockSize];
|
||||
m_ro = new double[m_blockSize];
|
||||
m_io = new double[m_blockSize];
|
||||
#endif
|
||||
|
||||
return m_plugin->initialise(channels, stepSize, blockSize);
|
||||
}
|
||||
|
|
@ -220,7 +296,11 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
|
|||
|
||||
} else if (blockSize & (blockSize-1)) {
|
||||
|
||||
// not a power of two, can't handle that with our current fft
|
||||
#ifdef HAVE_FFTW3
|
||||
// not an issue with FFTW
|
||||
#else
|
||||
|
||||
// not a power of two, can't handle that with our built-in FFT
|
||||
// implementation
|
||||
|
||||
size_t nearest = blockSize;
|
||||
|
|
@ -241,16 +321,13 @@ PluginInputDomainAdapter::Impl::makeBlockSizeAcceptable(size_t blockSize) const
|
|||
|
||||
std::cerr << "WARNING: Vamp::HostExt::PluginInputDomainAdapter::Impl::initialise: non-power-of-two\nblocksize " << blockSize << " not supported, using blocksize " << nearest << " instead" << std::endl;
|
||||
blockSize = nearest;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
// for some visual studii apparently
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979232846
|
||||
#endif
|
||||
|
||||
Plugin::FeatureSet
|
||||
PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
|
||||
RealTime timestamp)
|
||||
|
|
@ -308,33 +385,45 @@ PluginInputDomainAdapter::Impl::process(const float *const *inputBuffers,
|
|||
|
||||
// std::cerr << " to " << timestamp << std::endl;
|
||||
|
||||
for (size_t c = 0; c < m_channels; ++c) {
|
||||
for (int c = 0; c < m_channels; ++c) {
|
||||
|
||||
for (size_t i = 0; i < m_blockSize; ++i) {
|
||||
// Hanning window
|
||||
m_ri[i] = double(inputBuffers[c][i])
|
||||
* (0.50 - 0.50 * cos((2 * M_PI * i)
|
||||
/ m_blockSize));
|
||||
for (int i = 0; i < m_blockSize; ++i) {
|
||||
m_ri[i] = double(inputBuffers[c][i]) * m_window[i];
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_blockSize/2; ++i) {
|
||||
for (int i = 0; i < m_blockSize/2; ++i) {
|
||||
// FFT shift
|
||||
double value = m_ri[i];
|
||||
m_ri[i] = m_ri[i + m_blockSize/2];
|
||||
m_ri[i + m_blockSize/2] = value;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FFTW3
|
||||
|
||||
fftw_execute(m_plan);
|
||||
|
||||
for (int i = 0; i <= m_blockSize/2; ++i) {
|
||||
m_freqbuf[c][i * 2] = float(m_cbuf[i][0]);
|
||||
m_freqbuf[c][i * 2 + 1] = float(m_cbuf[i][1]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
fft(m_blockSize, false, m_ri, 0, m_ro, m_io);
|
||||
|
||||
for (size_t i = 0; i <= m_blockSize/2; ++i) {
|
||||
m_freqbuf[c][i * 2] = m_ro[i];
|
||||
m_freqbuf[c][i * 2 + 1] = m_io[i];
|
||||
for (int i = 0; i <= m_blockSize/2; ++i) {
|
||||
m_freqbuf[c][i * 2] = float(m_ro[i]);
|
||||
m_freqbuf[c][i * 2 + 1] = float(m_io[i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return m_plugin->process(m_freqbuf, timestamp);
|
||||
}
|
||||
|
||||
#ifndef HAVE_FFTW3
|
||||
|
||||
void
|
||||
PluginInputDomainAdapter::Impl::fft(unsigned int n, bool inverse,
|
||||
double *ri, double *ii, double *ro, double *io)
|
||||
|
|
@ -452,6 +541,8 @@ PluginInputDomainAdapter::Impl::fft(unsigned int n, bool inverse,
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue