annotate Source/SpectralContrast.cpp @ 15:585caf503ef5 tip

Tidy up for ROLI
author Geogaddi\David <d.m.ronan@qmul.ac.uk>
date Tue, 17 May 2016 18:50:19 +0100
parents 636c989477e7
children
rev   line source
d@10 1 /*
d@10 2 ==============================================================================
d@10 3
d@10 4 SpectralContrast.cpp
d@10 5 Created: 14 Aug 2015 12:21:29pm
d@10 6 Author: David
d@10 7
d@10 8 ==============================================================================
d@10 9 */
d@10 10
d@10 11 #include "SpectralContrast.h"
d@10 12 #include <algorithm>
d@12 13 #include <iostream>
d@10 14
d@10 15 void SpectralContrast::initSpectralContrastVariables(int frameSize, float sampleRate)
d@10 16 {
d@10 17
d@10 18 int numberBands = 6; //the number of bands in the filter
d@10 19 float lowFrequencyBound = 20; //the lower bound of the lowest band
d@10 20 float highFrequencyBound = sampleRate / 2.0f;
d@10 21 float staticDistribution = 0.15f; //the ratio of the bins to distribute equally [0, 1]
d@10 22 m_neighbourRatio = 0.4f; //the ratio of the bins in the sub band used to calculate the peak and valley", "(0,1]"
d@10 23
d@10 24 // get staticDistribution
d@10 25 float partToScale = 1.0f - staticDistribution;
d@10 26
d@10 27 float binWidth = sampleRate / frameSize;
d@10 28
d@10 29 int lastBins = 0;
d@10 30 m_startAtBin = 0;
d@10 31
d@10 32 m_numberOfBinsInBands.clear();
d@10 33 m_numberOfBinsInBands.resize(numberBands);
d@10 34 lastBins = int(lowFrequencyBound / binWidth);
d@10 35 m_startAtBin = lastBins;
d@10 36
d@10 37 // Determine how many bins are in each band to start with.
d@10 38 // The rest of the bands will be distributed logarithmically.
d@10 39 int totalNumberOfBins = int(highFrequencyBound / binWidth);
d@10 40 highFrequencyBound = int(partToScale * totalNumberOfBins) * binWidth;
d@10 41 int staticBinsPerBand = int((1 - partToScale) * totalNumberOfBins) / numberBands;
d@10 42 float ratio = highFrequencyBound / lowFrequencyBound;
d@10 43 float ratioPerBand = pow(ratio, float(1.0 / numberBands));
d@10 44 float currFreq = lowFrequencyBound;
d@10 45
d@10 46 for (int i = 0; i < numberBands; ++i)
d@10 47 {
d@10 48 currFreq = currFreq * ratioPerBand;
d@10 49 m_numberOfBinsInBands[i] = int(currFreq / binWidth - lastBins + staticBinsPerBand);
d@10 50 lastBins = int(currFreq / binWidth);
d@10 51 }
d@10 52
d@10 53 }
d@10 54
d@10 55 void SpectralContrast::computeSpectralContrast(std::vector<float> spectrum, std::vector<float>& spectralContrast, std::vector<float>& valleys)
d@10 56 {
d@10 57 std::vector<float> spectrumCopy = spectrum; // I want a copy because I'll be transforming it
d@10 58
d@10 59 //substitute minReal for a static value that is the same in all architectures. i.e.: 1e-30
d@12 60 float minFloat = std::numeric_limits<float>::min(); //numeric_limits<Real>::min();
d@10 61
d@10 62 spectralContrast.clear();
d@10 63 valleys.clear();
d@10 64
d@10 65 int specIdx = m_startAtBin;
d@10 66
d@12 67 for (int bandIdx = 0; bandIdx < int(m_numberOfBinsInBands.size()) && specIdx < int(spectrumCopy.size()); ++bandIdx)
d@10 68 {
d@10 69 // get the mean of the band
d@10 70 float bandMean = 0;
d@10 71 for (int i = 0; i < m_numberOfBinsInBands[bandIdx] && specIdx + i < int(spectrumCopy.size()); ++i)
d@10 72 {
d@10 73 bandMean += spectrumCopy[specIdx + i];
d@10 74 }
d@10 75
d@12 76 if (m_numberOfBinsInBands[bandIdx] != 0)
d@10 77 {
d@12 78 bandMean /= m_numberOfBinsInBands[bandIdx];
d@10 79 }
d@10 80
d@12 81 bandMean += minFloat;
d@12 82
d@10 83 // sort the subband (ascending order)
d@10 84 std::sort(spectrumCopy.begin() + specIdx, spectrumCopy.begin() + std::min(specIdx + m_numberOfBinsInBands[bandIdx], int(spectrum.size())));
d@10 85
d@10 86 // number of bins to take the mean of
d@10 87 int neighbourBins = int(m_neighbourRatio * m_numberOfBinsInBands[bandIdx]);
d@12 88 if (neighbourBins < 1)
d@12 89 {
d@12 90 neighbourBins = 1;
d@12 91 }
d@10 92
d@10 93 // valley (FLT_MIN prevents log(0))
d@10 94 float sum = 0;
d@12 95 for (int i = 0; i < neighbourBins && specIdx + i < int(spectrumCopy.size()); ++i)
d@10 96 {
d@12 97 sum += spectrumCopy[specIdx + i];
d@10 98 }
d@10 99
d@12 100 float valley = (sum / neighbourBins) + minFloat;
d@10 101
d@10 102 // peak
d@10 103 sum = 0;
d@12 104 for (int i = m_numberOfBinsInBands[bandIdx]; i > m_numberOfBinsInBands[bandIdx] - neighbourBins && specIdx + i - 1 < int(spectrumCopy.size()) && i > 0; --i)
d@10 105 {
d@12 106 sum += spectrumCopy[specIdx + i - 1];
d@10 107 }
d@12 108
d@10 109
d@12 110 float peak = (sum / neighbourBins) + minFloat;
d@10 111
d@12 112 float ans = (log10(peak / valley)) / (log10(bandMean) + minFloat) ;
d@12 113
d@12 114 spectralContrast.push_back(ans);
d@12 115 valleys.push_back(log10(valley));
d@10 116
d@10 117 specIdx += m_numberOfBinsInBands[bandIdx];
d@10 118 }
d@12 119
d@10 120 }