Vik*_*exe 5 c# optimization instrumentation naudio
我有一个播放流音频数据的应用程序(如聊天客户端)。工作流程包括三个简单的步骤:
数据接收代码是原生的(C 代码)。它读取套接字上的数据。然后它调用托管 C# 代码,该代码使用 Naudio 库来初始化设备并播放音频。
现在的问题是,我看到音频播放有些延迟。我已经检测了我的其余代码(特别是:在套接字上传输数据并将其传递回托管代码),这似乎没问题。整个传输过程大约需要 600 微秒,但是在我将缓冲区分配给 之后Naudio,它似乎在一段时间后开始播放(大约 200-250 毫秒)。
这是我处理音频播放部分的 C# 类:
class foo
{
static IWavePlayer s_WaveOut;
static WaveFormat s_WaveOutFormat;
static BufferedWaveProvider s_WaveProvider;
static byte[] s_Samples = new byte[10000];
// called from native code to init deivce with specified sample rate and num of channels
private static void DeviceInit(int rate, int bits, int channels)
{
s_WaveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
s_WaveOutFormat = new WaveFormat(rate, bits, channels);
s_WaveProvider = new BufferedWaveProvider(s_WaveOutFormat);
s_WaveProvider.DiscardOnBufferOverflow = true;
s_WaveProvider.BufferLength = 5 * 1024 * 1024;
s_WaveOut.Init(s_WaveProvider);
s_WaveOut.Play();
}
// called from native 'C' code upon receiving audio packates
private unsafe static void PlayDataCallback(
IntPtr buff,
Int32 size)
{
Marshal.Copy(buff, s_Samples, 0, size);
s_WaveProvider.AddSamples(s_Samples, 0, size);
}
}
Run Code Online (Sandbox Code Playgroud)
任何人都知道可能导致延迟的原因,或者我是否以错误的方式使用它(Naudio)。
我尝试了相同的 Naudio 库来播放 wav 文件,这似乎很完美,只有在我自己初始化设备后添加样本时才会出现问题。
[更新]如果我改变s_WaveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());到s_WaveOut = new DirectSound();,性能要好得多。如果在此之后,我修改 Naudio 源以将播放线程优先级设置为Highest(默认为 Normal),则性能进一步提高,但正如预期的那样,该进程开始消耗大量资源。
谢谢,
维克拉姆
我还使用 NAudio 开发音频流应用程序。我们还存在延迟问题。达到300毫秒。
捕获每秒发生 10 次(每 100 毫秒一次)。
使用 Vikram.exe 的建议来使用 DirectSoundOut 而不是 WaveOut 有一点帮助。延迟减少了 50 或 100 毫秒,但前提是我将所需延迟设置为 50 毫秒。
new DirectSoundOut(guid, 50);
Run Code Online (Sandbox Code Playgroud)
另一项技巧已将延迟降低了 100 或 200 毫秒。我们检查是否正在播放声音,如果有则跳过新帧。
if (s_WaveProvider.BufferedDuration <= 100)
s_WaveProvider.AddSamples(s_Samples, 0, size);
Run Code Online (Sandbox Code Playgroud)
在声音流畅度方面还有一些工作要做,但现在基本上已经没有延迟了。
音频播放总是会产生延迟。对于 WaveOut,您可以指定缓冲区的数量和总体所需的延迟。您还可以为其他驱动程序模型指定缓冲区大小。对于大多数播放场景,两个 100 毫秒的缓冲区是理想的选择,因为它具有合理的响应能力,并且除非在极端负载下,否则不会卡顿。但是,如果需要,您可以降低值,但要冒无法及时填充下一个缓冲区的风险。不要期望使用 NAudio 在 DAW 中获得那么低的延迟(例如 5 毫秒),它没有经过高度优化,并且由于垃圾收集器的原因,.NET 框架无论如何都不是特别适合此类应用程序。
以下是设置 WaveOut 输出延迟的示例:
var waveOut = new WaveOut();
waveout.DesiredLatency = 50; // 50ms latency
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7429 次 |
| 最近记录: |