Я пытаюсь скопировать файл .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);
}
Когда я это делаю, я получаю файл с такими значениями (правая часть этого снимка экрана) Выходной файл
Как я могу получить правильные значения, как мы видим их в левой части моего скриншота?
С уважением
Пожалуйста, напишите цифры текстом. Не добавляйте фотографии, когда в этом нет необходимости.
О да, я меняю это так: for(int i = 0; i < sizeof(Buffer); i++)
В стороне: буфер данных содержит bytesRead
байт. sizeof(Buffer)
— это максимальное количество байтов, которое может быть прочитано, а количество фактически прочитанных байтов равно bytesRead
.
Желаемый результат - с плавающей запятой, но вы читаете/записываете целые числа.
Судя по значениям, ваши образцы выглядят так, будто они закодированы в 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 цифры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);
}
Получение файла, полного "%.4f", а не данных... Попробую посмотреть значение в режиме отладки
Кажется, больше с «значением», определенным как «двойное»: D
f_printf не поддерживает плавающую запятую :( Но значение хорошее
@Antoine Обновлено, чтобы добавить обходной путь %.4f
.
Вот и все ! Большое спасибо
Кстати,
for(int i = 0; i <= sizeof(Buffer); i++)
выглядит как ошибка на единицу.