Click here to Skip to main content
Click here to Skip to main content
Go to top

Audio Library Part I - (Windows Mixer Control)

, 1 Oct 2006
Rate this:
Please Sign up or sign in to vote.
Library to control Windows Mixer from C#
Sample Image - AudioLib.jpg

Introduction

In this article, I'll show you how to use Windows Mixer from C#.

For some time, I was trying to get information about how to program the mixer from C#. I didn't have too much luck, and the few examples found were in C++, so… I took the hard and fun way... doing it myself.

This library is part of my Audio library to control Wave Audio (Playback/Recording), Mixer, Playback/Recording compressed files using ACM, basic speech recognition and some other stuff that I'll be releasing in future articles.

AudioMixer Namespace

Hierarchical Objects View

Sample screenshot

The hierarchical view shows how the classes are organized.

The main object Mixers contains two Mixer objects, Playback and Recording; those will work with default devices, but can be changed by setting the property Mixers.Playback.DeviceId or Mixers.Recording.DeviceId.

I made it as simple as possible by hiding all the flat Win32 API implementation from the developer and creating a hierarchical set of objects.

Every mixer is autonomous, meaning you can have Playback mixer set to one soundcard and Recording mixer to another one. Also each one contains two arrays or MixerLines (Lines, UserLines).

Lines object will contain all lines inside the mixer, for example all the lines that don't have controls associated with it or lines that are not source lines.

UserLines will contains all lines that the developer can interact with, having controls like Volume, Mute, Fadder, Bass, etc. (basically it is the same as Lines object but a filter was applied to it).

Every Line will contain a collection of controls, like Mute, Volume, Bass, Fader, etc.

If you are interested in knowing more about how Windows Mixer works, here is an excellent link with all the information about it.

Let's See Some Code

To Get the Audio Devices in the Computer

foreach(MixerDetail mixerDetail in mMixers.Devices)
{
    ...
    ...
}

To Get the Input Devices

foreach(MixerDetail mixerDetail in mMixers.Recording.Devices)
{
    ...
    ...
}

Change Output Mixer Device

Mixers mixers = new Mixers();
foreach(MixerDetail mixerDetail in mixers.Playback.Devices)
{
    if (mixerDetail.MixerName == "Sound Blaster Live")
        mixers.Playback.DeviceId = mixerDetail.DeviceId;
}

Change Output Mixer Device to the Default Device

Mixers mixers = new Mixers();
mixers.Playback.DeviceId = -1;

or

mixers.Playback.DeviceId = mixers.Playback.DeviceIdDefault;

Getting Playback Speaker Master Volume

mixers.Playback.Lines.GetMixerFirstLineByComponentType(
    MIXERLINE_COMPONENTTYPE.DST_SPEAKERS).Volume;

Setting Playback Speaker Master Volume for the Left Channel Only

MixerLine line = mixers.Playback.Lines.GetMixerFirstLineByComponentType(
    MIXERLINE_COMPONENTTYPE.DST_SPEAKERS);
line.Channel = Channel.Left;
line.Volume = 32000;

Selecting Microphone as Default Input

mixers.Recording.Lines.GetMixerFirstLineByComponentType(
    MIXERLINE_COMPONENTTYPE.SRC_MICROPHONE).Selected = true; 

Getting Callback Notifications When a Line has Changed

/* Initialization */
mMixers = new Mixers();
mMixers.Playback.MixerLineChanged +=
    new WaveLib.AudioMixer.Mixer.MixerLineChangeHandler(mMixer_MixerLineChanged);
mMixers.Recording.MixerLineChanged +=
    new WaveLib.AudioMixer.Mixer.MixerLineChangeHandler(mMixer_MixerLineChanged);
/* Events */
private void mMixer_MixerLineChanged(Mixer mixer, MixerLine line)
{
    Console.WriteLine("Mixer: " + mixer.DeviceDetail.MixerName);
    Console.WriteLine("Mixer Type: " + mixer.MixerType);
    Console.WriteLine("Mixer Line: " + line.Name);
}

Getting and Setting Rare Controls

Specific controls like Fadder, Microphone Boost, bass, treble, etc. can be accessed via the MixerControl object using ValueAsSigned, ValueAsUnsigned and ValueAsBoolean properties, but they are not implemented as standard properties because they don't belong to all controls.

x86 vs x64

Finally I got a core 2 duo and now I could compile the library under x86 and x64. At first I thought there won't be too much difference, but the big problem is that the IntPtr pointers are platform specific, so whereas a x86 takes 4 bytes, a x64 takes 8 bytes, that makes things really messy and there is no simple fix in some cases, for example in the following struct I could not find a way to make it work for x86 and x64 in C#. Looks like the .NET Framework is missing something to work with unions inside structs... I had to declare two structs and work with them separately.

Before

 [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)]
 public struct MIXERCONTROLDETAILS
 {
  [FieldOffset(0)] public UInt32  cbStruct;
  [FieldOffset(4)] public UInt32  dwControlID;
  [FieldOffset(8)] public UInt32  cChannels;
  /* Union start */
  [FieldOffset(12)] public IntPtr hwndOwner;
  [FieldOffset(12)] public UInt32 cMultipleItems;
  /* Union end */
  [FieldOffset(16)] public UInt32 cbDetails;
  [FieldOffset(20)] public IntPtr paDetails;
 }

After

 [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 2)]
 public struct MIXERCONTROLDETAILS
 {
  [FieldOffset(0)]  public UInt32 cbStruct;
  [FieldOffset(4)]  public UInt32 dwControlID;
  [FieldOffset(8)]  public UInt32 cChannels;
  /* Union start */
  [FieldOffset(12)] public IntPtr hwndOwner;
  [FieldOffset(12)] public UInt32 cMultipleItems;
  /* Union end */
  [FieldOffset(16)] public UInt32 cbDetails;
  [FieldOffset(20)] public IntPtr paDetails;
 }
 [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 2)]
 public struct MIXERCONTROLDETAILS64
 {
  [FieldOffset(0)] public UInt32  cbStruct;
  [FieldOffset(4)] public UInt32  dwControlID;
  [FieldOffset(8)] public UInt32  cChannels;
  /* Union start */
  [FieldOffset(12)] public IntPtr hwndOwner;
  [FieldOffset(12)] public UInt32 cMultipleItems;
  /* Union end */
  [FieldOffset(20)] public UInt32 cbDetails;
  [FieldOffset(24)] public IntPtr paDetails;
 }

I was hoping to declare a dynamic size for the FieldOffset and then I could have fixed the problem but it doesn't compile on .NET.

 [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 2)]
 public struct MIXERCONTROLDETAILS
 {
  [FieldOffset(0)] public UInt32  cbStruct;
  [FieldOffset(4)] public UInt32  dwControlID;
  [FieldOffset(8)] public UInt32  cChannels;
  /* Union start */
  [FieldOffset(12)] public IntPtr hwndOwner;
  [FieldOffset(12)] public UInt32 cMultipleItems;
  /* Union end */
  [FieldOffset(12 + IntPtr.Size)] public UInt32 cbDetails;
  [FieldOffset(12 + IntPtr.Size + 4)] public IntPtr paDetails;
 }

Notes

All the current functionality is tested and working, I tried not to include bugs, but they are there and I find them every once in a while. If you find bugs, I'll be grateful to get feedback to update the article.

For now I don't need anything else from the library, but if you think of something that is not included in it which could make it better, just let me know and I'll try to include it.

If you have a problem with it, feel free to write me an email.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

CastorTiu
Software Developer Microsoft
United States United States
I started with programming about 19 years ago as a teenager, from my old Commodore moving to PC/Server environment Windows/UNIX SQLServer/Oracle doing gwBasic, QBasic, Turbo Pascal, Assembler, Turbo C, BC, Summer87, Clipper, Fox, SQL, C/C++, Pro*C, VB3/5/6, Java, and today loving C#.
 
Currently working as SDE on Failover Clustering team for Microsoft.
 
Passion for most programming languages and my kids Aidan&Nadia.

Comments and Discussions

 
QuestionAccessing Win XP Information PinmemberCliffRat14-May-14 6:47 
QuestionReg : Microphone Boost PinmemberKAP_19843-Feb-14 17:36 
Questionmixer control PinmemberDavid Altman10-Dec-13 6:10 
QuestionDouts About Record audio and Listen back microfone PinmemberRodrigo Torres Leme5-Aug-13 5:46 
QuestionMixer Exception [modified] Pinmembermysofttest4-Jun-12 3:18 
GeneralRe: Mixer Exception PinmemberMember 85519105-Jul-12 20:59 
GeneralRe: Mixer Exception PinmemberTylor Pater21-Nov-13 8:43 
Question(windows mixer control) Pinmemberlokesh719010-May-12 23:34 
AnswerRe: (windows mixer control) Pinmembermysofttest4-Jun-12 19:54 
GeneralMy vote of 5 PinmemberSergio Andrés Gutiérrez Rojas14-Mar-12 18:17 
GeneralMy vote of 5 Pinmemberkostickaa5-Jan-12 23:01 
QuestionWaveLib.AudioMixer.MixerException Pinmemberamolpbhavsar10-Sep-11 2:20 
AnswerRe: WaveLib.AudioMixer.MixerException PinmemberMember 85519105-Jul-12 20:49 
GeneralWindows7/Vista version PinmemberMember 779661522-Apr-11 19:50 
Hi Castor,
 
I have used your program and it is working beautifully.
 
I am wondering if you have a version that works on Vista/Windows 7. Could I get a copy of it please?
 
Would greatly appreciate a response back.
 
My email ID: rsekar_2005@yahoo.com
 
Thanks
GeneralRe: Windows7/Vista version PinmemberloheL17-Sep-11 10:05 
Generaladding wav/mp3 Pinmembertzachip10-Dec-10 7:10 
QuestionRe: adding wav/mp3 PinmemberHY1232-Mar-11 1:19 
QuestionHow to impliment Audio Microphone Boost on Windows-7 and Windows-Vista Pinmembergawadepd31-Oct-10 21:40 
GeneralHiding mixer line PinmemberACNZdev27-Sep-10 14:05 
GeneralRe: Hiding mixer line PinmemberMember 45586617-Mar-11 21:41 
Generalwin 7 mixer PinmemberPdaus10-Aug-10 0:02 
GeneralC# Mixer Project needs massive update. [modified] PinmemberMember 724777618-Jul-10 17:19 
GeneralRe: C# Mixer Project needs massive update. PinmemberCastorTiu19-Jul-10 11:57 
GeneralRe: C# Mixer Project needs massive update. PinmemberJohn Whitmire21-Oct-10 9:05 
Generalnot working for win7x64 Pinmembermordred66613-Jul-10 4:10 
QuestionException coming while changing the device..... Pinmemberamolpbhavsar5-Feb-10 1:16 
AnswerRe: Exception coming while changing the device..... Pinmemberjeff.steinkamp8-Feb-10 11:53 
GeneralWin 7 and Speaker volume Pinmemberfguidetti3-Feb-10 21:16 
GeneralRe: Win 7 and Speaker volume Pinmemberronclarke22-Mar-10 8:00 
GeneralFront Mic Selection Pinmemberpeoman10-Jan-10 12:27 
GeneralRe: Front Mic Selection Pinmemberpeoman24-Jan-10 11:51 
GeneralMic Boost and AGC detect Pinmembernbishop7-Jan-10 5:39 
GeneralRe: Mic Boost and AGC detect Pinmemberkostickaa6-Jan-12 2:48 
QuestionWindows Seven? Pinmemberstainlesssteel18-Nov-09 10:28 
AnswerRe: Windows Seven? Pinmembernbishop7-Jan-10 5:40 
GeneralRe: Windows Seven? PinmemberMember 779661522-Apr-11 20:07 
QuestionEvent for Default Playback or recording device change Pinmemberamolpbhavsar14-Oct-09 4:47 
GeneralLooks great - but dies under Win7 x64 Pinmembertlhintoq21-Aug-09 18:44 
GeneralRe: Looks great - but dies under Win7 x64 Pinmembertlhintoq21-Aug-09 19:06 
QuestionRouting left/right channels Pinmemberezcodez26-Jul-09 18:52 
GeneralNo Volume [solved] Pinmemberblubspinat21-Jul-09 23:30 
QuestionError Message PinmemberYeahman31118-Jun-09 4:23 
QuestionI want have Mono Mode PinmemberVu Thanh Tung2-Jun-09 22:20 
GeneralHi There Buddy, PinmemberEveng Thao28-May-09 6:53 
GeneralPort to .NET CF Pinmemberizmoto13-May-09 4:25 
NewsAwesome! It works perfect with VS2008 Pinmembersdfasdfasdfasdf28-Dec-08 3:19 
Generalmax product name length PinmemberMember 472289621-Nov-08 19:47 
GeneralRe: max product name length [modified] PinmemberStefan Przybyl22-Apr-10 22:19 
QuestionIs this Code and Wavelibmixer is free? or any licence required to purchage? Pinmemberbalaji_vbr3-Oct-08 2:37 
GeneralProblem with recording voice from multiple microphones!!! PinmemberMeContra20-Sep-08 22:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140921.1 | Last Updated 1 Oct 2006
Article Copyright 2005 by CastorTiu
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid