annotate src/FeatureDownsample.cpp @ 60:1ea2aed23d4a tip

Fix version
author Chris Cannam
date Thu, 13 Feb 2020 13:37:36 +0000
parents 00b6ae41efbe
children
rev   line source
Chris@35 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@35 2
Chris@42 3 /*
Chris@42 4 Tipic
Chris@42 5
Chris@42 6 Centre for Digital Music, Queen Mary, University of London.
Chris@42 7
Chris@42 8 This program is free software; you can redistribute it and/or
Chris@42 9 modify it under the terms of the GNU General Public License as
Chris@42 10 published by the Free Software Foundation; either version 2 of the
Chris@42 11 License, or (at your option) any later version. See the file
Chris@42 12 COPYING included with this distribution for more information.
Chris@42 13 */
Chris@42 14
Chris@35 15 #include "FeatureDownsample.h"
Chris@35 16
Chris@42 17 #include "dsp/signalconditioning/Filter.h"
Chris@42 18 #include "base/Window.h"
Chris@42 19 #include "maths/MathUtilities.h"
Chris@35 20
Chris@35 21 #include <stdexcept>
Chris@35 22
Chris@35 23 using namespace std;
Chris@35 24
Chris@35 25 FeatureDownsample::FeatureDownsample(Parameters params) :
Chris@35 26 m_params(params)
Chris@35 27 {
Chris@35 28 if (params.downsampleFactor < 2 || params.windowLength < 2) {
Chris@35 29 throw invalid_argument
Chris@35 30 ("Expected downsampleFactor and windowLength each to be at least 2");
Chris@35 31 }
Chris@35 32
Chris@35 33 // Our windows are periodic rather than symmetric, but we want a
Chris@35 34 // symmetric window here
Chris@37 35 Window<double> w(HanningWindow, params.windowLength + 1);
Chris@37 36 vector<double> wdat(w.getWindowData());;
Chris@37 37 vector<double> wd(wdat.begin()+1, wdat.end());
Chris@35 38
Chris@36 39 double divisor = 0.0;
Chris@36 40 for (auto x: wd) divisor += x;
Chris@36 41 for (auto &x: wd) x /= divisor;
Chris@36 42
Chris@35 43 // FIR filter
Chris@35 44 for (int i = 0; i < m_params.featureSize; ++i) {
Chris@35 45 m_filters.push_back(new Filter({ {}, wd }));
Chris@35 46 }
Chris@35 47
Chris@36 48 m_toNext = 1;
Chris@36 49 m_toDrop = m_params.windowLength / 2;
Chris@36 50 m_inCount = 0;
Chris@36 51 m_outCount = 0;
Chris@35 52 }
Chris@35 53
Chris@35 54 FeatureDownsample::~FeatureDownsample()
Chris@35 55 {
Chris@35 56 for (auto &f: m_filters) delete f;
Chris@35 57 }
Chris@35 58
Chris@35 59 void
Chris@35 60 FeatureDownsample::reset()
Chris@35 61 {
Chris@35 62 for (auto &f: m_filters) f->reset();
Chris@36 63 m_toNext = 1;
Chris@36 64 m_toDrop = m_params.windowLength / 2;
Chris@36 65 m_inCount = 0;
Chris@36 66 m_outCount = 0;
Chris@35 67 }
Chris@35 68
Chris@35 69 RealBlock
Chris@35 70 FeatureDownsample::process(const RealBlock &in)
Chris@35 71 {
Chris@36 72 RealBlock out;
Chris@35 73
Chris@35 74 for (const auto &col: in) {
Chris@35 75 RealColumn outcol;
Chris@36 76 if (m_toDrop > 0) {
Chris@36 77 --m_toDrop;
Chris@36 78 } else {
Chris@36 79 --m_toNext;
Chris@36 80 }
Chris@35 81 for (int i = 0; i < m_params.featureSize; ++i) {
Chris@35 82 double val = 0.0;
Chris@35 83 m_filters[i]->process(&col[i], &val, 1);
Chris@35 84 if (m_toNext == 0) {
Chris@35 85 outcol.push_back(val);
Chris@35 86 }
Chris@35 87 }
Chris@35 88 if (m_toNext == 0) {
Chris@42 89 out.push_back(MathUtilities::normaliseLp
Chris@37 90 (outcol, m_params.normP, m_params.normThresh));
Chris@35 91 m_toNext = m_params.downsampleFactor;
Chris@36 92 ++m_outCount;
Chris@35 93 }
Chris@36 94 ++m_inCount;
Chris@36 95 }
Chris@36 96
Chris@36 97 return out;
Chris@36 98 }
Chris@36 99
Chris@36 100 RealBlock
Chris@36 101 FeatureDownsample::getRemainingOutput()
Chris@36 102 {
Chris@36 103 RealBlock pad(m_params.windowLength, RealColumn(m_params.featureSize, 0.0));
Chris@36 104 RealBlock tail = process(pad);
Chris@36 105 int expected = m_inCount / m_params.downsampleFactor;
Chris@36 106 RealBlock out;
Chris@36 107 for (int i = 0;
Chris@36 108 m_outCount < expected && i < int(tail.size());
Chris@36 109 ++i, ++m_outCount) {
Chris@42 110 out.push_back(MathUtilities::normaliseLp
Chris@37 111 (tail[i], m_params.normP, m_params.normThresh));
Chris@35 112 }
Chris@35 113 return out;
Chris@35 114 }
Chris@35 115
Chris@36 116