如何使用NAudio和ASIO直接读取输入缓冲区和播放?

时间:2015-04-06 12:35:07

标签: 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;
    }
}

1 个答案:

答案 0 :(得分:0)

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;
    }
}