c# - 如何使用NAudio和ASIO直接读取输入缓冲区并进行回放?

标签 c# .net audio naudio asio

使用ASIO和NAudio库的以下C#代码对我有一点问题。

我尝试从吉他获得声音,然后直接在扬声器中播放声音。到目前为止,它仍然有效,但是声音非常失真。我读过here,这是一种通过以下方式解决问题的方法:

Marshal.Copy(buf, 0, e.OutputBuffers[i], e.SamplesPerBuffer * 4);

但是,如果这样做,缓冲区的大小将增大4倍,因此代码将无法编译。

我已经使用asio4all和MAUDIO卡进行了尝试;他们两个都是同一个问题。
public partial class MainWindow : Window
{
    AsioOut ASIODriver;
    BufferedWaveProvider buffer;
    public MainWindow()
    {
        String[] drivernames = AsioOut.GetDriverNames();
        ASIODriver = new AsioOut(drivernames[0]);

        buffer = new BufferedWaveProvider(new WaveFormat ());
        ASIODriver.AudioAvailable += new EventHandler<AsioAudioAvailableEventArgs>(ASIODriver_AudioAvailable);
        ASIODriver.InitRecordAndPlayback(buffer,2,44100);
        //ASIODriver.InputChannelOffset = 1;
        ASIODriver.Play();       
    }

    private void ASIODriver_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
    {
        byte[] buf = new byte[e.SamplesPerBuffer];
        for (int i = 0; i < e.InputBuffers.Length; i++)
        {
           Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer);
           Marshal.Copy(buf, 0, e.OutputBuffers[i], e.SamplesPerBuffer); 
        }
        e.WrittenToOutputBuffers = true;
    }
}

最佳答案

OP解决方案。

解决方案是增加缓冲区的大小。有关更改,请参见注释行及其后续的一行。

public partial class MainWindow : Window
{
    AsioOut ASIODriver;
    BufferedWaveProvider buffer;
    public MainWindow()
    {
        String[] drivernames = AsioOut.GetDriverNames();
        ASIODriver = new AsioOut(drivernames[0]);

        buffer = new BufferedWaveProvider(new WaveFormat ());
        ASIODriver.AudioAvailable += new EventHandler<AsioAudioAvailableEventArgs>(ASIODriver_AudioAvailable);
        ASIODriver.InitRecordAndPlayback(buffer,2,44100);
        ASIODriver.Play();       
    }

    private void ASIODriver_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
    {
        //byte[] buf = new byte[e.SamplesPerBuffer];
        byte[] buf = new byte[e.SamplesPerBuffer*4];
        for (int i = 0; i < e.InputBuffers.Length; i++)
        {
           //Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer);
           //Marshal.Copy(buf, 0, e.OutputBuffers[i], e.SamplesPerBuffer);
           Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer*4);
           Marshal.Copy(buf, 0, e.OutputBuffers[i], e.SamplesPerBuffer*4);
        }
        e.WrittenToOutputBuffers = true;
    }
}

关于c# - 如何使用NAudio和ASIO直接读取输入缓冲区并进行回放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29471438/

相关文章:

c# - 在构造函数中作为通用类型的操作会产生编译错误

c# - 使用查询或代码

audio - ffmpeg - 向视频添加 3 个音频流

Java - 使用音频剪辑时出现问题

c# - 查找未使用/不必要的 assemblyBinding 重定向

c# - WPF 中的 ListView 和 MySQL

c# - 在 C# 中包装包含固定大小 C 数组的结构

html - Dart中的Dartium和Web Audio API导致声音失真

c# - ITextSharp 异常读取 pdf : Rebuild failed: Dictionary key "" is not a name

c# - 在构建时自动将 C++ 库复制到 C# 项目? ( Visual Studio 2010)