Преобразование моно PCM в код uLaw в стерео - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть некоторый код на c #, который имеет две функции. Один преобразует линейные данные PCM в формат MuLaw. Другая функция преобразует его обратно.

открытый статический байт [] LinearToMulaw (байт [] байт, int bitsPerSample, int channel)

открытый статический байт [] MuLawToLinear (байт [] байт, int bitsPerSample, int channel)

В следующем объяснении я всегда использую 16 бит, два канала.

Когда этот код был опубликован, автор решил заставить функции конвертировать звук в моно. Мне нужно стерео. Если я заменю каждую функцию только возвратом входных байтов, у меня действительно будет необходимое стерео. Левый и правый канал.

Теперь я немного знаю, что нужно сделать. Вот код для конвертации из Linear PCM в MuLaw:

    public static Byte[] LinearToMulaw(Byte[] bytes, int bitsPerSample, int channels)
    {
      //  return bytes;

        int blockAlign =  channels * bitsPerSample / 8;

        Byte[] result = new Byte[bytes.Length  / blockAlign]; 
        int resultIndex = 0;
        for (int i = 0; i < result.Length ; i++)
        {
            switch (bitsPerSample)
            {
                case 8:
                    switch (channels)
                    {
                        //8 Bit 1 Channel
                        case 1:
                            result[i] = linear2ulaw(bytes[resultIndex]);
                            resultIndex += 1;
                            break;

                        //8 Bit 2 Channel
                        case 2:
                            result[i] = linear2ulaw(bytes[resultIndex]);
                            resultIndex += 2;
                            break;
                    }
                    break;

                case 16:
                    switch (channels)
                    {
                        //16 Bit 1 Channel
                        case 1:
                            result[i] = linear2ulaw(BitConverter.ToInt16(bytes, resultIndex));
                            resultIndex += 2;
                            break;

                        //16 Bit 2 Channels
                        case 2:
                            result[i] = linear2ulaw(BitConverter.ToInt16(bytes, resultIndex));
                            resultIndex += 4; // this is 4 to skip the right channel
                            break;
                    }
                    break;
            }
        }


        return result;
    }

А вот код для обратного преобразования:

    public static Byte[] MuLawToLinear(Byte[] bytes, int bitsPerSample, int channels)
    {
      // return bytes;

        int blockAlign = channels * bitsPerSample / 8;


        Byte[] result = new Byte[bytes.Length * blockAlign];
        for (int i = 0, counter = 0; i < bytes.Length; i++, counter += blockAlign)
        {

            int value = MulawToLinear(bytes[i]);
            Byte[] values = BitConverter.GetBytes(value);

            switch (bitsPerSample)
            {
                case 8:
                    switch (channels)
                    {
                        //8 Bit 1 Channel
                        case 1:
                            result[counter] = values[0];
                            break;

                        //8 Bit 2 Channel
                        case 2:
                            result[counter] = values[0];
                            result[counter + 1] = values[0];
                            break;
                    }
                    break;

                case 16:
                    switch (channels)
                    {
                        //16 Bit 1 Channel
                        case 1:
                            result[counter] = values[0];
                            result[counter + 1] = values[1];
                            break;

                        //16 Bit 2 Channels
                        case 2:
                            result[counter] = values[0];
                            result[counter + 1] = values[1];
                            result[counter + 2] = values[0]; //tried 3 and 4 here
                            result[counter + 3] = values[1];
                            break;
                    }
                    break;
            }
        }


        return result;
    }

Эти две функции будут принимать массив байтов линейного стерео PCM и выводить их как моно.

Входные байты имеют следующий формат: байт 0, байт 1 - левый канал, а байты 2 и 3 - правый канал. Теперь автор преобразует входной байтовый массив в моно, увеличив индекс результата на 4, пропуская правый канал. В MuLaw to Linear он помещает значения правого канала в левый.

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

...