Неправильное воспроизведение Java с 24-битным звуком

Я использую javax sound API для реализации простой программы воспроизведения в консолях на основе http://www.jsresources.org/examples/AudioPlayer.html.

Протестировав его, используя 24-битный файл рампы (каждый образец является последним образцом плюс 1 по всему 24-битовому диапазону), очевидно, что во время воспроизведения происходит что-то странное. Записанный вывод не является содержимым файла (у меня есть цифровая петля, чтобы проверить это).

Кажется, что некорректно интерпретирует образцы, что приводит к тому, что левый канал выглядит так, будто он имеет некоторое усиление, применяемое к нему, и правый канал выглядит так, будто он ослабляется.

Я изучил, нужны ли элементы управления PAN и BALANCE, но они недоступны, и я проверил настройки системы звука Windows XP. Любая другая форма воспроизведения этого файла рампы в порядке.

Если я делаю тот же тест с 16-битным файлом, он корректно работает без повреждения потока.

Знает ли кто-нибудь, почему Java Sound API меняет мой аудиопоток?

2
задан Cycling Engineer 11 июня '10 в 19:50
источник поделиться

1 ответ

Проблема с воспроизведением Java 24-битного звука на самом деле связана с реализацией Microsoft DirectSound и/или Windows Java Sound. Используя Linux с Java Sound и ALSA, 24-битный звук отлично воспроизводится (запись на выходе показывает идеальное совпадение с входным файлом).

Чтобы узнать, почему он не работает в Windows, вы можете запросить поддерживаемые аудиоформаты выходной строки, которую вы хотите воспроизвести в Java, используя (где lineInfo - это Line.Info выходной строки):

DataLine.Info dataLineInfo = (DataLine.Info) lineInfo;

а затем перейдя через поддерживаемые форматы:

for (AudioFormat lineFormat : dataLineInfo.getFormats())

Для Windows я получаю что-то вроде:

Format #1: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #2: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #3: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
Format #4: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
Format #5: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #6: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #7: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
Format #8: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian

Что не поддерживает 24 бит в качестве поддерживаемого формата. Но в Windows XP он все еще позволяет мне воспроизводить 24-битный звук, но предположительно обработан до 16 бит Java/DirectSound, а затем обратно до 24 бит на звуковую карту. Следовательно, почему вывод данных неверен. В Windows 7 я обнаружил, что он просто отказался воспроизводить 24-битное аудио (вероятно, более разумным, если все, что он собирается сделать, это до 16 бит).

Для Linux (Fedora 17) я получаю что-то вроде (с той же самой звуковой картой, ESI Juli @, на том же ПК):

Format #1: PCM_SIGNED unknown sample rate, 32 bit, mono, 4 bytes/frame, little-endian
Format #2: PCM_SIGNED unknown sample rate, 32 bit, mono, 4 bytes/frame, big-endian
Format #3: PCM_SIGNED unknown sample rate, 32 bit, stereo, 8 bytes/frame, little-endian
Format #4: PCM_SIGNED unknown sample rate, 32 bit, stereo, 8 bytes/frame, big-endian
Format #5: PCM_SIGNED unknown sample rate, 24 bit, mono, 4 bytes/frame, little-endian
Format #6: PCM_SIGNED unknown sample rate, 24 bit, mono, 4 bytes/frame, big-endian
Format #7: PCM_SIGNED unknown sample rate, 24 bit, stereo, 8 bytes/frame, little-endian
Format #8: PCM_SIGNED unknown sample rate, 24 bit, stereo, 8 bytes/frame, big-endian
Format #9: PCM_SIGNED unknown sample rate, 24 bit, mono, 3 bytes/frame, little-endian
Format #10: PCM_SIGNED unknown sample rate, 24 bit, mono, 3 bytes/frame, big-endian
Format #11: PCM_SIGNED unknown sample rate, 24 bit, stereo, 6 bytes/frame, little-endian
Format #12: PCM_SIGNED unknown sample rate, 24 bit, stereo, 6 bytes/frame, big-endian
Format #13: PCM_SIGNED unknown sample rate, 20 bit, mono, 3 bytes/frame, little-endian
Format #14: PCM_SIGNED unknown sample rate, 20 bit, mono, 3 bytes/frame, big-endian
Format #15: PCM_SIGNED unknown sample rate, 20 bit, stereo, 6 bytes/frame, little-endian
Format #16: PCM_SIGNED unknown sample rate, 20 bit, stereo, 6 bytes/frame, big-endian
Format #17: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
Format #18: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
Format #19: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
Format #20: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
Format #21: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #22: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #23: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #24: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame, 

У этого есть 24 бит в качестве поддерживаемого формата. И как таковое это работает так, как ожидалось, и без ненужной дополнительной обработки.

Таким образом, похоже, что 24-битное воспроизведение работает с Java Sound, при условии, что для ОС (и, возможно, для устройства, но я не нашел различий между устройствами, которые я пробовал до сих пор), реализация этого перечисляет его как поддерживаемый аудиоформат. Мои тесты показывают, что Linux (ALSA) действительно поддерживает его, тогда как Windows (DirectSound) этого не делает.

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

Следующим был мой первоначальный вопрос, на который я только что ответил (я оставил его для справки):


Я не уверен, что это правильная процедура для решения старых вопросов, но из чтения часто задаваемых вопросов это выглядит так, что это предпочтительнее для публикации нового. Я уже опубликовал эту проблему на нескольких других местах (включая форум Oracle Java Sound), но без ответов до сих пор, и этот вопрос звучит точно так же, как проблема, с которой я сталкиваюсь:

Я использую Java Sound для воспроизведения аудиофайлов (в стандартном формате PCM), но я заметил, что он неправильно воспроизводит 24-битные данные, поскольку данные, выводимые из звуковой карты, не соответствуют вводу из файла, Он отлично работает для 16-битных (и даже 8-битных) аудиоданных, но не для 24-битного (и предположительно 32-битного, но у меня нет реальных 32-битных аудиофайлов для тестирования). Из вывода видно, что Java Sound делает дополнительную (и нежелательную) обработку аудиоданных, прежде чем передавать их на звуковую карту. Я могу с уверенностью сказать, что это Java Sound делает это, потому что, если я запускаю один и тот же тест с помощью ASIO для воспроизведения файла, тогда нет проблем, и данные соответствуют ожидаемому.

Немного больше информации о настройке: - Последняя версия Java JRE (думаю, 7u7), работающая под Windows XP SP3. - Звук, воспроизводимый с использованием примера AudioPlayer (как упоминалось в главном вопросе) на jsresources.org(я сначала попытался использовать свой собственный код, но переключился на это, если бы я ошибся, результаты на обоих одинаковы). - Звук воспроизводится на звуковой карте M-Audio через цифровой (S/PDIF) выход, который напрямую подключается (через внешний кабель) к цифровому на звуковой карте Lynx (на том же ПК), где он находится (используя Sony Sound Forge). - Затем записанный файл сравнивается с входным Wave файлом.

Для теста используются четыре разных входных файла Wave (сгенерированные из одного и того же исходного файла): - 16 бит, 44,1 кГц; - 16 бит, 48 кГц; - 24 бит, 44,1 кГц; - 24 бит, 48 кГц.

Используя ASIO для воспроизведения тестовых файлов, все четыре файла произвели правильный вывод (записанные данные соответствуют байту данных байта данных для байта после выравнивания начальных позиций для времени между нажатием на запись и нажатием на воспроизведение).

Используя Java для воспроизведения тестовых файлов, 16-разрядные (как 44,1 кГц, так и 48 кГц) выдают правильный вывод, тогда как 24-разрядные (как 44,1 кГц, так и 48 кГц) не работают. Не только это, но и то, как вывод неправильный, является несогласованным (если я запускаю тест два раза, он каждый раз производит разные выходные данные, ни один из которых не приближается к соответствующему входному файлу). Таким образом, не только звук Java воспроизводит 24-битные файлы ошибочно, он делает это неправильно по-разному каждый раз. Если это поможет, я могу сделать скриншоты звукового выхода Java по сравнению с входным файлом (ожидаемый вывод).

Самый простой способ воспроизвести это - использовать упомянутый выше пример AudioPlayer, воспроизвести 24-битный файл и записать вывод (если у вас есть только одна звуковая карта, возможно, можно использовать его микшер для правильной маршрутизации данных, чтобы разрешить он должен быть захвачен). Хотя это не так уж и плохо, что я могу слышать любую разницу, это отчасти поражает цель аудио высокого разрешения, если данные изменяются неожиданным образом (вы рискуете потерять прибыль от использования 24 бит на 16 бит, хотя я на самом деле не хочу вникать в этот аргумент здесь).

Итак, чтобы выразить это как вопрос - как я могу заставить Java Sound правильно воспроизводить 24-битное аудио?

3
ответ дан alexdw 27 сент. '12 в 17:46
источник поделиться

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