// Временные буферы для работы фильтра (размер зависит от вашего src_frames)
#define MAX_SRC_FRAMES 160
static float32_t src_float_L[MAX_SRC_FRAMES];
static float32_t src_float_R[MAX_SRC_FRAMES];
static float32_t dst_float_L[MAX_SRC_FRAMES * 4];
static float32_t dst_float_R[MAX_SRC_FRAMES * 4];
void audio_upsample_cmsis(const int16_t *src, int32_t *dst, uint8_t src_channels, uint32_t src_framerate)
{
uint32_t src_frames = (src_framerate / 10);
uint32_t factor = 32000 / src_framerate;
// 1. Разделяем каналы и переводим во float (-1.0 ... 1.0)
if (src_channels == 2) {
for (uint32_t f = 0; f < src_frames; f++) {
src_float_L[f] = (float32_t)src[f * 2] / 32768.0f;
src_float_R[f] = (float32_t)src[f * 2 + 1] / 32768.0f;
}
} else {
for (uint32_t f = 0; f < src_frames; f++) {
float32_t mono = (float32_t)src[f] / 32768.0f;
src_float_L[f] = mono;
src_float_R[f] = mono;
}
}
// 2. Аппаратная интерполяция и фильтрация
arm_fir_interpolate_f32(&fir_L, src_float_L, dst_float_L, src_frames);
arm_fir_interpolate_f32(&fir_R, src_float_R, dst_float_R, src_frames);
// 3. Интерливинг обратно в dst буфер с переводом в int32_t (сдвиг << 16)
uint32_t dst_frames = src_frames * factor;
uint32_t dst_idx = 0;
for (uint32_t f = 0; f < dst_frames; f++) {
// Ограничиваем (clip) значения во избежание искажений
float32_t sample_l = dst_float_L[f] * 32768.0f;
float32_t sample_r = dst_float_R[f] * 32768.0f;
if (sample_l > 32767.0f) sample_l = 32767.0f;
if (sample_l < -32768.0f) sample_l = -32768.0f;
if (sample_r > 32767.0f) sample_r = 32767.0f;
if (sample_r < -32768.0f) sample_r = -32768.0f;
dst[dst_idx] = ((int32_t)sample_l) << 16;
dst[dst_idx + 1] = ((int32_t)sample_r) << 16;
dst_idx += 2;
}
}