簡體   English   中英

C / STM32 - 從.wav 文件讀取和復制數據

[英]C / STM32 - Read and copy a data from .wav file

我正在嘗試從我的 flash RAM memory 復制 a.wav 文件。

#define AUDIO_BUFFER_SIZE          (1024 * 8)       /* Size (in bytes) of the buffer containing the PCM samples */

uint8_t                  Buffer[AUDIO_BUFFER_SIZE];    // Buffer containig the PCM samples to play

...

      /* Fill in the buffer with new data */
  if (f_read(&File, (uint8_t   *)Buffer, AUDIO_BUFFER_SIZE, &bytesRead) != FR_OK)
  {
    Error_Handler();
  }

  if (counter==1){
      HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
      //uint8_t string[20]="Hello, world!";
      //f_write(&OutFile, Buffer, (UINT)sizeof(Buffer),&bytesRead);
      for(int i = 0; i <= sizeof(Buffer); i++){
          f_printf(&OutFile, "%d\n",Buffer[i]);
          osDelay(10);
      }
      counter++;
  }
  else{
      HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET);
      f_close(&OutFile);
  }

當我這樣做時,我得到一個包含類似值的文件(此屏幕截圖的右側部分) Output 文件

我怎樣才能獲得正確的值,因為我們可以在屏幕截圖的左側看到它們?

問候

根據這些值,您的樣本看起來像是以帶符號的 16 位小端格式編碼的。

要解碼格式,您可以這樣做(假設f_printf的格式說明符就像標准的printf ):

// 2 bytes per sample, also use < instead of <=
for(int i = 0; i < sizeof(Buffer); i += 2){
    int value = Buffer[i] | (Buffer[i + 1] << 8); // merge the 2 bytes into one integer
    if (value >= 0x8000) value -= 0x10000; // because the samples are signed
    f_printf(&OutFile, "%.4f\n", value / (double)0x8000); // divide with the maximum value
    osDelay(10);
}

如果您無法通過f_printf打印浮點數,則可以通過以下方式進行四舍五入打印:

  1. 乘以10000 ,因為小數點后有 4 位
  2. 乘以 2 並根據值的符號加或減0x8000 (用於除法的值)
  3. 除以0x8000 * 2
  4. 打印小數點前后的值
// 2 bytes per sample, also use < instead of <=
for(int i = 0; i < sizeof(Buffer); i += 2){
    int v;
    int value = Buffer[i] | (Buffer[i + 1] << 8); // merge the 2 bytes into one integer
    if (value >= 0x8000) value -= 0x10000; // because the samples are signed
    // divide with the maximum value
    v = ((value * 10000) * 2 + (value >= 0 ? 0x8000 : -0x8000)) / (0x8000 * 2);
    f_printf(&OutFile, "%s%d.%04d\n",
      v < 0 && v / 10000 == 0 ? "-" : "", // sign (because typical integers don't have -0)
      v / 10000, // value before the decimal point
      (v < 0 ? -v : v) % 10000); // value after the decimal point
    osDelay(10);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM