Reputation: 1
I am recording an audio to send it to send it to Google speech to text but when I make the audio with naudio it records me only 5 seconds and from there it stops recording. I copy the code in C #, this is my first time using this API, but I don't know why it cuts me, if it should stop recording when I press the save button, the application is a simple form with 2 buttons, one for recording and the other for stop.
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private BufferedWaveProvider bwp;
WaveIn waveIn;
WaveOut waveOut;
WaveFileWriter writer;
WaveFileReader reader;
string output = "audio.raw";
public Form1()
{
InitializeComponent();
waveOut = new WaveOut();
waveIn = new WaveIn();
waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
waveIn.WaveFormat = new NAudio.Wave.WaveFormat(16000, 1);
bwp = new BufferedWaveProvider(waveIn.WaveFormat);
bwp.DiscardOnBufferOverflow = true;
btnRecordVoice.Enabled = true;
btnSave.Enabled = false;
//btnSpeechInfo.Enabled = false;
}
private void btnRecordVoice_Click(object sender, EventArgs e)
{
if (NAudio.Wave.WaveIn.DeviceCount < 1)
{
Console.WriteLine("No se encuentra un microfono!");
return;
}
waveIn.StartRecording();
btnRecordVoice.Enabled = false;
btnSave.Enabled = true;
}
private void btnSave_Click(object sender, EventArgs e)
{
waveIn.StopRecording();
if (File.Exists("audio.raw"))
File.Delete("audio.raw");
writer = new WaveFileWriter(output, waveIn.WaveFormat);
btnRecordVoice.Enabled = false;
btnSave.Enabled = false;
byte[] buffer = new byte[bwp.BufferLength];
int offset = 0;
int count = bwp.BufferLength;
var read = bwp.Read(buffer, offset, count);
if (count > 0)
{
writer.Write(buffer, offset, read);
}
waveIn.Dispose();
waveIn = null;
writer.Close();
writer = null;
reader = new WaveFileReader("audio.raw"); // (new MemoryStream(bytes));
waveOut.Init(reader);
waveOut.PlaybackStopped += new EventHandler<StoppedEventArgs>(waveOut_PlaybackStopped);
waveOut.Play();
}
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
bwp.AddSamples(e.Buffer, 0, e.BytesRecorded);
}
private void waveOut_PlaybackStopped(object sender, StoppedEventArgs e)
{
waveOut.Stop();
reader.Close();
reader = null;
}
}
}
Upvotes: 0
Views: 473
Reputation: 16596
You get a 5-second audio clip not only because you do a one-time BufferLength
read from the BufferedWaveProvider
...
int count = bwp.BufferLength;
var read = bwp.Read(buffer, offset, count);
...and 5 seconds is the default value of that property, but because BufferedWaveProvider
uses a circular buffer, so BufferLength
is all the data it has available.
What worked for me was to skip the BufferedWaveProvider
and write new data to the WaveFileWriter
as soon as it becomes available...
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
writer.Write(e.Buffer, 0, e.BytesRecorded);
}
To support that change, the button event handlers get changed to the following...
private void btnRecordVoice_Click(object sender, EventArgs e)
{
if (NAudio.Wave.WaveIn.DeviceCount < 1)
{
Console.WriteLine("No se encuentra un microfono!");
return;
}
writer = new WaveFileWriter(output, waveIn.WaveFormat);
waveIn.StartRecording();
btnRecordVoice.Enabled = false;
btnSave.Enabled = true;
}
private void btnSave_Click(object sender, EventArgs e)
{
waveIn.StopRecording();
writer.Close();
writer = null;
btnRecordVoice.Enabled = false;
btnSave.Enabled = false;
reader = new WaveFileReader("audio.raw"); // (new MemoryStream(bytes));
waveOut.Init(reader);
waveOut.PlaybackStopped += new EventHandler<StoppedEventArgs>(waveOut_PlaybackStopped);
waveOut.Play();
}
This appears to be the same approach used in Recording a WAV file in a WinForms app with WaveIn.
Upvotes: 1