如何同时生成信号和NAudio录音?

时间:2019-03-08 03:27:40

标签: c# record naudio

我想制作一个正弦信号,用扬声器播放,用MIC接收,然后录制。

我试图制作一些程序来实现以下目的,但是会出现一些问题。

生成正弦信号->扬声器-> MIC->录制(波形)

1)WaveOut:  我用了两个WaveOut。

a)生成信号

b)录制波形文件。  这有问题吗?

2)回声:

a)耳机:

如果使用耳机,我可以听到纯正弦扫频声音。但是MIC听不到这种声音。然后它将只录制环境声音。

b)发言人:

如果使用扬声器(相同的耳机线,只需添加放大器和扬声器),就可以听到回声,如下图所示。 MIC也会记录此回声。   我猜想MIC会收到此声音,并且在几毫秒后,扬声器会在原始声音上添加此声音。但我不明白为什么发言人添加了此声音。如何录制没有回声的声音?

3)录制时间:

我想记录2秒。然后我使用了计时器并定义了timer.Interval = 2秒。   但是实际记录时间超过2秒。一些延迟?

4)扫描时间:

我定义了2秒的扫描时间。但是在2秒钟内,正弦扫描未完成。结束时间(约2.2秒),频率为1.5kHz。 (我定义了结束频率  = 2kHz)。

Recorded Echo Wave file

public partial class Form1 : Form
{
    private WaveIn recorder;
    private BufferedWaveProvider bufferedWaveProvider;
    private SavingWaveProvider savingWaveProvider;
    private WaveOut player;

    private WaveOut player_sweep;   // 190305

    public Form1()
    {
        InitializeComponent();
    }

    private void OnStartRecording_Click(object sender, EventArgs e)
    {
        // set up the recorder
        recorder = new WaveIn();
        recorder.DataAvailable += RecorderOnDataAvailable;

        // set up our signal chain
        bufferedWaveProvider = new BufferedWaveProvider(recorder.WaveFormat);
        savingWaveProvider = new SavingWaveProvider(bufferedWaveProvider, "temp.wav");

        // set up playback
        player = new WaveOut();
        player.Init(savingWaveProvider);

        // 190305   / Signal Generator : Sine 50~2000 Hz, 2 sec
        SignalGenerator sweep_out = new SignalGenerator();
        sweep_out.Gain = 1;
        sweep_out.Frequency = 50;
        sweep_out.FrequencyEnd = 2000;
        sweep_out.SweepLengthSecs = 2;
        sweep_out.Type = SignalGeneratorType.Sweep;

        player_sweep = new WaveOut();   // 190305
        player_sweep.Init(sweep_out); // 190305

        // begin playback & record
        recorder.StartRecording();

        timer1.Enabled = true;

        // begin playback & record
        player.Play();      // Start Recording

        player_sweep.Play();    // 190305
    }

    private void RecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
    {
        bufferedWaveProvider.AddSamples(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);
    }

    private void timer1_Tick(object sender, EventArgs e)    // 190305
    {
        timer1.Enabled = false;

        player_sweep.Stop();    // 190305

        // stop playback
        player.Stop();

        // stop recording
        recorder.StopRecording();


        // finalise the WAV file
        savingWaveProvider.Dispose();

    }
}

1 个答案:

答案 0 :(得分:0)

我再次学习了NAudio。 (https://www.pluralsight.com/courses/audio-programming-naudio/) 我得到了如下解决方案。

我的目标:生成正弦信号->扬声器-> MIC->录制(波形)

使用此功能,我想另外使用FFT分析扬声器条件。

  1. 生成正弦信号:NAudio.Wave.SamplePrividers.SignalGenerator
  2. 扬声器输出:NAudio.Wave.WaveOut
  3. 麦克风:NAudio.Wave.WaveIn
  4. 记录(wave):NAudio.Wave.WaveFileWriter

//源代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Diagnostics;   // for Process, Stopwatch
using NAudio.Wave;    // for WaveOut, WaveIn
using NAudio.Wave.SampleProviders;  // for SignalGenerator

namespace Speaker_Record-Wave
{
    public partial class Form1 : Form
    {
        // 0) StopWatch
        Stopwatch stopWatch;

        // 1) Signal Gen -> Speaker
        WaveOut waveOut;
        SignalGenerator signalGenerator;

        // 2) MIC -> Wave
        WaveIn waveIn;
        WaveFileWriter waveFileWriter;

        public Form1()
        {
            InitializeComponent();
        }

        private void bt_Start_Click(object sender, EventArgs e)
        {
            // 0) StopWatch
            stopWatch = new Stopwatch();
            stopWatch.Start();

            // 1) Signal Gen -> Speaker
            Start_Signal();

            // 3) Timer_Sweep
            timer_Sweep.Interval = 1500;
            timer_Sweep.Enabled = true;

            // 2) MIC -> Wave
            Start_Record();
        }

        private void timer_Sweep_Tick(object sender, EventArgs e)
        {
            // 3) Timer_Sweep
            timer_Sweep.Enabled = false;

            // 1) Signal Gen -> Speaker
            waveOut.Stop();

            // 2) MIC -> Wave
            waveIn.StopRecording();

            // 4) 공통
            waveOut.Dispose();
            waveIn.Dispose();
            waveFileWriter.Dispose();

            // 0) StopWatch
            stopWatch.Stop();
            TimeSpan ts = stopWatch.Elapsed;
            string es = String.Format("{0:00}:{1:00}:{2:00}:{3:00}",ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            tb_Result.AppendText(es + "\n");
        }

        private void bt_Open_Folder_Click(object sender, EventArgs e)
        {
            Process.Start(".\\");   // Open Folder
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////

        // 1) Signal Gen -> Speaker
        private void Start_Signal()
        {
            signalGenerator = new SignalGenerator();
            signalGenerator.Type = SignalGeneratorType.Sweep;
            signalGenerator.Frequency = 50;
            signalGenerator.FrequencyEnd = 5000;
            signalGenerator.SweepLengthSecs = 1.5;

            waveOut = new WaveOut();
            waveOut.DeviceNumber = 0;
            waveOut.Init(signalGenerator);
            waveOut.Play();
        }

        // 2) MIC -> Wave
        private void Start_Record()
        {
            waveIn = new WaveIn();
            waveIn.DeviceNumber = 0;
            waveIn.WaveFormat = new WaveFormat(44100, 16, 1);

            waveIn.DataAvailable += OnDataAvailable;
            waveIn.RecordingStopped += OnRecordingStopped;

            waveFileWriter = new WaveFileWriter("1_Recorded.wav", waveIn.WaveFormat);

            waveIn.StartRecording();
        }

        // 2) MIC -> Wave
        private void OnDataAvailable(object sender, WaveInEventArgs e)
        {
            if (waveFileWriter != null)
            {
                waveFileWriter.Write(e.Buffer, 0, e.BytesRecorded);
            }
        }

        // 2) MIC -> Wave
        private void OnRecordingStopped(object sender, StoppedEventArgs e)
        {
            waveIn.Dispose();
            waveFileWriter.Dispose();
        }
    }
}