I have the following code to record audio in and out
using System;
using System.Diagnostics;
using System.IO;
using NAudio.Wave;
using Yeti.MMedia.Mp3;
namespace SoundRecording
{
public class SoundManager
{
private WaveInEvent _waveIn;
private WaveFileWriter _waveInFile;
private WasapiLoopbackCapture _waveOut;
private WaveFileWriter _waveOutFile;
private Process _lameProcess;
public void StartRecording()
{
InitLame();
DateTime dtNow = DateTime.Now;
try
{
InitAudioOut(dtNow);
}
catch
{
}
try
{
InitAudioIn(dtNow);
}
catch
{
}
}
private void InitLame()
{
string outputFileName = @"c:\Rec\test.mp3";
_lameProcess = new Process();
_lameProcess.StartInfo.FileName = @"lame.exe";
_lameProcess.StartInfo.UseShellExecute = false;
_lameProcess.StartInfo.RedirectStandardInput = true;
_lameProcess.StartInfo.Arguments = "-r -s 44.1 -h -b 256 --bitwidth 32 - \"" + outputFileName + "\"";
_lameProcess.StartInfo.CreateNoWindow = true;
_lameProcess.Start();
}
private void InitAudioIn(DateTime dtNow)
{
string pathIn = @"C:\Rec\(" + dtNow.ToString("HH-mm-ss") + " " + dtNow.ToString("dd-MM-yyyy") + " IN).wav";
_waveIn = new WaveInEvent();
_waveIn.WaveFormat = new WaveFormat(8000, 1);
_waveIn.DataAvailable += WaveInDataAvailable;
_waveIn.RecordingStopped += WaveInRecordStopped;
_waveInFile = new WaveFileWriter(pathIn, _waveIn.WaveFormat);
_waveIn.StartRecording();
}
private void InitAudioOut(DateTime recordMarker)
{
string pathOut = @"C:\Rec\(" + recordMarker.ToString("HH-mm-ss") + " " + recordMarker.ToString("dd-MM-yyyy") + " OUT).mp3";
_waveOut = new WasapiLoopbackCapture();
//_waveOut.WaveFormat = new WaveFormat(44100, 1);
_waveOut.DataAvailable += WaveOutDataAvailable;
_waveOut.RecordingStopped += WaveOutRecordStopped;
_waveOutFile = new WaveFileWriter(pathOut, new Mp3WaveFormat(_waveOut.WaveFormat.SampleRate, _waveOut.WaveFormat.Channels, 0, 128));
_waveOut.StartRecording();
}
private void WaveInDataAvailable(object sender, WaveInEventArgs e)
{
if (_waveInFile != null)
{
_waveInFile.Write(e.Buffer, 0, e.BytesRecorded);
_waveInFile.Flush();
}
}
private void WaveOutDataAvailable(object sender, WaveInEventArgs e)
{
if (_waveInFile != null)
{
using (var memStream = new MemoryStream(e.Buffer))
{
using (WaveStream wStream = new RawSourceWaveStream(memStream, _waveOut.WaveFormat))
{
var format = new WaveFormat(_waveOut.WaveFormat.SampleRate, _waveOut.WaveFormat.Channels);
var transcodedStream = new ResamplerDmoStream(wStream, format);
var read = (int)transcodedStream.Length;
var bytes = new byte[read];
transcodedStream.Read(bytes, 0, read);
var fmt = new WaveLib.WaveFormat(transcodedStream.WaveFormat.SampleRate, transcodedStream.WaveFormat.BitsPerSample, transcodedStream.WaveFormat.Channels);
var beconf = new Yeti.Lame.BE_CONFIG(fmt, 128);
// Encode WAV to MP3
byte[] mp3Data;
using (var mp3Stream = new MemoryStream())
{
using (var mp3Writer = new Mp3Writer(mp3Stream, fmt, beconf))
{
int blen = transcodedStream.WaveFormat.AverageBytesPerSecond;
mp3Writer.Write(bytes, 0, read);
mp3Data = mp3Stream.ToArray();
}
}
_waveOutFile.Write(mp3Data, 0, mp3Data.Length);
_waveOutFile.Flush();
}
}
}
}
private byte[] WavBytesToMp3Bytes(IWaveProvider waveStream, uint bitrate = 128)
{
// Setup encoder configuration
var fmt = new WaveLib.WaveFormat(waveStream.WaveFormat.SampleRate, waveStream.WaveFormat.BitsPerSample, waveStream.WaveFormat.Channels);
var beconf = new Yeti.Lame.BE_CONFIG(fmt, bitrate);
// Encode WAV to MP3
int blen = waveStream.WaveFormat.AverageBytesPerSecond;
var buffer = new byte[blen];
byte[] mp3Data = null;
using (var mp3Stream = new MemoryStream())
{
using (var mp3Writer = new Mp3Writer(mp3Stream, fmt, beconf))
{
int readCount;
while ((readCount = waveStream.Read(buffer, 0, blen)) > 0)
{
mp3Writer.Write(buffer, 0, readCount);
}
mp3Data = mp3Stream.ToArray();
}
}
return mp3Data;
}
private void WaveInRecordStopped(object sender, StoppedEventArgs e)
{
if (_waveIn != null)
{
_waveIn.Dispose();
_waveIn = null;
}
if (_waveInFile != null)
{
_waveInFile.Dispose();
_waveInFile = null;
}
_lameProcess.StandardInput.BaseStream.Close();
_lameProcess.StandardInput.BaseStream.Dispose();
_lameProcess.Close();
_lameProcess.Dispose();
}
private void WaveOutRecordStopped(object sender, StoppedEventArgs e)
{
if (_waveOutFile != null)
{
_waveOutFile.Close();
_waveOutFile = null;
}
_waveOut = null;
}
public void StopRecording()
{
try
{
_waveIn.StopRecording();
}
catch
{
}
try
{
_waveOut.StopRecording();
}
catch
{
}
}
}
}
I'm using NAudio to capture audio in/out and yetis' lame wrapper to convert it to mp3 file on the fly, the problem is that the resulting audio out file is corrupted and unreadable, probably, missing mp3 headers or something other that i've missed...