Mercurial > hg > constant-q-cpp
changeset 34:e9752aa1b234
More on reconstructing CQ shape. This is not always correct yet, though
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 06 Nov 2013 14:30:19 +0000 |
parents | f6ef28b02be4 |
children | 75d528478feb |
files | cpp-qm-dsp/ConstantQ.cpp cpp-qm-dsp/ConstantQ.h cpp-qm-dsp/Makefile |
diffstat | 3 files changed, 52 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/cpp-qm-dsp/ConstantQ.cpp Wed Nov 06 09:09:55 2013 +0000 +++ b/cpp-qm-dsp/ConstantQ.cpp Wed Nov 06 14:30:19 2013 +0000 @@ -69,7 +69,8 @@ m_decimators.push_back(0); for (int oct = 1; oct < m_octaves; ++oct) { - Resampler *r = new Resampler(sourceRate, sourceRate / pow(2, oct)); + Resampler *r = new Resampler + (sourceRate, sourceRate / pow(2, oct), 60, 0.02); latencies.push_back(r->getLatency()); m_decimators.push_back(r); } @@ -105,50 +106,51 @@ //!!!! need some mechanism for handling remaining samples at the end while (m_buffers[0].size() >= m_bigBlockSize) { - vector<vector<double> > chunk = processBigBlock(); - for (int i = 0; i < m_octaves; ++i) { - vector<double> v; - v.insert(v.end(), - m_buffers[i].begin() + m_bigBlockSize/pow(2,i), m_buffers[i].end()); - m_buffers[i] = v; + + int base = out.size(); + int totalColumns = pow(2, m_octaves - 1) * m_p.atomsPerFrame; + cerr << "totalColumns = " << totalColumns << endl; + for (int i = 0; i < totalColumns; ++i) { + out.push_back(vector<double>()); } - out.insert(out.end(), chunk.begin(), chunk.end()); + + for (int octave = 0; octave < m_octaves; ++octave) { + + int blocksThisOctave = pow(2, (m_octaves - octave - 1)); +// cerr << "octave " << octave+1 << " of " << m_octaves << ", n = " << blocksThisOctave << endl; + + for (int b = 0; b < blocksThisOctave; ++b) { + vector<vector<double> > block = processOctaveBlock(octave); + + for (int j = 0; j < m_p.atomsPerFrame; ++j) { + int target = base + + (b * (totalColumns / blocksThisOctave) + + (j * ((totalColumns / blocksThisOctave) / m_p.atomsPerFrame))); +// cerr << "j " << j << " -> target " << target << endl; + for (int i = 0; i < m_p.binsPerOctave; ++i) { + out[target].push_back(block[j][m_p.binsPerOctave-i-1]); + } + } + } + } } return out; } -vector<vector<double> > -ConstantQ::processBigBlock() -{ - vector<vector<double> > out; - - for (int i = 0; i < pow(2, m_octaves - 1) * m_p.atomsPerFrame; ++i) { - out.push_back(vector<double>()); - } - cerr << "returning " << out.size() << " cols per big block" << endl; - - for (int i = 0; i < m_octaves; ++i) { - int n = pow(2, (m_octaves - i - 1)); - cerr << "octave " << i+1 << " of " << m_octaves << ", n = " << n << endl; - for (int j = 0; j < n; ++j) { - int origin = j * m_p.fftSize; //!!! no -- it's the hop but how does that add up? - vector<vector<double> > block = - processOctaveBlock(m_buffers[i].data() + origin); - - //... - } - } - - return out; -} - vector<vector<double> > -ConstantQ::processOctaveBlock(const double *data) +ConstantQ::processOctaveBlock(int octave) { vector<double> ro(m_p.fftSize, 0.0); vector<double> io(m_p.fftSize, 0.0); - m_fft->forward(data, ro.data(), io.data()); + + m_fft->forward(m_buffers[octave].data(), ro.data(), io.data()); + + vector<double> shifted; + shifted.insert(shifted.end(), + m_buffers[octave].begin() + m_p.fftHop, + m_buffers[octave].end()); + m_buffers[octave] = shifted; vector<C> cv; for (int i = 0; i < m_p.fftSize; ++i) { @@ -157,11 +159,12 @@ vector<C> cqrowvec = m_kernel->process(cv); + // Reform into a column matrix vector<vector<double> > cqblock; - for (int i = 0; i < m_p.binsPerOctave; ++i) { + for (int j = 0; j < m_p.atomsPerFrame; ++j) { cqblock.push_back(vector<double>()); - for (int j = 0; j < m_p.atomsPerFrame; ++j) { - cqblock[i].push_back(abs(cqrowvec[i * m_p.atomsPerFrame + j])); + for (int i = 0; i < m_p.binsPerOctave; ++i) { + cqblock[j].push_back(abs(cqrowvec[i * m_p.atomsPerFrame + j])); } }
--- a/cpp-qm-dsp/ConstantQ.h Wed Nov 06 09:09:55 2013 +0000 +++ b/cpp-qm-dsp/ConstantQ.h Wed Nov 06 14:30:19 2013 +0000 @@ -18,6 +18,14 @@ int binsPerOctave); ~ConstantQ(); + double getSampleRate() const { return m_sampleRate; } + double getMaxFrequency() const { return m_p.maxFrequency; } + double getMinFrequency() const { return m_p.minFrequency; } // actual min, not that provided to ctor + int getBinsPerOctave() const { return m_binsPerOctave; } + int getOctaves() const { return m_octaves; } + int getTotalBins() const { return m_octaves * m_binsPerOctave; } + int getColumnHop() const { return m_p.fftHop / m_p.atomsPerFrame; } + std::vector<std::vector<double> > process(std::vector<double>); private: @@ -40,8 +48,7 @@ FFTReal *m_fft; void initialise(); - std::vector<std::vector<double> > processBigBlock(); - std::vector<std::vector<double> > processOctaveBlock(const double *data); + std::vector<std::vector<double> > processOctaveBlock(int octave); }; #endif
--- a/cpp-qm-dsp/Makefile Wed Nov 06 09:09:55 2013 +0000 +++ b/cpp-qm-dsp/Makefile Wed Nov 06 14:30:19 2013 +0000 @@ -3,8 +3,8 @@ CFLAGS := -I../.. $(CFLAGS) $(DEFINES) -CXXFLAGS := -I../.. -Wall -g $(CXXFLAGS) $(DEFINES) -#CXXFLAGS := -I../.. -Wall -O3 -ffast-math -ftree-vectorize $(CXXFLAGS) $(DEFINES) +#CXXFLAGS := -I../.. -fPIC -Wall -g $(CXXFLAGS) $(DEFINES) +CXXFLAGS := -I../.. -fPIC -Wall -O3 -ffast-math -ftree-vectorize $(CXXFLAGS) $(DEFINES) LDFLAGS := $(LDFLAGS)