c@178: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ c@178: c@178: /* c@178: QM Vamp Plugin Set c@178: c@178: Centre for Digital Music, Queen Mary, University of London. c@178: This file copyright 2009 Thomas Wilmering. c@135: c@135: This program is free software; you can redistribute it and/or c@135: modify it under the terms of the GNU General Public License as c@135: published by the Free Software Foundation; either version 2 of the c@135: License, or (at your option) any later version. See the file c@178: COPYING included with this distribution for more information. c@178: */ c@178: c@178: #include "DWT.h" c@178: c@178: #include c@178: c@178: using std::string; c@178: using std::vector; c@178: using std::cerr; c@178: using std::endl; c@178: c@178: DWT::DWT(float inputSampleRate) : c@178: Plugin(inputSampleRate), c@178: m_stepSize(0), c@178: m_blockSize(0) c@178: { c@178: m_scales = 10; c@178: m_flength = 0; c@178: m_wavelet = Wavelet::Haar; c@178: m_threshold = 0; c@178: m_absolute = 0; c@178: } c@178: c@178: DWT::~DWT() c@178: { c@178: } c@178: c@178: string c@178: DWT::getIdentifier() const c@178: { c@178: return "qm-dwt"; c@178: } c@178: c@178: string c@178: DWT::getName() const c@178: { c@178: return "Discrete Wavelet Transform"; c@178: } c@178: c@178: string c@178: DWT::getDescription() const c@178: { c@178: return "Visualisation by scalogram"; c@178: } c@178: c@178: string c@178: DWT::getMaker() const c@178: { c@178: return "Queen Mary, University of London"; c@178: } c@178: c@178: int c@178: DWT::getPluginVersion() const c@178: { c@178: return 1; c@178: } c@178: c@178: string c@178: DWT::getCopyright() const c@178: { c@178: return "Plugin by Thomas Wilmering. Copyright (c) 2009 Thomas Wilmering and QMUL - All Rights Reserved"; c@178: } c@178: c@178: size_t c@178: DWT::getPreferredBlockSize() const c@178: { c@178: size_t s = (1 << m_scales); c@178: while (s < 1024) s *= 2; c@178: return s; c@178: } c@178: c@178: size_t c@178: DWT::getPreferredStepSize() const c@178: { c@178: return 0; c@178: } c@178: c@178: bool c@178: DWT::initialise(size_t channels, size_t stepSize, size_t blockSize) c@178: { c@178: if (channels < getMinChannelCount() || c@178: channels > getMaxChannelCount()) return false; c@210: c@210: if (m_inputSampleRate > 1000000) { // somewhat arbitrarily c@210: std::cerr << "DWT::initialise: ERROR: Maximum sample rate exceeded" << std::endl; c@210: return false; c@210: } c@178: c@178: if ((1U << m_scales) > blockSize) { c@178: std::cerr << "DWT::initialise: ERROR: Block size must be at least 2^scales (specified block size " << blockSize << " < " << (1 << m_scales) << ")" << std::endl; c@178: return false; c@178: } c@178: c@178: m_stepSize = stepSize; c@178: m_blockSize = blockSize; c@178: c@178: Wavelet::createDecompositionFilters(m_wavelet, m_lpd, m_hpd); c@178: c@178: m_flength = m_lpd.size(); // or m_hpd.size() c@178: c@178: m_samplePass.resize(m_scales); // resize buffer for samples to pass to next block c@178: c@178: for (int i=0; i b) b = 1 << s; // correct blocksize if smaller than 2^(max scale) c@178: c@178: //-------------------------------------------------------------------------------------------------- c@178: c@178: float tempDet; c@178: float aTempDet; c@178: int outloc; c@178: int halfblocksize = int(.5 * b); c@178: int fbufloc; c@178: int fbufloc2; c@178: c@178: vector< vector > wCoefficients(m_scales); // result c@178: vector tempAprx(halfblocksize,0.0); // approximation c@178: vector fbuf(b+m_flength-2,0.0); // input buffer c@178: c@178: for (int n=m_flength-2; n blocksize c@178: m_samplePass[scale].push_back(fbuf[m_flength-2+n]); c@178: m_samplePass[scale].erase (m_samplePass[scale].begin(),m_samplePass[scale].begin()+b); c@178: } c@178: c@178: for (int n=0; n> 1; // the approximation in tmpfwd is stored as c@178: halfblocksize = halfblocksize >> 1; // input for next level c@178: c@178: for (int n=m_flength-2; n(b+m_flength-2).swap(fbuf); c@178: vector(halfblocksize).swap(tempAprx); // set new size with zeros c@178: } c@178: } c@178: c@178: c@178: //----------------------------------------------------------------------------------------- c@178: c@178: halfblocksize = int(.5 * b_init); c@178: c@178: for (int m = 0; m > wCoefficients(m_scales); // result c@178: vector tempAprx(halfblocksize,0.0); // approximation c@178: vector fbuf(b+len-2,0.0); // input buffer c@178: c@178: //for (int n=len-2; n blocksize c@178: m_samplePass[scale].push_back(fbuf[len-2+n]); c@178: m_samplePass[scale].erase (m_samplePass[scale].begin(),m_samplePass[scale].begin()+b); c@178: } c@178: c@178: for (int n=0; n> 1; // the approximation in tmpfwd is stored as c@178: halfblocksize = halfblocksize >> 1; // input for next level c@178: c@178: for (int n=len-2; n(b+len-2).swap(fbuf); c@178: vector(halfblocksize).swap(tempAprx); // set new size with zeros c@178: } c@178: c@178: } c@178: c@178: //----------------------------------------------------------------------------------------- c@178: c@178: halfblocksize = int(.5 * b_init + 0.1); c@178: c@178: for (int m = 0; m