Skip to content

Commit bd7a29a

Browse files
Create mfcc.cpp
1 parent 18493f2 commit bd7a29a

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

inference-app/src/mfcc.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "mfcc.h"
2+
3+
MFCC::MFCC(int num_mfcc_coeffs, int frame_size, int num_fft_points) :
4+
_num_mfcc_coeffs(num_mfcc_coeffs),
5+
_frame_size(frame_size),
6+
_num_fft_points(num_fft_points),
7+
_hanning_window(NULL),
8+
_mel_filterbank(NULL)
9+
{
10+
}
11+
12+
MFCC::~MFCC()
13+
{
14+
if (_hanning_window != NULL) {
15+
delete [] _hanning_window;
16+
_hanning_window = NULL;
17+
}
18+
if (_mel_filterbank != NULL) {
19+
delete [] _mel_filterbank;
20+
_mel_filterbank = NULL;
21+
}
22+
}
23+
24+
int MFCC::init()
25+
{
26+
// Initialize the hanning window and Mel filterbank, similar to DSPPipeline::init
27+
28+
return 1;
29+
}
30+
31+
void MFCC::extract_mfcc(const int16_t* input, float32_t* output)
32+
{
33+
int16_t windowed_input[_frame_size];
34+
int16_t fft_q15[_frame_size * 2];
35+
36+
// Apply the MFCC pipeline: Hanning Window + FFT
37+
arm_mult_q15(_hanning_window, input, windowed_input, _frame_size);
38+
arm_rfft_q15(&_S_q15, windowed_input, fft_q15);
39+
40+
// Calculate the magnitude spectrum (similar to DSPPipeline::calculate_spectrum)
41+
// Compute the power spectrum
42+
arm_cmplx_mag_q15(fft_q15, fft_mag_q15, _frame_size / 2 + 1);
43+
44+
// Apply Mel filterbank to the power spectrum (specific to MFCC)
45+
float32_t mel_energies[_num_mfcc_coeffs];
46+
apply_mel_filterbank(fft_mag_q15, mel_energies);
47+
48+
// Compute the logarithm of the mel energies
49+
for (int i = 0; i < _num_mfcc_coeffs; i++) {
50+
mel_energies[i] = logf(mel_energies[i]);
51+
}
52+
53+
// Apply DCT (Discrete Cosine Transform) to obtain MFCC coefficients
54+
compute_mfcc(output, mel_energies);
55+
}
56+
57+
void MFCC::apply_mel_filterbank(const int16_t* spectrum, float32_t* mel_energies)
58+
{
59+
// Define the filter bank parameters
60+
int num_filter_banks = 13;
61+
int filter_bank_size = _frame_size / 2 + 1; // Half of the FFT size
62+
63+
// Initialize the mel filterbank
64+
if (_mel_filterbank == NULL) {
65+
_mel_filterbank = new float32_t[num_filter_banks * filter_bank_size];
66+
67+
// Initialize the mel filterbank with appropriate filter shapes
68+
// You can use equations like Triangular, Hanning, or other shapes for filters
69+
// Fill _mel_filterbank with filter coefficients based on filter bank parameters
70+
// Ensure that the coefficients sum to 1 for each filter
71+
// This step is essential and depends on your specific filterbank design.
72+
}
73+
74+
// Apply the mel filter bank to the spectrum
75+
for (int i = 0; i < num_filter_banks; i++) {
76+
mel_energies[i] = 0.0;
77+
for (int j = 0; j < filter_bank_size; j++) {
78+
mel_energies[i] += _mel_filterbank[i * filter_bank_size + j] * spectrum[j];
79+
}
80+
}
81+
}
82+
83+
void MFCC::compute_mfcc(float32_t* mfcc_output, const float32_t* mel_energies)
84+
{
85+
// Define the number of MFCC coefficients
86+
int num_mfcc_coeffs = 9;
87+
88+
// Initialize the DCT matrix (you can precompute it)
89+
// It's a matrix of size num_mfcc_coeffs x 13 (number of filter banks)
90+
// You can find precomputed DCT matrices in DSP libraries or compute it manually
91+
92+
// Compute the DCT of the mel energies to obtain MFCC coefficients
93+
for (int i = 0; i < num_mfcc_coeffs; i++) {
94+
mfcc_output[i] = 0.0;
95+
for (int j = 0; j < 13; j++) {
96+
mfcc_output[i] += mel_energies[j] * dct_matrix[i * 13 + j];
97+
}
98+
}
99+
}
100+

0 commit comments

Comments
 (0)