naudio 从麦克风录制声音然后保存

Posted

技术标签:

【中文标题】naudio 从麦克风录制声音然后保存【英文标题】:naudio record sound from microphone then save 【发布时间】:2013-07-31 23:01:35 【问题描述】:

我在使用 naudio 和保存录音时遇到了一些问题。我目前拥有的代码可以保存 wav 文件,但是当我打开它时,Windows Media Player 返回错误:“Windows Media Player 在播放文件时遇到问题”

我有两个按钮,一个“录制”按钮,按下后变成停止按钮。而且我有一个“保存”按钮,单击该按钮会将录音保存到sample.wav

NAudio.Wave.WaveIn sourceStream = null;
NAudio.Wave.DirectSoundOut waveOut = null;
NAudio.Wave.WaveFileWriter waveWriter = null;

private void recordButton_Click(object sender, EventArgs e)

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

    sourceStream = new NAudio.Wave.WaveIn();
    sourceStream.DeviceNumber = deviceNumber;
    sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);

    NAudio.Wave.WaveInProvider waveIn = new NAudio.Wave.WaveInProvider(sourceStream);

    waveOut = new NAudio.Wave.DirectSoundOut();
    waveOut.Init(waveIn);

    sourceStream.StartRecording();
    waveOut.Play();

    recordButton.Visible = false;
    stopRecord.Visible = true;


private void saveResponse_Click(object sender, EventArgs e)

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

    string saveLocation = "c:\\wav\\sample.wav";

    sourceStream = new NAudio.Wave.WaveIn();
    sourceStream.DeviceNumber = deviceNumber;
    sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(deviceNumber).Channels);

    sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable);
    waveWriter = new NAudio.Wave.WaveFileWriter(saveLocation, sourceStream.WaveFormat);

    sourceStream.StartRecording();

    MessageBox.Show("Recording successfully saved.");


private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)

    if (waveWriter == null) return;

    waveWriter.WriteData(e.Buffer, 0, e.BytesRecorded);
    waveWriter.Flush();

private void stopRecord_Click(object sender, EventArgs e)

    if (waveOut != null)
    
        waveOut.Stop();
        waveOut.Dispose();
        waveOut = null;
    
    if (sourceStream != null)
    
        sourceStream.StopRecording();
        sourceStream.Dispose();
        sourceStream = null;
    
    if (waveWriter != null)
    
        waveWriter.Dispose();
        waveWriter = null;
    

    recordButton.Visible = true;
    stopRecord.Visible = false;
    saveResponse.Enabled = true;

【问题讨论】:

你能展示一下你的“停止”动作背后的代码吗?只需要看看你是如何关闭waveWriter 等的。 @Corey,我在代码中添加了“停止”操作。干杯。 好的,用类似的代码测试过,一切似乎都对我有用。您是否在尝试在 WMP 中播放之前停止录制? 我要做的是单击“录制”按钮并录制我的声音,然后单击停止按钮,然后单击“保存”按钮。当我单击保存按钮并打开 wav 文件时,没有音频。 啊...那就可以解释了。我觉得这看起来有点古怪:P 【参考方案1】:

您的recordButton_Click 代码没有记录,它是从WaveInWaveOut 的管道数据,这会将来自您的源(麦克风)的数据直接播放到输出(扬声器)。它不会保留该数据以供以后使用,它只是将其从一个管道传输到另一个。如果您想随后将该数据保存到磁盘,则需要自己进行缓冲。

另一方面,saveResponse_Click 正在开始将数据从麦克风直接记录到磁盘上的波形文件中。如果你点击你的Save Response按钮,稍等片刻,然后点击你的Stop按钮,你应该会得到一个录制的波形文件。

如果您想直接记录到磁盘,这很好。如果您想记录到内存,然后可选地写入磁盘,那么您需要在数据进入时保存数据。也许在记录时使用内存流来保存数据,然后在需要时将其写入WaveFileWriter保存文件。


这是我用于测试直接录制到磁盘上的波形文件的代码:

public WaveIn waveSource = null;
public WaveFileWriter waveFile = null;

private void StartBtn_Click(object sender, EventArgs e)

    StartBtn.Enabled = false;
    StopBtn.Enabled = true;

    waveSource = new WaveIn();
    waveSource.WaveFormat = new WaveFormat(44100, 1);

    waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
    waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped);

    waveFile = new WaveFileWriter(@"C:\Temp\Test0001.wav", waveSource.WaveFormat);

    waveSource.StartRecording();


private void StopBtn_Click(object sender, EventArgs e)

    StopBtn.Enabled = false;

    waveSource.StopRecording();


void waveSource_DataAvailable(object sender, WaveInEventArgs e)

    if (waveFile != null)
    
        waveFile.Write(e.Buffer, 0, e.BytesRecorded);
        waveFile.Flush();
    


void waveSource_RecordingStopped(object sender, StoppedEventArgs e)

    if (waveSource != null)
    
        waveSource.Dispose();
        waveSource = null;
    

    if (waveFile != null)
    
        waveFile.Dispose();
        waveFile = null;
    

    StartBtn.Enabled = true;

【讨论】:

当我写你的代码时,它抛出异常并说“BadDeviceId 调用 waveInOpen”。有什么建议吗?那是什么错误? @abidinberkay 默认的 DeviceNumber 为 0,如果 ID 不正确,可能意味着您从未插入过麦克风。

以上是关于naudio 从麦克风录制声音然后保存的主要内容,如果未能解决你的问题,请参考以下文章

无法使用麦克风 c# naudio 捕捉 15k 的音调

使用 NAudio 使用 asioout 录制时如何使声音更大?

NAudio 记录和保存麦克风输入和扬声器输出

错误的 .wav 格式录制音频 NAudio 库

使用 ActionScript 3 将保存声音录制到文件中。不是来自麦克风

在 Java 中使用声音计将声音从麦克风录制到文件