#java #arrays #audio #byte #surround
#java #массивы #Аудио #байт #объемный
Вопрос:
Насколько я понимаю, используемый мной массив байтов аудио (PCM Stereo 16bit) составляет 4 байта на сэмпл. Я заметил, что при инвертировании значения байта (т. Е. От -128 до 128 и от 128 до -128) звук не переводится в канал объемного звучания. Звучит так же (фронтальный звук). Я экспериментировал с инвертированием каждого второго байта (каждые 2 байта), а не всех байтов, и получил что-то вроде объемного звука, но он очень грязный и прерывистый. Как именно мне обработать обычный 16-битный стереофонический WAV-файл PCM (в виде массива байтов), чтобы звук размещался в каналах объемного звучания?
Мой код:
public byte[] putInSurround(byte[] audio) {
for (int i = 0; i < audio.length; i = 4) {
int i0 = audio[i 0];
int i1 = audio[i 1];
int i2 = audio[i 2];
int i3 = audio[i 3];
if (0 > audio[i 0]) {
i0 = Math.abs(audio[i 0]);
}
if (0 < audio[i 0]) {
i0 = 0 - audio[i 0];
}
if (0 > audio[i 1]) {
i1 = Math.abs(audio[i 1]);
}
if (0 < audio[i 1]) {
i1 = 0 - audio[i 1];
}
if (0 > audio[i 2]) {
i2 = Math.abs(audio[i 2]);
}
if (0 < audio[i 2]) {
i2 = 0 - audio[i 2];
}
if (0 > audio[i 3]) {
i3 = Math.abs(audio[i 3]);
}
if (0 < audio[i 3]) {
i3 = 0 - audio[i 3];
}
audio[i 0] = (byte) i0;
//audio[i 1] = (byte) i1; <-- Commented Out For Every Other Byte.
//audio[i 2] = (byte) i2; <-- Commented Out For Every Other Byte.
audio[i 3] = (byte) i3;
}
return audio;
}
Ответ №1:
Я никоим образом не являюсь экспертом в DSP, но у меня есть несколько наблюдений, которые могут оказаться полезными:
-
Вы анализируете свой массив с шагом в 4 байта, что корректно соответствует одному 16-битному образцу стереозвука:
2 channels * 16 bits = 32 bits = 4 bytes
.Возможно, я не понимаю, что вы пытаетесь сделать, но в современном объемном звуке каналы объемного звучания обычно независимы друг от друга. Это означает, что вам потребуется более 4 байт на сэмпл объемного звучания. Если, например, у вас 5 каналов, вам потребуется 10 байт на выборку, что, вероятно, означает, что вам нужны отдельные входные и выходные массивы в вашем коде.
Существуют такие методы, как Dolby Surround и Dolby Pro Logic, где каналы объемного звучания кодируются матрицей в два стереоканала, но используемая математика DSP намного сложнее, чем та, что есть в вашем коде. Не говоря уже о необходимости специального декодера и потере качества, подразумеваемой такими методами.
-
Инвертировать каждый байт 2-байтовой выборки не имеет смысла: значение выборки, равное 1000d, станет -744d. Подобные побитовые операции редко используются в DSP, если вообще используются.
-
Обычно звуковые сэмплы хранятся в виде двоичных чисел, дополненных знаком 2. Это делает обработку их по байтам довольно сложной, особенно на языке без беззнаковых чисел и без приведения указателей, таком как Java. Вам было бы лучше преобразовать массив байтов в массив
short
илиint
— или использовать другой язык программирования, такой как C . -
При инвертировании -128 получается 128, который не может быть сохранен в байте со знаком, как это используется Java.
-
При «инвертировании каждого другого байта» вы сохраняете значение, обратное
i 0
иi 3
, вместоi 0
иi 2
илиi 1
иi 3
. -
Результат инвертирования каждого другого байта, хотя по-прежнему не имеет никакого смысла, имеет различный эффект, в зависимости от того, является ли ваше звуковое представление строчным или строчным. В файлах RIFF WAV используется порядок байтов с малым концом.
Инвертирование байтов 0 и 2 изменяет LSB сэмплов, что просто добавило бы шум высокой амплитуды и явные искажения, когда динамический диапазон аудиоклипа ограничен.
Инвертирование байтов 1 и 3 приблизило бы инвертирование всего сэмпла с высокими амплитудами и добавило бы много искажений в клипах с ограниченным динамическим диапазоном.
-
Инвертирование всей выборки, а не отдельных байтов, является приближением сдвига фазы на 180 градусов. Однако я не уверен, где вы можете это использовать…
Вам нужно сообщить нам, что именно вы пытаетесь сделать, если вам нужна дополнительная помощь, кроме этой. Вы должны хотя бы указать, каков ваш ожидаемый результат и какие алгоритмы DSP вы используете.
Комментарии:
1. Если у вас есть копия NetBeans, у меня есть код программы, на которую я ссылаюсь. sourceforge.net/projects/loopmaker/files/Development/… В Editor.java процедура объемного звучания вызывается в строках 847 и 1205, а сама процедура находится в строке 1309. Я пишу аудиопрограмму с циклическим воспроизведением, и она должна иметь возможность размещать сигнал wav, ориентированный на передние динамики, на задние динамики. Начиная с 4 байт / сэмпл, это может быть (подобная сигналу) проблема 3D вместо (подобной каналу) проблемы 8 байт / сэмпл.