5

I am able to capture system audio which is generated by speaker with the help of WasapiLoopbackCapture (naudio). but the problem is it capture wav file and size of wav file very large (almost 10 to 15 MB/Min). I have to capture 2-3 hour audio and this will be too high. I m looking for a solution that will convert wav stream which is capture by WasapiLoopbackCapture convert to MP3 and then save this to disk. I try a loat with LAME.exe or other solution but not get success. Any working code.

Here is My Code:

private void button1_Click(object sender, EventArgs e){
    LoopbackRecorder obj = new LoopbackRecorder();
    string a = textBox1.Text;
    obj.StartRecording(@"e:\aman.mp3");

}

public class LoopbackRecorder
{
    private IWaveIn _waveIn;
    private Mp3WaveFormat _mp3format;
    private WaveFormat _wavFormat;


    private WaveFileWriter _writer;
    private bool _isRecording = false;


    /// <summary>
    /// Constructor
    /// </summary>
    public LoopbackRecorder()
    {

    }

    /// <summary>
    /// Starts the recording.
    /// </summary>
    /// <param name="fileName"></param>
    public void StartRecording(string fileName)
    {
        // If we are currently record then go ahead and exit out.
        if (_isRecording == true)
        {
            return;
        }

        _fileName = fileName;
        _waveIn = new WasapiLoopbackCapture();
       // _waveIn.WaveFormat = new WaveFormat(16000, 16 , 2);
        _writer = new WaveFileWriter(fileName, _waveIn.WaveFormat);

        _waveIn.DataAvailable += OnDataAvailable;
      //  _waveIn.RecordingStopped += OnRecordingStopped;
        _waveIn.StartRecording();
        _isRecording = true;
    }




    private void OnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
    {
        if (_writer == null)
        {
            _writer = new WaveFileWriter(@"e:\aman.mp3", _waveIn.WaveFormat);
        }

        _writer.Write(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);

      byte[] by=  Float32toInt16(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);

    }

    private string _fileName = "";
    /// <summary>
    /// The name of the file that was set when StartRecording was called.  E.g. the current file being written to.
    /// </summary>
    public string FileName
    {
        get
        {
            return _fileName;
        }
    }
}
puretppc
  • 3,232
  • 8
  • 38
  • 65
Aman Sharma
  • 311
  • 1
  • 8
  • 22

2 Answers2

7

Here's an example of using NAudio.Lame (in a console application) to capture data from sound card loopback and write direct to an MP3 file:

using System;
using NAudio.Lame;
using NAudio.Wave;

namespace MP3Rec
{
    class Program
    {
        static LameMP3FileWriter wri;
        static bool stopped = false;

        static void Main(string[] args)
        {
            // Start recording from loopback
            IWaveIn waveIn = new WasapiLoopbackCapture();
            waveIn.DataAvailable += waveIn_DataAvailable;
            waveIn.RecordingStopped += waveIn_RecordingStopped;
            // Setup MP3 writer to output at 32kbit/sec (~2 minutes per MB)
            wri = new LameMP3FileWriter( @"C:\temp\test_output.mp3", waveIn.WaveFormat, 32 );
            waveIn.StartRecording();

            stopped = false;

            // Keep recording until Escape key pressed
            while (!stopped)
            {
                if (Console.KeyAvailable)
                {
                    var key = Console.ReadKey(true);
                    if (key != null && key.Key == ConsoleKey.Escape)
                        waveIn.StopRecording();
                }
                else
                    System.Threading.Thread.Sleep(50);
            }

            // flush output to finish MP3 file correctly
            wri.Flush();
            // Dispose of objects
            waveIn.Dispose();
            wri.Dispose();
        }

        static void waveIn_RecordingStopped(object sender, StoppedEventArgs e)
        {
            // signal that recording has finished
            stopped = true;
        }

        static void waveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            // write recorded data to MP3 writer
            if (wri != null)
                wri.Write(e.Buffer, 0, e.BytesRecorded);
        }
    }
}

At the moment the NAudio.Lame package on NuGet is compiled for x86 only, so make sure your application is set to target that platform.

jishi
  • 24,126
  • 6
  • 49
  • 75
Corey
  • 15,524
  • 2
  • 35
  • 68
  • Hi I am unable to add using NAudio.Lame; in my project I try to add lame_enc.dll its also not adding to my project could you pls tell me how to add this name space in my project. – Aman Sharma Nov 06 '13 at 07:49
  • 1
    Hi no I am able to add ref of naudio.lame to my project by now its showing error "Cannot use local variable 'waveIn' before it is declared" . I try it like this // Start recording from loopback IWaveIn waveIn = new WasapiLoopbackCapture(); wri = new LameMP3FileWriter(@"C:\temp\test_output.mp3", waveIn.WaveFormat,128); waveIn.DataAvailable += waveIn_DataAvailable; waveIn.RecordingStopped += waveIn_RecordingStopped; waveIn.StartRecording(); stopped = false; but it still showing error :-Unsupported encoding format Extensible – Aman Sharma Nov 06 '13 at 11:38
  • Hi Cory thanks its working for me now . yes its showing error on 64 bit based machines . Any workaround to solve this problem. – Aman Sharma Nov 06 '13 at 12:57
  • I'll have to do 32-bit and 64-bit packages eventually, I guess. For the moment, grab the source from GitHub and compile for whichever platform, then add the 64- or 32-bit version of libmp3lame.dll. – Corey Nov 07 '13 at 22:38
  • I've just put a pre-release version on NuGet. It auto-selects the correct DLL based on which bit width the program is currently running. Should work for all platform targets (x86, x64 and AnyCPU) out of the box. Try it out (select `Include prerelease` in the NuGet window) and let me know if it works for you. – Corey Nov 08 '13 at 14:57
  • Just tried this but the audio quality comes out very bad – TomSelleck Jan 16 '21 at 11:23
  • Increasing the bitrate fixed the issue, thanks. – TomSelleck Jan 16 '21 at 11:33
1

To convert the audio to MP3 on the fly, one of the easiest ways is to use the command line options that let you pass audio into LAME.exe via stdin. I describe how to do that in this article.

You may also be interested that Corey Murtagh has created a LAME package for NAudio. I haven't tried it myself, but it looks like it should also do the job. Documentation is here.

Mark Heath
  • 48,273
  • 29
  • 137
  • 194
  • 1
    Hey, my first plug :P – Corey Nov 06 '13 at 06:11
  • HI I m trying to use this code but not get success (copy from the article provided by you) string outputFileName = @"c:\users\mark\documents\test.mp3"; Process p = new Process(); p.StartInfo.FileName = @"lame.exe"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.Arguments = "-r -s 16 -m m - \"" + outputFileName + "\""; p.StartInfo.CreateNoWindow = true; p.Start(); // now write your raw PCM audio into the standard input stream and close it when you are done p.StandardInput.BaseStream; – Aman Sharma Nov 06 '13 at 07:07