Загрузка данных


// Временные буферы для работы фильтра (размер зависит от вашего 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;
    }
}