c@97: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ c@97: c@97: /* c@97: QM Vamp Plugin Set c@97: c@97: Centre for Digital Music, Queen Mary, University of London. c@97: 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@135: COPYING included with this distribution for more information. c@97: */ c@97: c@97: #include "DWT.h" c@97: c@97: #include c@97: c@97: using std::string; c@97: using std::vector; c@97: using std::cerr; c@97: using std::endl; c@97: c@97: DWT::DWT(float inputSampleRate) : c@97: Plugin(inputSampleRate), c@97: m_stepSize(0), c@97: m_blockSize(0) c@97: { c@97: m_scales = 10; c@97: m_flength = 0; c@97: m_wavelet = Wavelet::Haar; c@97: m_threshold = 0; c@97: m_absolute = 0; c@97: } c@97: c@97: DWT::~DWT() c@97: { c@97: } c@97: c@97: string c@97: DWT::getIdentifier() const c@97: { c@98: return "qm-dwt"; c@97: } c@97: c@97: string c@97: DWT::getName() const c@97: { c@97: return "Discrete Wavelet Transform"; c@97: } c@97: c@97: string c@97: DWT::getDescription() const c@97: { c@97: return "Visualisation by scalogram"; c@97: } c@97: c@97: string c@97: DWT::getMaker() const c@97: { c@97: return "Queen Mary, University of London"; c@97: } c@97: c@97: int c@97: DWT::getPluginVersion() const c@97: { c@97: return 1; c@97: } c@97: c@97: string c@97: DWT::getCopyright() const c@97: { c@97: return "Plugin by Thomas Wilmering. Copyright (c) 2009 Thomas Wilmering and QMUL - All Rights Reserved"; c@97: } c@97: c@97: size_t c@129: DWT::getPreferredBlockSize() const c@129: { c@129: size_t s = (1 << m_scales); c@129: while (s < 1024) s *= 2; c@129: return s; c@129: } c@129: c@129: size_t c@97: DWT::getPreferredStepSize() const c@97: { c@97: return 0; c@97: } c@97: c@97: bool c@97: DWT::initialise(size_t channels, size_t stepSize, size_t blockSize) c@97: { c@97: if (channels < getMinChannelCount() || c@97: channels > getMaxChannelCount()) return false; c@97: c@129: if ((1 << m_scales) > blockSize) { c@129: std::cerr << "DWT::initialise: ERROR: Block size must be at least 2^scales (specified block size " << blockSize << " < " << (1 << m_scales) << ")" << std::endl; c@129: return false; c@129: } c@129: c@97: m_stepSize = stepSize; c@97: m_blockSize = blockSize; c@97: c@97: Wavelet::createDecompositionFilters(m_wavelet, m_lpd, m_hpd); c@97: c@97: m_flength = m_lpd.size(); // or m_hpd.size() c@97: c@97: m_samplePass.resize(m_scales); // resize buffer for samples to pass to next block c@97: c@97: for (int i=0; i b) b = 1 << s; // correct blocksize if smaller than 2^(max scale) c@97: c@97: //-------------------------------------------------------------------------------------------------- c@97: c@97: float tempDet; c@127: float aTempDet; c@97: int outloc; c@97: int halfblocksize = int(.5 * b); c@97: int fbufloc; c@97: int fbufloc2; c@97: c@97: vector< vector > wCoefficients(m_scales); // result c@97: vector tempAprx(halfblocksize,0.0); // approximation c@97: vector fbuf(b+m_flength-2,0.0); // input buffer c@97: c@97: for (int n=m_flength-2; n blocksize c@97: m_samplePass[scale].push_back(fbuf[m_flength-2+n]); c@97: m_samplePass[scale].erase (m_samplePass[scale].begin(),m_samplePass[scale].begin()+b); c@97: } c@97: c@97: for (int n=0; n> 1; // the approximation in tmpfwd is stored as c@97: halfblocksize = halfblocksize >> 1; // input for next level c@97: c@97: for (int n=m_flength-2; n(b+m_flength-2).swap(fbuf); c@97: vector(halfblocksize).swap(tempAprx); // set new size with zeros c@97: } c@97: } c@97: c@97: c@97: //----------------------------------------------------------------------------------------- c@97: c@97: halfblocksize = int(.5 * b_init); c@97: c@97: for (int m = 0; m > wCoefficients(m_scales); // result c@97: vector tempAprx(halfblocksize,0.0); // approximation c@97: vector fbuf(b+len-2,0.0); // input buffer c@97: c@97: //for (int n=len-2; n blocksize c@97: m_samplePass[scale].push_back(fbuf[len-2+n]); c@97: m_samplePass[scale].erase (m_samplePass[scale].begin(),m_samplePass[scale].begin()+b); c@97: } c@97: c@97: for (int n=0; n> 1; // the approximation in tmpfwd is stored as c@97: halfblocksize = halfblocksize >> 1; // input for next level c@97: c@97: for (int n=len-2; n(b+len-2).swap(fbuf); c@97: vector(halfblocksize).swap(tempAprx); // set new size with zeros c@97: } c@97: c@97: } c@97: c@97: //----------------------------------------------------------------------------------------- c@97: c@97: halfblocksize = int(.5 * b_init + 0.1); c@97: c@97: for (int m = 0; m