This project has moved. For the latest updates, please go here.

WASAPI loopback recording

Nov 13, 2009 at 11:05 AM
Edited Nov 13, 2009 at 11:10 AM

Hello!

Is there any source snippet that shows how to record from WASAPI loopback to file or stream?

Nov 13, 2009 at 12:11 PM
Edited Nov 13, 2009 at 12:12 PM

Okay, I wrote sample application. Here is it: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAudio.CoreAudioApi;
using NAudio;
using NAudio.Wave;

namespace SampleApp
{
    class Program
    {
        //Stops application and recording when key was pressed
        static volatile bool stop = false;
   
        //Thread handler
        static void KeyGet()
        {
            Console.ReadKey();
            stop = true;
        }

        static void Main(string[] args)
        {
            System.Threading.Thread Thread = new System.Threading.Thread(KeyGet);
            Thread.Start();

            //Default render endpoint
            MMDevice DefaultDevice = new MMDeviceEnumerator().GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
            Console.WriteLine("Default renderer: {1:S} ({0:S})", DefaultDevice.Properties[2].Value, DefaultDevice.FriendlyName);
        
            //Device updating period and aligning
            int UpdatePeriod = (int)DefaultDevice.AudioClient.DefaultDevicePeriod;
            int BlockAlign = DefaultDevice.AudioClient.MixFormat.BlockAlign;

            WaveFileWriter Output = new WaveFileWriter(@"C:\Users\Din\Desktop\sample.wav", DefaultDevice.AudioClient.MixFormat);

            //Initializes client
            DefaultDevice.AudioClient.Initialize(AudioClientShareMode.Shared, AudioClientStreamFlags.Loopback, 0, 0, DefaultDevice.AudioClient.MixFormat, Guid.Empty);
            DefaultDevice.AudioClient.Start();

            while (true)
            {
                if (DefaultDevice.AudioClient.AudioCaptureClient.GetNextPacketSize() != 0)
                {
                    //Reads data
                    int FramesToRead;
                    AudioClientBufferFlags BufferFlags;
                    IntPtr Data = DefaultDevice.AudioClient.AudioCaptureClient.GetBuffer(out FramesToRead, out BufferFlags);
                    byte[] ReadData = new byte[FramesToRead * BlockAlign];

                    System.Runtime.InteropServices.Marshal.Copy(Data, ReadData, 0, FramesToRead * BlockAlign);

                    try
                    {
                        Output.WriteData(ReadData, 0, FramesToRead * BlockAlign);
                    }
                    catch (Exception Exception)
                    {
                        Console.WriteLine("Wrong: {0:S}", Exception.Message);
                    }

                    //Debug
                    Console.WriteLine("{0:D} frames ({1:S})", FramesToRead, BufferFlags.ToString());

                    //Releases buffer
                    DefaultDevice.AudioClient.AudioCaptureClient.ReleaseBuffer(FramesToRead);
                }
                else
                {
                    Console.WriteLine("Waiting for data");
                }

                if (stop == true)
                {
                    Console.WriteLine("Output was closed");
                    Output.Close();
                    break;
                }

                System.Threading.Thread.Sleep(UpdatePeriod / 2 / 10000);
            }
        }
    }
}

Something wrong/bad? 
Now it's time to convert stream to another format...