如何使用 ASIO 和 Naudio 将音频捕获保存在 wav 文件中?

Posted

技术标签:

【中文标题】如何使用 ASIO 和 Naudio 将音频捕获保存在 wav 文件中?【英文标题】:How to save an audio capture in a wav file using ASIO and Naudio? 【发布时间】:2015-06-13 22:11:07 【问题描述】:

到目前为止,我写的是:

private AsioOut ASIODriver;
private BufferedWaveProvider buffer;

String[] drivernames = AsioOut.GetDriverNames();
ASIODriver = new AsioOut(drivernames[1]);
buffer = new BufferedWaveProvider(new WaveFormat(sampleRate, 16, 2));
ASIODriver.AudioAvailable += new EventHandler<AsioAudioAvailableEventArgs>(ASIODriver_AudioAvailable);
ASIODriver.InitRecordAndPlayback(buffer, 2, sampleRate);
ASIODriver.Play();

private void ASIODriver_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
 
    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 * 4);
        Marshal.Copy(buf, 0, e.OutputBuffers[i], e.SamplesPerBuffer * 4);

        if (recorderOn && i == 1)
        
            recorder.addInputToStream(buf);
        
    

这部分用于通过 ASIO 捕捉和播放吉他的声音。到目前为止没有问题。

public void addInputToStream(byte[] buffer)

    byte[] sample = new byte[buffer.Length / 4];
    if (waveWriter == null) waveWriter = new WaveFileWriter(@"C:\Temp\Test0001.wav", new WaveFormat(44100, 16, 1));
    for (int i = 0; i < buffer.Length; i = i + 4)
    
        sample[i/4] = (byte)Convert.ToSingle(buffer[i] + buffer[i + 1] + buffer[i + 2] + buffer[i + 3]);
    
    waveWriter.Write(sample, 0, sample.Length);

问题出现在方法addInputToStream,声音很好的放在了.wav文件里但是文件里有很多“音频寄生虫”。很烦人。 我在调用该方法时尝试更改 i 变量,不使用 Convert.ToSingle 但结果相同。

我怀疑waveWriterWaveFormat 有问题,但我不知道我错过了什么。 你们谁有线索?

【问题讨论】:

您将四个字节变量加在一起,转换为一个字节,然后转换为一个字节。这对我来说没有任何意义。你想达到什么目的? @MarkHeath 我想要的只是将来自 ASIO 输入缓冲区的音频信号录制到 .wav 文件中。问题是音频文件包含类似于输入信号的东西,但有很多噪声寄生虫。对于 Convert.ToSingle,我同意。最初,我写道:if (waveWriter == null) waveWriter = new waveFileWriter(@"C:\Temp\Test0001.wav", new WaveFormat(44100, 16, 1)); waveWriter.Write(buffer, 0, buffer.Length); 但同样的结果,音频文件非常嘈杂。我不知道我是否足够清楚,英语不流利。 【参考方案1】:

您需要创建一个 WaveFileWriter 并写出示例。这很简单,但我也花了一段时间才搞定。 (注意:我没有设置 waveprovider,但你已经有了那个部分)。

 class Asiosample

    private NAudio.Wave.AsioOut _audioDevice;
    public WaveFileWriter AsioWaveFileWriter;
    public AsioSample()
    
        //this is set for one channel
        AsioWaveFileWriter = new WaveFileWriter("sample.wav", new WaveFormat(48000, 1));
        _audioDevice = new NAudio.Wave.AsioOut(2);//or whatever
        _audioDevice.InitRecordAndPlayback(_waveProvider, 1, 48000);
        _audioDevice.AudioAvailable += new EventHandler<NAudio.Wave.AsioAudioAvailableEventArgs>(OnAudioAvailable);
        _audioDevice.Play();
    

    private unsafe void OnAudioAvailable(object sender, NAudio.Wave.AsioAudioAvailableEventArgs e)
    
        var floatsamples = new float[e.SamplesPerBuffer * e.InputBuffers.Length];
        e.GetAsInterleavedSamples(floatsamples);
        AsioWaveFileWriter.WriteSamples(floatsamples, 0, floatsamples.Length);
        AsioWaveFileWriter.Flush();
    

 

【讨论】:

以上是关于如何使用 ASIO 和 Naudio 将音频捕获保存在 wav 文件中?的主要内容,如果未能解决你的问题,请参考以下文章

在 NAudio 中列出 ASIO 音频输出设备

NAudio ASIO Playback 在某些设备上挂起

尝试在 ASIO 输出上使用 NAudio 播放音频时的空引用

NAudio Asio 录制和播放

NAudio Asio 同时录制和播放

NAudio - ASIO 播放到设备(仅限静态)