如何记录并使用AsioOut n音讯播放 [英] How to record and playback with NAudio using AsioOut

查看:591
本文介绍了如何记录并使用AsioOut n音讯播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图获取声音输入发送有延迟可能较少直接输出用C#。

我使用该库的 n音讯,支持的 ASIO 更好的延迟。

I'm using the library NAudio that supports ASIO for better latency.

在特别的,我用在 AsioOut 对象进行记录和另一个用于回放初始化的 BufferedWaveProvider ,这是填补了一个回调函数: OnAudioAvailable ,它允许我使用在ASIO缓冲区。

In particular, I use the AsioOut object for recording and another for playback initialized with a BufferedWaveProvider, which is filled in a Callback function: OnAudioAvailable, which allows me to use the ASIO buffers.

的问题是,我听到的是各种故障并与延迟的声音。我认为这个问题是在功能OnAudioAvailable所在的缓冲区充满了作为从声卡输入数据

The problem is that I hear the sound with various glitches and with a bit of delay. I think the problem is in the function OnAudioAvailable where the buffer is filled with data taken as input from the sound card.

声明:

NAudio.Wave.AsioOut playAsio;
NAudio.Wave.AsioOut recAsio;
NAudio.Wave.BufferedWaveProvider buffer;

播放过程:

if (sourceList.SelectedItems.Count == 0) return;

int deviceNumber = sourceList.SelectedItems[0].Index;

recAsio = new NAudio.Wave.AsioOut(deviceNumber);
recAsio.InitRecordAndPlayback(null, 2, 44100); //rec channel = 1

NAudio.Wave.WaveFormat formato = new NAudio.Wave.WaveFormat();
buffer = new NAudio.Wave.BufferedWaveProvider(formato);

recAsio.AudioAvailable += new EventHandler<NAudio.Wave.AsioAudioAvailableEventArgs>(OnAudioAvailable);

//Collego l'output col buffer
playAsio = new NAudio.Wave.AsioOut(deviceNumber);
playAsio.Init(buffer);

//Registro
recAsio.Play();
//Playback
playAsio.Play();



OnAudioAvailable():

//Callback
private unsafe void OnAudioAvailable(object sender, NAudio.Wave.AsioAudioAvailableEventArgs e)
{
    //Copio tutti gli elementi di InputBuffers in buf e li aggiungo in coda al buffer
    byte[] buf = new byte[e.SamplesPerBuffer];
    for (int i = 0; i < e.InputBuffers.Length; i++)
    {
        Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer);
        //Aggiungo in coda al buffer
        buffer.AddSamples(buf, 0, buf.Length);
    }
}



AsioAudioAvailableEventArgs定义:

public AsioAudioAvailableEventArgs(IntPtr[] inputBuffers, int samplesPerBuffer, AsioSampleType asioSampleType);
public float[] GetAsInterleavedSamples();



有谁知道如何解决它?
谢谢大家。

Does anyone know how to fix it? Thank you all.

推荐答案

您不应该使用的两个实例来 AsioOut 同一设备。我很惊讶这个工作的。只需使用一,用 InitRecordAndPlayback

You should not be using two instances of AsioOut for the same device. I'm surprised this works at all. Just use the one, with InitRecordAndPlayback.

有关绝对最小的延迟为传递监控, AudioAvailableEvent ,直接复制到 OutputBuffers ,并设定 WrittenToOutputBuffers = TRUE 。这意味着你不需要 BufferedWaveProvider

For absolute minimal latency for pass-through monitoring, in AudioAvailableEvent, copy directly to the OutputBuffers, and set WrittenToOutputBuffers = true. This means you don't need a BufferedWaveProvider.

还记得任何毛刺只是由于你不管理处理AudioAvailable事件的速度不够快。当你使用ASIO的工作,你可以以非常低的延迟(如分10毫秒),并且可以处理大量的数据(例如96kHz的采样率,8路输入和输出)。所以,你需要做的数据在很短的时间窗口移动了不少。在.NET,你在不幸的事实是,垃圾收集器可以在任何时候踢,使你错过一次缓冲时间因素。

Also remember that any glitches are simply due to you not managing to process the AudioAvailable event quickly enough. When you're working with ASIO, you can be at very low latencies (e.g. sub 10ms), and can be dealing with lots of data (e.g. 96kHz sample rates, 8 channels of input and output). So you need to do a lot of moving of data in a short time window. With .NET, you have to factor in the unfortunate fact that the garbage collector could kick in at any time and cause you to miss a buffer from time to time.

这篇关于如何记录并使用AsioOut n音讯播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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