Преобразование 32-битной формы волны в 16-битную форму волны

Я захватывал звук, используя режим захвата обратной петли. Захваченный сигнал представляет собой 32-битный сигнал. Я изо всех сил пытаюсь преобразовать это в 16-битную форму сигнала, чтобы кодировщики, такие как lame, могли с этим справиться (он говорит, что формат данных не поддерживается: 0x0003).

Я пробовал сдвигать биты (не моя сильная сторона) в самом волновом потоке с 32 бит на 16 бит, но результат все равно звучит искаженно.

Класс Wave32To16Stream в этом случае, похоже, не работает:

В идеале я хотел бы просто захватить прямо в 16 бит, нет ли способа установить битовую глубину захвата? Если нет, может ли кто-нибудь помочь мне с преобразованием волнового потока?

Пример захваченного сигнала можно найти здесь: http://dl.dropbox.com/u/454409/test.wav (10 МБ)

Я бы также согласился на какой-то способ кодирования этого в mp3 с помощью lame, я пробовал все перестановки параметров, которые только мог придумать, чтобы заставить его принимать волновой файл. Что интересно, Audacity (который использует lame_enc для кодирования mp3) смог создать mp3 из сигнала (но, возможно, Audacity автоматически преобразует его в 16-битный перед передачей в lame).


person hreinn1000    schedule 29.09.2010    source источник


Ответы (3)


Формат 0x0003 на самом деле является ieeeFloat, вы не должны получить это исключение. Лучше проверьте значение, которое он прочитал. Вы не можете преобразовать значения с побитовым сдвигом, вы должны преобразовать из числа с плавающей запятой в короткое. Простой бросок делает свою работу.

person Hans Passant    schedule 29.09.2010

Sox может преобразовать это для вас.

http://sox.sourceforge.net/

Подходящие командные строки:

http://sox.sourceforge.net/Docs/FAQ

sox любой файл -b 16 скорость исходящего файла -I 22050 дизеринг -s

Н.Б. И передискретизация, и дизеринг требуют некоторого запаса. Если SoX сообщает, что во время обработки произошло какое-либо отсечение, то преобразование следует повторить с некоторым затуханием, например.

sox any-file -b 16 outfile gain -1 rate 44100 dither -s

person strainer    schedule 29.09.2010
comment
В правильном преобразовании в 16 бит есть немного волшебства. Ошибка округления слышна при воспроизведении на громкости. У Sox есть довольно интеллектуальные нойз-шейперы, способные сделать ошибку округления неслышимой, спрятав ее в неслышимых местах. - person Andrew Rondeau; 25.10.2016

Если у вас 32-битный формат с плавающей запятой, то, скорее всего, выборочные значения находятся в диапазоне от -1 до 1. Чтобы преобразовать в 16-битный (целые числа), вам нужно будет умножить на 32767 и привести к INT16.

Если 32-битный диапазон с плавающей запятой больше, чем -1..1, вам необходимо найти минимальное и максимальное значения и вычислить коэффициент масштабирования, чтобы получить выборки в диапазоне INT16.

Возможно, вам придется добавить немного дизеринга.

person Han    schedule 29.09.2010