views:

552

answers:

3

Hello fellow programmers,

I'm developing an application that among other things, enumerates all input audio devices (using SetupAPI) and then for each audio device, it lists all input audio lines (using winmm.dll).

Basically, the way I'm relating the two is getting the device path from the audio device and then using waveInMessage to compare the audio line's device path.

Now, I want to be able to do the same with the windows default [input] audio line (WAVE_MAPPER).

The problem is that using waveInGetDevCaps for WAVE_MAPPER returns "Microsoft Sound Mapper", and using waveInMessage with DRV_QUERYDEVICEINTERFACE returns an empty string.

Any suggestions on how to find out which device the Microsoft Mapper is mapping to?

+1  A: 

Well for one I've found DirectSound to be a lot easier and with far less XP to Vista undocumented oddities (And far less undocumented oddities in general).

But probably the only way you'll work it out is to enumerate all the other devices and see which one matches the WAVE_MAPPER one.

Honestly though ... use DirectSound or, if you are able to do Vista and Win 7 only, use the Core Audio API. Winmm is an ANCIENT API and was pretty broken when it was first introduced ...

Goz
The problem is we have to support windows 2000 and up. Now regarding your suggestion, I actually am enumerating all the devices, but the thing is I have nothing to hold on and compare... I couldn't find a way to match WAVE_MAPPER with the list of devices I already have.
Padu Merloti
DirectSound will work on Win 2K out of the box .. but its up to you. I'd still strongly recommend avoiding winmm ... but good luck I hope all the undocumented changed don't bite ya like they did me!
Goz
+2  A: 

The device that WAVE_MAPPER is mapped to depends on the parameters passed to waveInOpen. From the documentation:

WAVE_MAPPER - The function selects a waveform-audio input device capable of recording in the specified format.

This means you can't check the device properties without actually opening it. Once you open it, you should be able to get the actual device ID with waveInGetID.

interjay
waveInGetID is one of the functions I haven't ported to C# yet. By reading its documentation, it sounds like it should work. I will test your suggestion and let it be known here if it works or not.
Padu Merloti
Just tested it... got a handle from waveInOpen, then passed the handle to waveInGetID.... what did I get... hahahaaha... -1 (WAVE_MAPPER). Maybe that's why the first entry on google says "This function is supported for backward compatibility. New applications can cast a handle of the device rather than retrieving the device identifier."
Padu Merloti
A: 

Please correct me if I'm wrong, but I've been watching some videos from past Microsoft conferences on sound development. On the latest one from Larry Osterman, he mentions new sound features in [I believe] Windows 7 that his team worked on.

One of the features was [the name is my interpretation] "device hot swap". Let's say your application is playing back using the "windows default sound playback" endpoint, and that at this moment is a set of USB Headphones. Suddenly you disconnect the headphones. Up to Windows 7, your application would crash [if you didn't foresee that test scenario]. In Windows 7 [and here's the hook to the original subject], IF you're using the Windows default playback device, Windows will gracefully and automatically swap the output stream to the new default, which could be the speakers.

What I'm trying to get to, is that I'm trying to fit the WAVE_MAPPER device into a class where it is not supposed to be. Maybe, conceptually speaking, the WAVE_MAPPER despite having the same capability of audio stream input and output, should be treated as an exception.

I'll try to be more concrete. In my application, I have a list of audio devices, and each audio device has a list of audio lines. Audio devices have properties such as VID and PID that are easily discoverable through the SetupAPI and can be related to audio lines via winmm's waveInMessage. WAVE_MAPPER doesn't follow that logic and I was trying to make it do.

So instead of trying to relate the WAVE_MAPPER with its underlying audio device, I will just treat it as what it is: the default audio device.

Padu Merloti