我正在尝试在c#中实现VAD(语音活动检测)算法,因为我没有为此目的找到任何合适的库。 我不使用波形文件,但只使用内存流,如下所示:
NAudio.Wave.WaveFileWriter waveWriter;
Stream s1 = new MemoryStream();
WaveInEvent waveSource = new WaveInEvent();
waveSource.WaveFormat = new NAudio.Wave.WaveFormat(16000, 16, 1);
waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
waveWriter = new NAudio.Wave.WaveFileWriter(s1, waveSource.WaveFormat);
waveSource.StartRecording();
Console.ReadLine();
waveSource.StopRecording();
s1.Position = 0;
var bytes = streamToArray(s1);
我将遵循这个tutorial,其中第一步是将输入信号分割为10ms帧。我知道如何从文件输入中执行此操作,但如何使用字节数组执行类似的操作? 谢谢你的回答!
更新
我测试了这些方法:
1
short[] sdata = new short[(int)Math.Ceiling(bytes.Length / 2.0)];
Buffer.BlockCopy(bytes, 0, sdata, 0, bytes.Length);
2
for (var i = 0; i < bytes.Length; i += 2)
{
var b1 = (short)bytes[i];
var b2 = (short)bytes[i + 1];
sListData.Add((short)(b1 | b2 << 8));
}
当我将输出数组与使用Big Endian的方法进行比较时,它们都是相同的。
所以BlockCopy
完成了这项工作,但只有当BE合适时才能完成。
答案 0 :(得分:0)
不是100%肯定这是不是你的意思,但是: 假设音频流参数为16kbp,每个样本16bit,单通道,这是一个非常快速的计算,如果16000个样本是1秒,那么10ms是16000/100 = 160个样本。现在16位是2个字节,它给我们160 * 2 = 320字节。 所以每个320字节是10ms。 您可以使用Array.Copy - https://msdn.microsoft.com/en-us/library/z50k9bft(v=vs.110).aspx将chunk od数据复制到单独的数组中。
下面只是一些代码:
var int8Array = new byte [] {0x04,0x02,0x08,0xA1};
var int16ArrayLE = new List<short>();
var int16ArrayBE = new List<short>();
for(var i=0;i<int8Array.Length;i+=2)
{
var b1 = (short)int8Array[i];
var b2 = (short)int8Array[i+1];
int16ArrayLE.Add((short)((b1 << 8) + b2));
int16ArrayBE.Add((short)(b1 + (b2 << 8)));
}
.net短类型是16位整数,字节是8位整数。代码对可读性有点明确。我展示了两种可能的转换 - Little Endian和Big Endian。在前者中,第一个字节在后一个第二个字节中更为重要。字节顺序取决于流格式,可以是。