#c# #record #naudio
#c# #запись #naudio
Вопрос:
Я хочу создать синусоидальный сигнал, воспроизвести его с помощью динамика, принять его с помощью микрофона, а затем записать.
Я пытался создать несколько программ для достижения этого, как показано ниже, но возникают некоторые проблемы.
Генерировать синусоидальный сигнал -> Динамик -> МИКРОФОН -> Запись (волна)
1) Выход сигнала: я использовал два выхода сигнала.
a) Для генерации сигнала
б) Записать файл wave. Создает ли это проблему?
2) Эхо-звук :
a) Наушники :
Если я использую наушники, я могу слышать чистый синусоидальный звук. Но микрофон не слышит этот звук. и тогда он просто запишет звук окружающей среды.
б) Динамик :
Если я использую динамик (ту же линию наушников, я просто добавляю усилитель и динамик), я могу слышать эхо-звук, как показано на рисунке ниже. И микрофон также записывает этот эхо-звук. Я могу предположить, что микрофон получил этот звук, и через несколько миллисекунд динамик добавляет этот звук к исходному звуку. Но я не могу понять, почему динамик добавляет этот принятый звук. Как я могу записывать без эхо-звука?
3) Время записи :
Я хочу записать 2 секунды. Затем я использовал timer и определил timer.Интервал = 2 секунды. Но реальное время записи превышает 2 секунды. некоторая задержка?
4) Время развертки :
Я определил время развертки в 2 секунды. Но в течение более чем 2 секунд синусоидальная развертка не завершена. Во время завершения (около 2,2 секунды) частота составляет 1,5 кГц. (Я определил конечную частоту = 2 кГц).
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 amp; record
recorder.StartRecording();
timer1.Enabled = true;
// begin playback amp; 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. Пометка на потом. Когда я вернусь домой, я поделюсь своим решением
Ответ №1:
Я снова изучил NAudio. ( https://www.pluralsight.com/courses/audio-programming-naudio / ) И я получил решение, как показано ниже.
Моя цель: генерировать синусоидальный сигнал -> Динамик -> МИКРОФОН -> Запись (волна)
используя это, я хочу дополнительно проанализировать состояние динамика с помощью FFT.
- Генерировать синусоидальный сигнал:NAudio.Wave.SamplePrividers.SignalGenerator
- Выход динамика: NAudio.Wave.WaveOut
- Микрофон: NAudio.Wave.WaveIn
- Запись (волна): 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();
}
}
}