Преобразование байтового массива PCM в каналы объемного звучания

Насколько я понимаю, массив байтов звука, который я использую (PCM Stereo 16bit), составляет 4 байта на образец. Я заметил, что когда вы инвертируете значение Byte (например, -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;
    }

person user698816    schedule 08.04.2011    source источник


Ответы (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, если вообще используются.

  • Обычно аудиосэмплы хранятся как двоичные числа с дополнением до двух со знаком. Это делает их побайтовую обработку довольно сложной, особенно в языке без беззнаковых чисел и без приведения указателей, например в Java. Лучше преобразовать массив байтов в массив short или int - или использовать другой язык программирования, например C ++.

  • Инвертирование -128 дает +128, который не может быть сохранен в подписанном байте, используемом Java.

  • При «инвертировании байтов друг друга» вы сохраняете инверсию i + 0 и i + 3 вместо i + 0 и i + 2 или i + 1 и i + 3.

  • Результат инвертирования байтов друг друга, хотя и не имеет никакого смысла, имеет различный эффект, в зависимости от того, является ли ваше аудиопрезентация прямой или прямой порядок байтов. WAV-файлы RIFF используют порядок байтов с прямым порядком байтов.

    Инвертирование байтов 0 и 2 изменяет младший бит сэмплов, что просто добавит шума с высокими амплитудами и явного искажения, когда динамический диапазон аудиоклипа ограничен.

    Инвертирование байтов 1 и 3 приблизит инвертирование всего семпла с высокими амплитудами и добавит много искажений в клипах с ограниченным динамическим диапазоном.

  • Инвертирование всего образца, а не отдельных байтов, является приближением фазового сдвига на 180 градусов. Я не уверен, где это можно использовать ...

Вы должны сообщить нам, что именно вы пытаетесь сделать, если вам нужна дополнительная помощь, чем эта. Вы должны хотя бы упомянуть, каков ваш ожидаемый результат и какие алгоритмы DSP вы используете.

person thkala    schedule 09.04.2011
comment
Если у вас есть копия NetBeans, у меня есть код программы, о которой я говорю. sourceforge.net/projects/loopmaker/files/Development/ В Editor.java процедура объемного звучания вызывается в строках 847 и 1205, а сама процедура - на 1309. Это циклическая аудиопрограмма, которую я пишу, и она должна иметь возможность размещать волну ориентации переднего динамика. к тыловым динамикам. Поскольку 4 байта / образец, это может быть (как сигнал) проблема 3D вместо (как канал) проблема 8 байтов / образец. - person user698816; 10.04.2011