Конвертировать массив байтов PCM в каналы объемного звучания
Как я понимаю, используемый мной массив байтов аудио (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 вы используете.