有效地转换音频字节 - byte []到short []

Dav*_*ers 2 c# silverlight xna bytearray windows-phone-7

我正在尝试使用XNA麦克风捕获音频并将其传递给我分析数据以用于显示目的的API.但是,API需要16位整数数组中的音频数据.所以我的问题相当直截了当; 什么是将字节数组转换为短数组的最有效方法?

    private void _microphone_BufferReady(object sender, System.EventArgs e)
    {
        _microphone.GetData(_buffer);

        short[] shorts;

        //Convert and pass the 16 bit samples
        ProcessData(shorts);
    }
Run Code Online (Sandbox Code Playgroud)

干杯,戴夫

编辑:这是我提出的,似乎工作,但它可以更快地完成吗?

    private short[] ConvertBytesToShorts(byte[] bytesBuffer)
    {
        //Shorts array should be half the size of the bytes buffer, as each short represents 2 bytes (16bits)
        short[] shorts = new short[bytesBuffer.Length / 2];

        int currentStartIndex = 0;

        for (int i = 0; i < shorts.Length - 1; i++)
        {
            //Convert the 2 bytes at the currentStartIndex to a short
            shorts[i] = BitConverter.ToInt16(bytesBuffer, currentStartIndex);

            //increment by 2, ready to combine the next 2 bytes in the buffer
            currentStartIndex += 2;
        }

        return shorts;

    }
Run Code Online (Sandbox Code Playgroud)

And*_*ell 5

阅读完更新后,我可以看到你需要实际将一个字节数组直接复制到short的缓冲区中,合并字节.这是文档中的相关部分:

用作SoundEffect构造函数的参数的byte []缓冲区格式,Microphone.GetData方法和DynamicSoundEffectInstance.SubmitBuffer方法是PCM波形数据.另外,PCM格式是交错的并且是小端的.

现在,如果你的系统有一些奇怪的原因BitConverter.IsLittleEndian == false,那么你将需要循环缓冲区,交换字节,从little-endian转换为big-endian.我将把代码留作练习 - 我有理由相信所有的XNA系统都是小端的.

出于您的目的,您可以直接使用Marshal.Copy或复制缓冲区Buffer.BlockCopy.两者都将为您提供平台本机内存复制操作的性能,这将非常快:

// Create this buffer once and reuse it! Don't recreate it each time!
short[] shorts = new short[_buffer.Length/2];

// Option one:
unsafe
{
    fixed(short* pShorts = shorts)
        Marshal.Copy(_buffer, 0, (IntPtr)pShorts, _buffer.Length);
}

// Option two:
Buffer.BlockCopy(_buffer, 0, shorts, 0, _buffer.Length);
Run Code Online (Sandbox Code Playgroud)