Преобразование данных PDM в PCM или другой формат аудиоданных - PullRequest
0 голосов
/ 03 июля 2019

Я работаю над встроенной системой (NUCLEO-L476RG) с микрофоном MEMS с pdm (модуляцией плотности импульсов). Имейте в виду, что я не очень знаком с обработкой звука. В настоящее время программа может преобразовывать значения pdm в частотную область посредством быстрого преобразования Фурье. Однако мне нужны данные во временной области или преобразовать их в PCM. В основном аудио данные, которые позволили бы мне создавать файлы WAV. Поэтому я попытался захватить данные pdm сам по себе, но каким-то образом, когда я их распечатываю, я получаю кратные 125. то есть 0 -1024 -1792 -256 -256 -1024 -1280 -768 -768 -1536 -256

Что представляют собой эти значения? Разве значения pdm не должны быть единичными? Какие драйверы / промежуточное ПО мне понадобится для преобразования pdm в pcm, если это вообще возможно? Для справки я использую arm_math.h из библиотеки CMSIS DSP, если это актуально. Это, вероятно, недостаточно информации, поэтому не стесняйтесь задавать мне вопросы о вещах, которые я пропустил, спасибо.

Я не пробовал слишком много вещей, так как это не моя кодовая база, поэтому я не до конца понимаю это с самого начала.

  // I think pdm data comes from this function
  // and stored in 'Buff'
   HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, Buff, 
                                    FFT_SampleNum)
.
.
.
.
.


  // This is where pdm values are plugged into fast fourier transform
  // input data
  for (uint32_t i = 0; i < FFT_SampleNum; i++)
    FFT_inp[i] = (float) FFT_inp_int32[i];

  // Windowing
    arm_mult_f32(FFT_inp, FFT_window, FFT_inp, FFT_SampleNum);

  // Execute FFT
        arm_rfft_fast_f32(&S, FFT_inp, FFT_oup, 0);

  // calculate magnitude
        arm_cmplx_mag_f32(FFT_oup, FFT_mag, FFT_SampleNum / 2);

  // Normalization (Unitary transformation) of magnitude
        arm_scale_f32(FFT_mag, 1.0f / sqrtf((float) FFT_SampleNum), 
                      FFT_mag, FFT_SampleNum / 2);


  // AC coupling
  for (uint32_t i = 0; i < FFT_SampleNum / 2; i++)
  {
    if (*(FFT_frq + i) < FFT_AC_COUPLING_HZ)
        FFT_mag[i] = 1.0f;
    else
        break;
  }

Вот базовый код: https://github.com/y2kblog/NUCLEO-L476RG_DFSDM_PDM-Mic

...