Skip to content

Instantly share code, notes, and snippets.

@polson
Created September 22, 2025 17:45
Show Gist options
  • Save polson/f73a1110315ad849e07049facc2b28fc to your computer and use it in GitHub Desktop.
Save polson/f73a1110315ad849e07049facc2b28fc to your computer and use it in GitHub Desktop.
ManagedBass WASAPI input device monitoring example
using System;
using ManagedBass;
using ManagedBass.Fx;
using ManagedBass.Mix;
using ManagedBass.Wasapi;
class Program
{
private static int pushHandle = 0;
private static int mixer = 0;
private static int reverbHandle = 0;
private const int FREQUENCY = 48000;
private static readonly ReverbParameters REVERB_PARAMETERS = new()
{
fDryMix = 0.7f,
fWetMix = 0.4f,
fRoomSize = 0.5f,
fDamp = 0.6f
};
static void Main(string[] args)
{
try
{
if (!Bass.Init(Bass.NoSoundDevice, FREQUENCY, DeviceInitFlags.Default))
{
Console.WriteLine($"Failed to initialize BASS: {Bass.LastError}");
return;
}
var outputDeviceIndex = InitializeOutput();
var inputDeviceIndex = InitializeInput();
pushHandle = Bass.CreateStream(
FREQUENCY,
1,
BassFlags.Float | BassFlags.Decode,
StreamProcedureType.Push
);
mixer = BassMix.CreateMixerStream(
FREQUENCY,
2,
BassFlags.Float | BassFlags.Decode
);
BassMix.MixerAddChannel(mixer, pushHandle, BassFlags.MixerChanMatrix);
float[,] matrix = new float[2, 1] { { 1.0f }, { 1.0f } };
BassMix.ChannelSetMatrix(pushHandle, matrix);
Console.WriteLine(BassFx.Version);
reverbHandle = Bass.ChannelSetFX(mixer, EffectType.Freeverb, 1);
if (reverbHandle == 0)
{
Console.WriteLine($"Failed to add reverb effect: {Bass.LastError}");
}
else
{
if (!Bass.FXSetParameters(reverbHandle, REVERB_PARAMETERS))
{
Console.WriteLine($"Failed to set reverb parameters: {Bass.LastError}");
}
else
{
Console.WriteLine("Reverb effect added successfully!");
Console.WriteLine($" Dry Mix: {REVERB_PARAMETERS.fDryMix:F1}");
Console.WriteLine($" Wet Mix: {REVERB_PARAMETERS.fWetMix:F1}");
Console.WriteLine($" Room Size: {REVERB_PARAMETERS.fRoomSize:F1}");
Console.WriteLine($" Damping: {REVERB_PARAMETERS.fDamp:F1}");
}
}
BassWasapi.CurrentDevice = inputDeviceIndex;
BassWasapi.Start();
BassWasapi.CurrentDevice = outputDeviceIndex;
BassWasapi.Start();
Console.WriteLine("\nVocal monitoring with medium reverb is now active!");
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
Console.WriteLine("\nStopping monitoring...");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
BassWasapi.Free();
Bass.Free();
}
}
static int DefaultInputProcedure(IntPtr buffer, int length, IntPtr user)
{
return Math.Max(0, Bass.StreamPutData(pushHandle, buffer, length));
}
static int DefaultOutputProcedure(IntPtr buffer, int length, IntPtr user)
{
return Bass.ChannelGetData(mixer, buffer, length);
}
static int InitializeOutput()
{
var deviceIndex = 0;
String name = "Unknown";
for (int i = 0; i < BassWasapi.DeviceCount; i++)
{
var info = BassWasapi.GetDeviceInfo(i);
if (!info.IsInput && info.IsDefault)
{
name = info.Name;
deviceIndex = i;
break;
}
}
if (BassWasapi.Init(-1, FREQUENCY, 0, WasapiInitFlags.Exclusive | WasapiInitFlags.EventDriven | WasapiInitFlags.Raw, 0.00001f, 0, DefaultOutputProcedure, IntPtr.Zero))
{
var wasapiInfo = BassWasapi.Info;
Console.WriteLine("Initialized Output Device Format:");
Console.WriteLine($" ID: {deviceIndex}");
Console.WriteLine($" Name: {name}");
Console.WriteLine($" Sample Rate: {wasapiInfo.Frequency}Hz");
Console.WriteLine($" Channels: {wasapiInfo.Channels}");
Console.WriteLine($" Format: {GetFormatName(wasapiInfo.Format)}");
Console.WriteLine($" Buffer Length: {wasapiInfo.BufferLength}");
}
else
{
Console.WriteLine($"Failed to initialize WASAPI output device. Error: {Bass.LastError}");
}
return deviceIndex;
}
static int InitializeInput()
{
var deviceIndex = 0;
String name = "Unknown";
for (int i = 0; i < BassWasapi.DeviceCount; i++)
{
var info = BassWasapi.GetDeviceInfo(i);
if (info.IsInput && info.IsDefault)
{
name = info.Name;
deviceIndex = i;
break;
}
}
if (BassWasapi.Init(-2, FREQUENCY, 0, WasapiInitFlags.Exclusive | WasapiInitFlags.EventDriven | WasapiInitFlags.Raw, 0.00001f, 0, DefaultInputProcedure, IntPtr.Zero))
{
var wasapiInfo = BassWasapi.Info;
Console.WriteLine("Initialized Input Device Format:");
Console.WriteLine($" ID: {deviceIndex}");
Console.WriteLine($" Name: {name}");
Console.WriteLine($" Sample Rate: {wasapiInfo.Frequency}Hz");
Console.WriteLine($" Channels: {wasapiInfo.Channels}");
Console.WriteLine($" Format: {GetFormatName(wasapiInfo.Format)}");
Console.WriteLine($" Buffer Length: {wasapiInfo.BufferLength}");
}
else
{
Console.WriteLine($"Failed to initialize WASAPI input device. Error: {Bass.LastError}");
}
return deviceIndex;
}
static string GetFormatName(WasapiFormat format)
{
return format switch
{
WasapiFormat.Float => "32-bit Float",
WasapiFormat.Bit8 => "8-bit PCM",
WasapiFormat.Bit16 => "16-bit PCM",
WasapiFormat.Bit24 => "24-bit PCM",
WasapiFormat.Bit32 => "32-bit PCM",
WasapiFormat.Unknown => "Unknown",
_ => format.ToString()
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment