Получилось у меня в итоге вот что:
#define PCM_OUT_SIZE 16
#define PDM_BUFF_SIZE 256
#define PWM_BUFF_SIZE 256
#define PCM_BUFF_SIZE 32
#define BIAS 512
void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s){
PDM_Filter(&((uint8_t*)(pdm_mic_data))[0], (uint16_t*)&(pcm_mic_data[0]), &PDM1_filter_handler);//получаем первые 16 отсчетов PCM
}
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s){
uint8_t sign;
uint8_t j = 0;
PDM_Filter(&((uint8_t*)(pdm_mic_data))[PDM_BUFF_SIZE/2], (uint16_t*)&(pcm_mic_data[PCM_BUFF_SIZE/2]), &PDM1_filter_handler);//вторые 16 отсчетов PCM
for (uint16_t i = buf_ptr * PCM_BUFF_SIZE; i < (buf_ptr * PCM_BUFF_SIZE) + PCM_BUFF_SIZE; i++){//преобразуем в 10-битный ШИМ сигнал
if (pcm_mic_data[j] > 0) sign = 1; else sign = 0;
PWM_buf[i] = ABS(pcm_mic_data[j]) >> 6;
if (sign) PWM_buf[i] = BIAS + PWM_buf[i]; else PWM_buf[i] = BIAS - PWM_buf[i];
j++;
}
if (++buf_ptr > 8) buf_ptr = 0; //размер кольцевого буфера ШИМ = 8 * 32 отсчетов PCM
if (buf_ptr == 4 && !PWM_buf_rdy){//При первом заполнении половины буфера ШИМ запускаем воспроизведение
PWM_buf_rdy = 1;
HAL_TIM_Base_Start_IT(&htim2);//таймер 2 с частотой дискретизации 16кГц подставляет новое значение в CCR1 TIM1 из буфера ШИМ
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}
}
Частота тактирования 1Мгц - проверено осциллографом. Но искажения остались... Увидел одну аморальность- первые два отсчета в pcm_mic_data всегда "битые". Резко выбиваются из остальных. Например при отсутствии сигнала на микрофоне заполнение буфера в районе "0". Но первые два значения могут быть 500 и -1000 например... Подозреваю, что искажения связаны именно с этими значениями...