Mercurial > hg > vamp-tempogram
comparison NoveltyCurve.cpp @ 5:8d7e336b41e9
Adding NoveltyCurve.*
author | Carl Bussey <c.bussey@se10.qmul.ac.uk> |
---|---|
date | Tue, 05 Aug 2014 15:59:15 +0100 |
parents | |
children | 21147df9cb2d |
comparison
equal
deleted
inserted
replaced
4:597f033fa7a2 | 5:8d7e336b41e9 |
---|---|
1 // | |
2 // NoveltyCurve.cpp | |
3 // Tempogram | |
4 // | |
5 // Created by Carl Bussey on 10/07/2014. | |
6 // Copyright (c) 2014 Carl Bussey. All rights reserved. | |
7 // | |
8 | |
9 #include <cmath> | |
10 #include <vector> | |
11 #include <iostream> | |
12 #include "FIRFilter.h" | |
13 #include "WindowFunction.h" | |
14 using namespace std; | |
15 #include "NoveltyCurve.h" | |
16 | |
17 NoveltyCurve::NoveltyCurve(float samplingFrequency, int blockSize, int numberOfBlocks, int compressionConstant) : | |
18 m_samplingFrequency(samplingFrequency), | |
19 m_blockSize(blockSize), | |
20 m_numberOfBlocks(numberOfBlocks), | |
21 m_compressionConstant(compressionConstant), | |
22 m_numberOfBands(5), | |
23 m_bandBoundaries(NULL), | |
24 m_hannLength(65), | |
25 m_hannWindow(NULL), | |
26 m_bandSum(NULL) | |
27 { | |
28 initialise(); | |
29 } | |
30 | |
31 NoveltyCurve::~NoveltyCurve(){ | |
32 cleanup(); | |
33 } | |
34 | |
35 void | |
36 NoveltyCurve::initialise(){ | |
37 data = vector<float>(m_numberOfBlocks); | |
38 | |
39 m_hannWindow = new float[m_hannLength]; | |
40 WindowFunction::hanning(m_hannWindow, m_hannLength, true); | |
41 | |
42 m_bandBoundaries = new int[m_numberOfBands+1]; //make index variable | |
43 | |
44 m_bandBoundaries[0] = 0; | |
45 for (int band = 1; band < m_numberOfBands; band++){ | |
46 float lowFreq = 500*pow(2.5, band-1); | |
47 m_bandBoundaries[band] = m_blockSize*lowFreq/m_samplingFrequency; | |
48 } | |
49 m_bandBoundaries[m_numberOfBands] = m_blockSize/2 + 1; | |
50 | |
51 m_bandSum = new float * [m_numberOfBands]; | |
52 for (int i = 0; i < m_numberOfBands; i++){ | |
53 m_bandSum[i] = new float[m_numberOfBlocks]; | |
54 } | |
55 } | |
56 | |
57 void | |
58 NoveltyCurve::cleanup(){ | |
59 delete []m_hannWindow; | |
60 m_hannWindow = NULL; | |
61 delete []m_bandBoundaries; | |
62 m_bandBoundaries = NULL; | |
63 | |
64 for(int i = 0; i < m_numberOfBands; i++){ | |
65 delete []m_bandSum[i]; | |
66 m_bandSum[i] = NULL; | |
67 } | |
68 delete []m_bandSum; | |
69 m_bandSum = NULL; | |
70 } | |
71 | |
72 float NoveltyCurve::calculateMax(float ** spectrogram){ | |
73 int specLength = (m_blockSize/2 + 1); | |
74 float max = 0; | |
75 | |
76 for (int j = 0; j < m_numberOfBlocks; j++){ | |
77 for (int i = 0; i < specLength; i++){ | |
78 max = max > spectrogram[i][j] ? max : spectrogram[i][j]; | |
79 } | |
80 } | |
81 | |
82 return max; | |
83 } | |
84 | |
85 void NoveltyCurve::subtractLocalAverage(float * noveltyCurve){ | |
86 vector<float> localAverage(m_numberOfBlocks); | |
87 | |
88 FIRFilter *filter = new FIRFilter(m_numberOfBlocks, m_hannLength); | |
89 filter->process(&noveltyCurve[0], m_hannWindow, &localAverage[0]); | |
90 delete filter; | |
91 | |
92 for (int i = 0; i < m_numberOfBlocks; i++){ | |
93 noveltyCurve[i] -= localAverage[i]; | |
94 noveltyCurve[i] = noveltyCurve[i] >= 0 ? noveltyCurve[i] : 0; | |
95 } | |
96 } | |
97 | |
98 vector<float> | |
99 NoveltyCurve::spectrogramToNoveltyCurve(float ** spectrogram){ | |
100 | |
101 float normaliseScale = calculateMax(spectrogram); | |
102 | |
103 for (int block = 0; block < m_numberOfBlocks; block++){ | |
104 | |
105 for (int band = 0; band < m_numberOfBands; band++){ | |
106 | |
107 int specIndex = m_bandBoundaries[band]; | |
108 int bandEnd = m_bandBoundaries[band+1]; | |
109 | |
110 while(specIndex < bandEnd){ | |
111 | |
112 spectrogram[specIndex][block] /= normaliseScale; //normalise | |
113 spectrogram[specIndex][block] = log(1+m_compressionConstant*spectrogram[specIndex][block]); | |
114 | |
115 int currentY = spectrogram[specIndex][block]; | |
116 int prevBlock = block-1; | |
117 int previousY = prevBlock >= 0 ? spectrogram[specIndex][prevBlock] : 0; | |
118 | |
119 if(currentY > previousY){ | |
120 m_bandSum[band][block] += (currentY - previousY); | |
121 } | |
122 | |
123 //cout << specIndex << endl; | |
124 specIndex++; | |
125 } | |
126 } | |
127 | |
128 float total = 0; | |
129 for(int band = 0; band < m_numberOfBands; band++){ | |
130 total += m_bandSum[band][block]; | |
131 } | |
132 float average = total/m_numberOfBands; | |
133 data[block] = average; | |
134 } | |
135 | |
136 subtractLocalAverage(&data[0]); | |
137 | |
138 return data; | |
139 } |