forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmfcc_comp.h
More file actions
195 lines (163 loc) · 5.43 KB
/
mfcc_comp.h
File metadata and controls
195 lines (163 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2022 Intel Corporation. All rights reserved.
*
* Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
*/
#ifndef __SOF_AUDIO_MFCC_MFCC_COMP_H__
#define __SOF_AUDIO_MFCC_MFCC_COMP_H__
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/math/auditory.h>
#include <sof/math/dct.h>
#include <sof/math/fft.h>
#include <stddef.h>
#include <stdint.h>
/* __XCC__ is both for xt_xcc and xt_clang */
#if defined(__XCC__)
# include <xtensa/config/core-isa.h>
# if XCHAL_HAVE_HIFI4
# define MFCC_HIFI4
# elif XCHAL_HAVE_HIFI3
# define MFCC_HIFI3
# else
# define MFCC_GENERIC
# endif
#else
# define MFCC_GENERIC
#endif
#define MFCC_MAGIC 0x6d666363 /* ASCII for "mfcc" */
/* Set to 16 for lower RAM and MCPS with slightly lower quality. Set to 32 for best
* quality but higher MCPS and RAM. The MFCC input is currently 16 bits. With this option
* set to 32 the FFT and Mel filterbank are computed with better 32 bit precision. There
* is also need to enable 32 bit FFT from Kconfig if set.
*/
#define MFCC_FFT_BITS 16
/* MFCC with 16 bit FFT benefits from data normalize, for 32 bits there's no
* significant impact. The amount of left shifts for FFT input is limited to
* 10 that equals about 60 dB boost. The boost is compensated in Mel energy
* calculation.
*/
#if MFCC_FFT_BITS == 16
#define MFCC_NORMALIZE_FFT
#else
#undef MFCC_NORMALIZE_FFT
#endif
#define MFCC_NORMALIZE_MAX_SHIFT 10
struct audio_stream;
struct comp_dev;
/** \brief Type definition for processing function select return value. */
typedef void (*mfcc_func)(struct processing_module *mod,
struct input_stream_buffer *bsource,
struct output_stream_buffer *bsink,
int frames);
/** \brief MFCC processing functions map item. */
struct mfcc_func_map {
uint8_t source; /**< source frame format */
mfcc_func func; /**< processing function */
};
struct mfcc_buffer {
int16_t *addr;
int16_t *end_addr;
int16_t *r_ptr;
int16_t *w_ptr;
int s_avail; /**< samples count */
int s_free; /**< samples count */
int s_length; /**< length in samples for wrap */
};
struct mfcc_pre_emph {
int16_t coef;
int16_t delay;
int enable;
};
struct mfcc_fft {
#if MFCC_FFT_BITS == 16
struct icomplex16 *fft_buf; /**< fft_padded_size */
struct icomplex16 *fft_out; /**< fft_padded_size */
#elif MFCC_FFT_BITS == 32
struct icomplex32 *fft_buf; /**< fft_padded_size */
struct icomplex32 *fft_out; /**< fft_padded_size */
#else
#error "MFCC_FFT_BITS needs to be 16 or 32"
#endif
struct fft_plan *fft_plan;
int fft_fill_start_idx; /**< Set to 0 for pad left, etc. */
int fft_size;
int fft_padded_size;
int fft_hop_size;
int fft_buf_size;
int half_fft_size;
size_t fft_buffer_size; /**< bytes */
};
struct mfcc_cepstral_lifter {
struct mat_matrix_16b *matrix;
int16_t cepstral_lifter;
int num_ceps;
};
struct mfcc_state {
struct mfcc_buffer buf; /**< Circular buffer for input data */
struct mfcc_pre_emph emph; /**< Pre-emphasis filter */
struct mfcc_fft fft; /**< FFT related */
struct dct_plan_16 dct; /**< DCT related */
struct psy_mel_filterbank melfb; /**< Mel filter bank */
struct mfcc_cepstral_lifter lifter; /**< Cepstral lifter coefficients */
struct mat_matrix_16b *mel_spectra; /**< Pointer to scratch */
struct mat_matrix_16b *cepstral_coef; /**< Pointer to scratch */
int32_t *power_spectra; /**< Pointer to scratch */
int16_t buf_avail;
int16_t *buffers;
int16_t *prev_data; /**< prev_data_size */
int16_t *window; /**< fft_size */
int16_t *triangles;
int source_channel;
int buffer_size;
int prev_data_size;
int low_freq;
int high_freq;
int sample_rate;
int waiting_fill:1; /**< booleans */
int prev_samples_valid:1;
size_t sample_buffers_size; /**< bytes */
};
/* MFCC component private data */
struct mfcc_comp_data {
struct mfcc_state state;
struct comp_data_blob_handler *model_handler;
struct sof_mfcc_config *config;
int max_frames;
mfcc_func mfcc_func; /**< processing function */
};
static inline int mfcc_buffer_samples_without_wrap(struct mfcc_buffer *buffer, int16_t *ptr)
{
return buffer->end_addr - ptr;
}
static inline int16_t *mfcc_buffer_wrap(struct mfcc_buffer *buffer, int16_t *ptr)
{
if (ptr >= buffer->end_addr)
ptr -= buffer->s_length;
return ptr;
}
int mfcc_setup(struct processing_module *mod, int max_frames, int rate, int channels);
void mfcc_free_buffers(struct mfcc_comp_data *cd);
void mfcc_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource,
struct output_stream_buffer *bsink, int frames);
void mfcc_source_copy_s16(struct input_stream_buffer *bsource, struct mfcc_buffer *buf,
struct mfcc_pre_emph *emph, int frames, int source_channel);
void mfcc_fill_prev_samples(struct mfcc_buffer *buf, int16_t *prev_data,
int prev_data_length);
void mfcc_fill_fft_buffer(struct mfcc_state *state);
#ifdef MFCC_NORMALIZE_FFT
int mfcc_normalize_fft_buffer(struct mfcc_state *state);
#endif
void mfcc_apply_window(struct mfcc_state *state, int input_shift);
#if CONFIG_FORMAT_S16LE
int16_t *mfcc_sink_copy_zero_s16(const struct audio_stream *sink,
int16_t *w_ptr, int samples);
int16_t *mfcc_sink_copy_data_s16(const struct audio_stream *sink, int16_t *w_ptr,
int samples, int16_t *r_ptr);
void mfcc_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource,
struct output_stream_buffer *bsink, int frames);
#endif
#ifdef UNIT_TEST
void sys_comp_mfcc_init(void);
#endif
#endif /* __SOF_AUDIO_MFCC_MFCC_COMP_H__ */