有效地转换音频字节 - 字节[]短[] [英] Efficiently convert audio bytes - byte[] to short[]

查看:231
本文介绍了有效地转换音频字节 - 字节[]短[]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用XNA麦克风捕获音频并将它传递给一个API我有分析用于显示目的的数据。然而,API要求中的16位的整数的数组中的音频数据。所以我的问题是相当简单的;什么是对的字节数组转换成短阵的最有效方法是什么?



 私人无效_microphone_BufferReady(对象发件人,发送System.EventArgs )
{
_microphone.GetData(_buffer);

短[]短裤;

//转换并通过16位示例
过程数据(短裤);
}



干杯,
戴夫



修改:这是我想出了,似乎工作,但能不能做到更快

 私的短[] ConvertBytesToShorts(字节[] bytesBuffer)
{
//短裤阵列应该是字节的缓冲区大小的一半,因为每个短代表2个字节( 16位)
短[] =短裤新的短[bytesBuffer.Length / 2];

INT currentStartIndex = 0;

的for(int i = 0; I< shorts.Length - 1;我++)在currentStartIndex
{
//将2个字节为短
短裤[I] = BitConverter.ToInt16(bytesBuffer,currentStartIndex);

//增量2,准备接下来的2个字节的缓冲区
结合currentStartIndex + = 2;
}

返回短裤;

}


解决方案

阅读后您的更新,我可以看到你需要实际直接复制字节数组的短裤的缓冲区,合并字节。下面是来自文档的相关章节:




的字节[]用作用于SoundEffect中构造一个参数,Microphone.GetData方法和DynamicSoundEffectInstance.SubmitBuffer方法缓冲器格式是PCM波形数据。此外,PCM格式是交错和little-endian的。




现在,如果出于某种奇怪的原因,你的系统有 BitConverter.IsLittleEndian ==虚假,那么你就需要遍历您的缓冲区,交换字节,当您去,从小端转换为大端。我会离开的代码作为一个练习 - 我有理由相信所有的XNA系统是小端



有关你的目的,你可以复制缓冲区直接使用 Marshal.Copy Buffer.BlockCopy 。双方将会给你平台的本地内存复制操作的性能,这将是非常快的:

  //创建这个缓冲区一次和重用!每次不要重建它! 
短[] =短裤新的短[_buffer.Length / 2];

//选择一:
不安全
{
固定(短* pShorts =短裤)
Marshal.Copy(_buffer,0,(IntPtr的) pShorts,_buffer.Length);
}

//办法二:
Buffer.BlockCopy(_buffer,0,短裤,0,_buffer.Length);


I'm trying to use the XNA microphone to capture audio and pass it to an API I have that analyses the data for display purposes. However, the API requires the audio data in an array of 16 bit integers. So my question is fairly straight forward; what's the most efficient way to convert the byte array into a short array?

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

        short[] shorts;

        //Convert and pass the 16 bit samples
        ProcessData(shorts);
    }

Cheers, Dave

EDIT: This is what I have come up with and seems to work, but could it be done faster?

    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;

    }

解决方案

After reading your update, I can see you need to actually copy a byte array directly into a buffer of shorts, merging bytes. Here's the relevant section from the documentation:

The byte[] buffer format used as a parameter for the SoundEffect constructor, Microphone.GetData method, and DynamicSoundEffectInstance.SubmitBuffer method is PCM wave data. Additionally, the PCM format is interleaved and in little-endian.

Now, if for some weird reason your system has BitConverter.IsLittleEndian == false, then you will need to loop through your buffer, swapping bytes as you go, to convert from little-endian to big-endian. I'll leave the code as an exercise - I am reasonably sure all the XNA systems are little-endian.

For your purposes, you can just copy the buffer directly using Marshal.Copy or Buffer.BlockCopy. Both will give you the performance of the platform's native memory copy operation, which will be extremely fast:

// 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);

这篇关于有效地转换音频字节 - 字节[]短[]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆