Как преобразовать 3 байта в порядке с прямым порядком байтов в число с плавающей запятой от -1 до +1

У меня есть 3 байта с прямым порядком байтов. это: Верхний, Средний и Нижний (от бита 23 до бита 0) Как я могу преобразовать их в число с плавающей запятой от -1 до +1?

3 байта имеют обратный порядок байтов, потому что в wav есть строка RIFF. поэтому минимальное значение равно (0x7FFFFF), а максимальное значение равно (0x800000)

http://www.labbookpages.co.uk/audio/javaWavFiles.html

для 16-битного wav: кадры волны находятся в дополнительном двоичном коде 2s между -32768; 0x8000 и 32767; 0x7FFF)

Это не стандартный формат. Вам нужно знать, как кодируется значение с плавающей запятой. Только вы можете определить это.

David Heffernan 22.05.2019 13:13

3 байта данных из wav 24 бита. labbookpages.co.uk/audio/javaWavFiles.html эти 3 байта в little-endian.. в дескрипторе есть RIFF

Andrea Verdi 22.05.2019 14:07

Укажите эту информацию в вопросе

David Heffernan 22.05.2019 14:22

Мне эта ссылка не совсем понятна. Я не понимаю, откуда берутся диапазоны, они не совпадают с моим пониманием того, что подразумевает арифметика 24-битного дополнения до двух.

David Heffernan 22.05.2019 15:17
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
4
389
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ссылка, которую вы предоставляете, кажется мне неправильной. Конечно, 24-битный формат использует стандартный арифметика с дополнением до двух. В этом случае 0x7FFFFF представляет -8388608, а 0x800000 представляет 8388607.

На этом основании вы используете эту функцию для преобразования ваших трех байтов в целочисленное значение со знаком:

function TwosComplement24(const Bytes): Integer;
begin
  Result := 0;
  Move(Bytes, Result, 3);
  Result := (Result and $7fffff) - (Result and $800000);
end;

Как только вы это сделаете, вы можете преобразовать значение с плавающей запятой следующим образом:

function Sample24toReal(const Bytes): Double;
begin
  Result := TwosComplement24(Bytes) / 8388608;
end;

Я использовал нетипизированный параметр для 3 байтов, но вы можете сделать это по-разному в зависимости от того, как вы читаете данные.

Кроме того, этот код написан в предположении, что он работает на машине с прямым порядком байтов. Если данные с прямым порядком байтов, а машина с обратным порядком байтов, вам нужно будет перевернуть каждую группу из трех байтов.

хорошо эти работы. а вернуть 3 байта после манипуляции с поплавком?

Andrea Verdi 23.05.2019 12:21

Проделайте обратные операции

David Heffernan 23.05.2019 12:40

функция MyToByteL(fl:extended):longint; var ret1 : длинный интервал; var retval2 : расширенный; начало ret1 := 0; рет1 := 0; ретвал2 := фл; retval2 := раунд(retval2 * 8388608); ret1 := раунд (retval2); ret1 := (ret1 и $7ffffff) -(ret1 и $800000); результат := ret1; конец; это не работает

Andrea Verdi 23.05.2019 15:09

Нет, преобразование между 32-битным дополнением до двух и 24-битным дополнением до двух неверно. Мы не можем сделать это в комментариях. Должен быть новый вопрос. Я действительно думаю, что ответил на этот вопрос, и что вы в состоянии принять ответ.

David Heffernan 23.05.2019 15:11

Я не могу открыть еще один вопрос. Как я могу сделать?

Andrea Verdi 23.05.2019 21:42

Вероятно, вам придется подождать, чтобы спросить еще раз. Что вам говорит ТАК? Это будет что-то вроде или с $ 800000, если значение отрицательное, а затем этот Move с перевернутыми аргументами.

David Heffernan 23.05.2019 21:52

можешь сделать скрин?

Andrea Verdi 23.05.2019 22:45

с итерацией это слишком долго, вы можете мне помочь?

Andrea Verdi 24.05.2019 10:03

Вам просто нужно сдвинуть бит знака вниз, вот так: if Value and $80000000 <> 0 then Value := Value or $00800000; Move(Value, Bytes, 3);

David Heffernan 24.05.2019 10:13

Другие вопросы по теме