У меня есть 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)
3 байта данных из wav 24 бита. labbookpages.co.uk/audio/javaWavFiles.html эти 3 байта в little-endian.. в дескрипторе есть RIFF
Укажите эту информацию в вопросе
Мне эта ссылка не совсем понятна. Я не понимаю, откуда берутся диапазоны, они не совпадают с моим пониманием того, что подразумевает арифметика 24-битного дополнения до двух.
Ссылка, которую вы предоставляете, кажется мне неправильной. Конечно, 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 байта после манипуляции с поплавком?
Проделайте обратные операции
функция MyToByteL(fl:extended):longint; var ret1 : длинный интервал; var retval2 : расширенный; начало ret1 := 0; рет1 := 0; ретвал2 := фл; retval2 := раунд(retval2 * 8388608); ret1 := раунд (retval2); ret1 := (ret1 и $7ffffff) -(ret1 и $800000); результат := ret1; конец; это не работает
Нет, преобразование между 32-битным дополнением до двух и 24-битным дополнением до двух неверно. Мы не можем сделать это в комментариях. Должен быть новый вопрос. Я действительно думаю, что ответил на этот вопрос, и что вы в состоянии принять ответ.
Я не могу открыть еще один вопрос. Как я могу сделать?
Вероятно, вам придется подождать, чтобы спросить еще раз. Что вам говорит ТАК? Это будет что-то вроде или с $ 800000, если значение отрицательное, а затем этот Move с перевернутыми аргументами.
можешь сделать скрин?
с итерацией это слишком долго, вы можете мне помочь?
Вам просто нужно сдвинуть бит знака вниз, вот так: if Value and $80000000 <> 0 then Value := Value or $00800000; Move(Value, Bytes, 3);
Это не стандартный формат. Вам нужно знать, как кодируется значение с плавающей запятой. Только вы можете определить это.