有效地转换音频字节 - 字节[]短[] [英] Efficiently convert audio bytes - byte[] to short[]
问题描述
我试图使用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
orBuffer.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屋!