Krotos Modules 3
Loading...
Searching...
No Matches
MelFrequencySpectrum.cpp
Go to the documentation of this file.
1//=====================================================================================
7//=====================================================================================
8
10
11//=====================================================================================
23
24//=====================================================================================
25float krotos::MelFrequencySpectrum::m_hertzToMel(float f) { return 1127 * log(1 + (f / 700.f)); }
26
27//=====================================================================================
28float krotos::MelFrequencySpectrum::m_melToHertz(float m) { return 700.f * (exp(m / 1127.f) - 1.f); }
29
30//=====================================================================================
31void krotos::MelFrequencySpectrum::setParameters(int audioFrameSize, int numCoeffs)
32{
33 m_fftSize = audioFrameSize;
34 m_magnitudeSpectrumSize = (audioFrameSize / 2) + 1;
35 m_numCoefficients = numCoeffs;
36
37 buildMelFilterbank();
38}
39
40//=====================================================================================
42{
43 m_samplingFrequency = fs;
44
45 buildMelFilterbank();
46}
47
48//=====================================================================================
49std::vector<float> krotos::MelFrequencySpectrum::calculateMelSpectrum(std::vector<float> magnitudeSpectrum)
50{
51 // !
52 // We are expecting to receive a magnitude spectrum with a size that is
53 // (N / 2) + 1, where N is the audioFrameSize that you initialised the
54 // Mel-spectrum object with. This isn't the case and so it is being
55 // initialised wrongly.
56 assert(magnitudeSpectrum.size() == m_magnitudeSpectrumSize);
57
58 std::vector<float> melSpectrum;
59
60 for (int m = 0; m < m_numCoefficients; m++)
61 {
62 float melValue = 0;
63
64 for (int k = 0; k < magnitudeSpectrum.size(); k++)
65 {
66 melValue += (magnitudeSpectrum[k] * magnitudeSpectrum[k]) * m_melFilterBank[m][k];
67 }
68
69 melSpectrum.push_back(melValue);
70 }
71
72 return melSpectrum;
73}
74
75//=====================================================================================
77{
78 float lowFreq = 20;
79 float highFreq = ((float)m_samplingFrequency) / 2.f;
80
81 float lowMelFrequency = m_hertzToMel(lowFreq);
82 float highMelFrequency = m_hertzToMel(highFreq);
83
84 m_melFilterBank.resize(m_magnitudeSpectrumSize);
85
86 for (int i = 0; i < m_numCoefficients; i++)
87 {
88 m_melFilterBank[i].resize(m_magnitudeSpectrumSize);
89 // std::fill(m_melFilterBank[i].begin(), m_melFilterBank[i].end(), 0);
90 for (auto& mel : m_melFilterBank)
91 {
92 if (mel.size() > 0)
93 {
94 FloatVectorOperations::fill(&mel[0], 0.f, mel.size());
95 }
96 }
97 }
98
99 std::vector<float> melPoints;
100
101 float melRange = highMelFrequency - lowMelFrequency;
102
103 float stepSize = melRange / ((float)m_numCoefficients + 1);
104
105 melPoints.push_back(lowMelFrequency);
106 for (int i = 0; i < m_numCoefficients; i++)
107 {
108 melPoints.push_back(lowMelFrequency + ((i + 1) * stepSize));
109 }
110 melPoints.push_back(highMelFrequency);
111
112 std::vector<int> melFilterBins;
113
114 for (int i = 0; i < melPoints.size(); i++)
115 {
116 float h = m_melToHertz(melPoints[i]);
117
118 int k = static_cast<int>(((float)m_fftSize) * (h / ((float)m_samplingFrequency)));
119
120 melFilterBins.push_back(k);
121 }
122
123 for (int m = 0; m < m_numCoefficients; m++)
124 {
125 // !
126 // If you are getting this assertion failure, then you are trying to get
127 // too many separate Mel-frequency bins from a FFT magnitude spectrum that
128 // isn't large enough to give you the separation you need. Either increase
129 // your FFT size or set the number of Mel-frequency coefficients to a
130 // smaller number
131 assert(melFilterBins[m] < melFilterBins[m + 1]);
132
133 for (int k = 0; k < m_magnitudeSpectrumSize; k++)
134 {
135 if ((k >= melFilterBins[m]) && (k <= melFilterBins[m + 1]))
136 {
137 float t1 = (float)(k - melFilterBins[m]);
138 float t2 = (float)(melFilterBins[m + 1] - melFilterBins[m]);
139
140 m_melFilterBank[m][k] = t1 / t2;
141 }
142 else if ((k >= melFilterBins[m + 1]) && (k <= melFilterBins[m + 2]))
143 {
144 float t1 = (float)(melFilterBins[m + 2] - k);
145 float t2 = (float)(melFilterBins[m + 2] - melFilterBins[m + 1]);
146
147 m_melFilterBank[m][k] = t1 / t2;
148 }
149 else
150 {
151 m_melFilterBank[m][k] = 0.0;
152 }
153 }
154 }
155}
void buildMelFilterbank()
Definition MelFrequencySpectrum.cpp:76
void setParameters(int audioFrameSize, int numCoeffs)
Definition MelFrequencySpectrum.cpp:31
static float m_hertzToMel(float f)
Definition MelFrequencySpectrum.cpp:25
int m_numCoefficients
Definition MelFrequencySpectrum.h:38
MelFrequencySpectrum()
Definition MelFrequencySpectrum.cpp:12
int m_magnitudeSpectrumSize
Definition MelFrequencySpectrum.h:40
int m_samplingFrequency
Definition MelFrequencySpectrum.h:41
static float m_melToHertz(float m)
Definition MelFrequencySpectrum.cpp:28
void setSamplingFrequency(int fs)
Definition MelFrequencySpectrum.cpp:41
int m_fftSize
Definition MelFrequencySpectrum.h:39
std::vector< float > calculateMelSpectrum(std::vector< float > magnitudeSpectrum)
Definition MelFrequencySpectrum.cpp:49