c - C / STM32 - 从 .wav 文件读取和复制数据
问题描述
我正在尝试从我的闪存中复制一个 .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);
}
当我这样做时,我得到一个包含类似值的文件(此屏幕截图的右侧部分) 输出文件
我怎样才能获得正确的值,因为我们可以在屏幕截图的左侧看到它们?
问候
解决方案
根据这些值,您的样本看起来像是以带符号的 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
,则可以通过以下方式进行四舍五入打印:
- 乘
10000
因为小数点后有4位 - 乘以 2 并根据值的符号加或减
0x8000
(用于除法的值) - 被除以
0x8000 * 2
- 打印小数点前后的值
// 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);
}
推荐阅读
- c# - Resharper - 更喜欢带有支持字段的代码样式
- javascript - 如何从多行和多列的表格中获取选定的复选框并作为回复发送
- android - 如何测试 androidx.fragment.app.Fragment.onCreateOptionsMenu()?
- sql - 在 mongodb 上进行 sql 查询以根据单列的 id 值获取多列的计数
- tensorflow - CNN - 在 1 张图片中显示的两个类别之间进行选择
- excel - 在代码问题中使用 Union 将工作表与源工作表分开
- python - 如何将元组值添加到值也是 nd.array 的字典的每个键中?
- java - 当它从java中的内部“for”循环“中断”时它会“更新”吗?
- for-loop - for-range 结构与 Go 中的闭包有何关系?
- html - 在 Bootstrap 4.1 container-fluid > row > col 中间垂直对齐 div