【发布时间】:2011-11-03 10:32:22
【问题描述】:
我正在尝试播放通过网络接收到的音频,该音频以一系列短裤的形式到达。我正在尝试使用 NAudio 的 WaveOut 对象来完成这项工作,但据我所知,这仅适用于字节 []。所以到目前为止我的问题是:
- 是否可以从 short[] 而不是 byte[] 播放音频?
- 如果是这样,该怎么做?
不多,但我现在拥有的是这个(显然是从一个字节[]播放音频):
protected override void Write(VoiceSource source, VoicePacket packet)
{
if (connected)
{
try
{
dispatcher.Invoke((WriteCallback)provider.Write, packet.Data);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}
WriteCallback 定义为:
private delegate void WriteCallback(byte[] data);
我要写信的提供者是IWaveProvider 接口的实现。
编辑
我尝试了 Mark 告诉我的“技巧”,我的界面如下所示:
interface ISampleBuffer {
byte[] Bytes { get; set; }
short[] Shorts { get; set; }
}
缓冲区结构如下所示:
[StructLayout(LayoutKind.Explicit, Pack = 2)]
public struct SampleBuffer : ISampleBuffer
{
[FieldOffset(0)]
private byte[] bytes;
[FieldOffset(0)]
private short[] shorts;
public byte[] Bytes { get { return bytes; } set { bytes = value; } }
public short[] Shorts { get { return shorts; } set { shorts = value; } }
}
我已经这样实现了这个缓冲区:
short[] audio = decoder.Decode(packet.Data);
buffer.Bytes = new byte[audio.Length * 2];
buffer.Shorts = audio;
dispatcher.Invoke((WriteCallback)provider.Write, buffer.Bytes);
但是,每当我运行此设置时,我的日志中都会出现堆栈跟踪,并出现以下异常:
Object of type 'System.Int16[]' cannot be converted to type 'System.Byte[]'.
我的实现方式有问题吗?
【问题讨论】:
-
您误解了
byte[]和short[]的实际含义。数组是引用类型,因此byte[]类型的变量实际上是指向堆上其他位置的指针。要做这样的事情,你需要在不安全的结构中使用fixed字段,并且你需要在编译时知道数组的大小。 -
数组的大小在编译时是已知的。我得到的音频是 24o 长度的短数组。所以应该是可以的。我需要改变什么才能让它工作?
-
使用固定缓冲区:msdn.microsoft.com/en-us/library/zycewsya%28v=VS.100%29.aspx。您必须使用指针和其他错误将其转换为数组。虽然我觉得你从错误的角度解决问题,但如果你不得不求助于那些......
-
好吧,由于实现它的复杂性,我宁愿不使用它。但我只是在探索各个角度,看看什么是有效的。我已经尝试过您的方法,从技术上讲,它可以顺利运行。但实际上,我什么也没听到。没有音频正在播放。
-
应该反过来。 buffer.Shorts = decoder.Decode... 然后将 buffer.Bytes 传递给你的函数