听到来自麦克风的传入音频

Posted

技术标签:

【中文标题】听到来自麦克风的传入音频【英文标题】:Hearing the Incoming audio from mic 【发布时间】:2013-02-27 00:08:36 【问题描述】:

我只想听听我使用 NAudio 对麦克风说的话,这是我目前的代码,但问题是我什么都听不到。任何帮助将不胜感激。

public partial class frmMain : Form
    
        private WaveIn waveIn; // Gets an audio from microphone
        private WaveOut waveOut; // Sends audio to speaker
        private BufferedWaveProvider waveProvider; // Gets an audio from stream

        public frmMain()
        
            InitializeComponent();
        

        private void frmMain_Load(object sender, EventArgs e)
        
            waveOut = new WaveOut();
            waveIn = new WaveIn();
            waveProvider = new BufferedWaveProvider(waveIn.WaveFormat);

            waveOut.Init(waveProvider);             

            waveIn.DataAvailable += waveIn_DataAvailable;

            waveOut.Play();            
        

        private void waveIn_DataAvailable(object sender, WaveInEventArgs e)
        
            waveProvider.Read(e.Buffer, 0, e.BytesRecorded);
        

        private void btnStop_Click(object sender, EventArgs e)
        
            waveIn.StopRecording();
            waveIn.Dispose();
        

        private void btnStart_Click(object sender, EventArgs e)
        
            waveIn.StartRecording();
        
    

我将在网络编程中使用这种场景,在该场景中,我将数据从麦克风发送到套接字,然后在客户端,BufferedWaveProvider 将读取数据,然后将其发送到扬声器。如果有更好的方法,请发表评论。

TIA

【问题讨论】:

您正在从 DataAvailable 事件中的错误流中读取数据。然后你什么也不用做。 您的 waveIn_DataAvailable 方法正在尝试从 waveProvider 读取而不是写入。将waveProvider.Read 更改为waveProvider.AddSamples,看看是否有帮助。此外,您对 waveIn 对象的初始化似乎并不完整……您还没有调用 waveIn.StartRecording 我在 btnStart_Click 事件上进行 StartRecording 延迟是 NAudio 的 WaveInWaveOut 类访问设备和数据的方式所固有的。 NAudio 并不是真正为低延迟而设计的,但您可以通过将waveIn.BufferedMilliseconds 设置为较低的值(例如10)和waveOut.DesiredLatency 设置为100 左右来减少它。如果您在DesiredLatency 上的设置太低,它会开始对您产生影响,所以请在此设置上放轻松。 @VincentDagpin NAudio 显然有一些压缩类可以使用 ACM 编解码器。我从来没有和他们一起玩过,但他们可能会给你一个合理的起点。 ACM 编解码器通常不能很好地处理低延迟的东西,因此请四处寻找一个好的音频压缩库,例如 github.com/JohnACarruthers/Opus.NET 【参考方案1】:

承诺的示例代码。代码用于具有两个按钮(名为 StartBtn 和 StopBtn)的表单。

public partial class Form1 : Form

    private WaveIn waveIn = null;
    private BufferedWaveProvider waveProvider = null;
    private WaveOut waveOut = null;

    public Form1()
    
        InitializeComponent();
    

    private void StartBtn_Click(object sender, EventArgs e)
    
        if (waveIn != null)
            return;

        // create wave input from mic
        waveIn = new WaveIn(this.Handle);
        waveIn.BufferMilliseconds = 25;
        waveIn.RecordingStopped += waveIn_RecordingStopped;
        waveIn.DataAvailable += waveIn_DataAvailable;

        // create wave provider
        waveProvider = new BufferedWaveProvider(waveIn.WaveFormat);

        // create wave output to speakers
        waveOut = new WaveOut();
        waveOut.DesiredLatency = 100;
        waveOut.Init(waveProvider);
        waveOut.PlaybackStopped += wavePlayer_PlaybackStopped;

        // start recording and playback
        waveIn.StartRecording();
        waveOut.Play();
    

    void waveIn_DataAvailable(object sender, WaveInEventArgs e)
    
        // add received data to waveProvider buffer
        if (waveProvider != null)
            waveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
    

    private void StopBtn_Click(object sender, EventArgs e)
    
        if (waveIn != null)
            waveIn.StopRecording();
    

    void waveIn_RecordingStopped(object sender, StoppedEventArgs e)
    
        // stop playback
        if (waveOut != null)
            waveOut.Stop();

        // dispose of wave input
        if (waveIn != null)
        
            waveIn.Dispose();
            waveIn = null;
        

        // drop wave provider
        waveProvider = null;
    

    void wavePlayer_PlaybackStopped(object sender, StoppedEventArgs e)
    
        // stop recording
        if (waveIn != null)
            waveIn.StopRecording();

        // dispose of wave output
        if (waveOut != null)
        
            waveOut.Dispose();
            waveOut = null;
        
    

特别注意waveIn.BufferMillisecondswaveOut.DesiredLatency 设置以减少延迟时间。

为了压缩网络传输的数据,我建议使用不同的库来处理数据块。您可能需要调整 BufferMilliseconds 值以减少开销并获得更好的压缩比。

Opus Codec 看起来是一个合理的选择,Opus.NET 用于 C#。

【讨论】:

哇... 2013 年回答!我的问题是,我们可以将 VST 插件应用到从麦克风“听到”的声音并在扬声器中播放吗?

以上是关于听到来自麦克风的传入音频的主要内容,如果未能解决你的问题,请参考以下文章

聆听来自多个麦克风的音频

iPhone 麦克风的硬件限制

iOS中的麦克风输入到扬声器输出?

QT 5.7 分析音频输出

来自麦克风的实时音频播放。 C#

处理来自移动麦克风的音频输入而不将其保存到文件中