Преобразование массива байтов в массив шорт без копирования данных - PullRequest
3 голосов
/ 12 мая 2011

У меня есть массив байтов, которые на самом деле являются 16-битными сэмплами со звуковой карты. Таким образом, 1000 байтов фактически представляют 500 Short (16-битные значения).

В настоящее время я конвертирую их так:

byte [] inputData = new byte[1000];
short [] convertedData = new short[500];
Buffer.BlockCopy(inputData, 0, convertedData , 0, 1000);

Работает нормально и довольно быстро, поскольку это низкоуровневая байтовая копия.

Но есть ли способ сделать это без копии? то есть сказать C # для обработки этой области памяти как массива 500 шорт вместо 1000 байтов? Я знаю, что в C / C ++ я мог бы просто навести указатель, и это сработало бы.

Эта копия выполняется в узком цикле, до 5000 раз в секунду, поэтому, если я смогу удалить копию, это будет полезно.

Ответы [ 3 ]

8 голосов
/ 12 мая 2011

StructLayout позволяет управлять физическим расположением полей данных в классе или структуре.Обычно он используется при взаимодействии с неуправляемым кодом, который ожидает данные в определенной компоновке.

Попробуйте:

[StructLayout(LayoutKind.Explicit)]
struct UnionArray
{
    [FieldOffset(0)]
    public Byte[] Bytes;

    [FieldOffset(0)]
    public short[] Shorts;
}

static void Main(string[] args)
{
    var union = new UnionArray() {Bytes = new byte[1024]};

    foreach (short s in union.Shorts)
    {
        Console.WriteLine(s);
    }
}
2 голосов
/ 12 мая 2011

Возможно, аналог C # языка C union сработает.

0 голосов
/ 12 мая 2011
bytes[] inputData = Array.ConvertAll<short, bytes>(bytes, delegate(short[] convertedData) { return short.Parse(convertedData); } );

что-то в этом роде, я не проверял, но, возможно, это вам поможет:)

...