[wdmaudiodev] AW: Re: Vista Core API: Changing audio device sample rate via PKEY_AudioEngine_DeviceFormat does not work

  • To: <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Wed, 10 Jan 2007 10:35:25 +0100

Hi Mitch,

thanks for the response. This is what I suspected. Currently we don't supply an 
inf file for this device, it installs without any user interaction as a default 
USB audio device. You are suggesting that we install an appropriate inf file 
with our software setup. When the device is later on plugged in, it will be 
installed using our own inf file overruling one of these inf files: usb.inf, 
wdma_usb.inf, wdmaudio.inf?

This would work for us very well in most cases. Could you provide some 
information how to do this?

Nevertheless it can happen that the device is plugged in before the software is 
installed. In this case I see three options:
- deinstall the device and get it detected and installed again. I suppose that 
this can be done using the setup api
- tell the user where to click (bad choice)
- run my registry hack. Not nice but working.

Best regards
Wolfgang Bruessler

-----Ursprüngliche Nachricht-----
Von: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] 
Im Auftrag von Mitchell Rundle
Gesendet: Dienstag, 9. Januar 2007 19:02
An: wdmaudiodev@xxxxxxxxxxxxx
Betreff: [wdmaudiodev] Re: Vista Core API: Changing audio device sample rate 
via PKEY_AudioEngine_DeviceFormat does not work

You cannot set the device format via the propertyStore alone as this will cause 
the internal state of various audio core components to be out of sync.

You can set the device format at install time via the device inf.  If this is a 
viable solution let me know and I will provide more details.

Regards,
Mitch Rundle
Microsoft

This posting is provided "AS IS" with no warranties, and confers no rights.

-----Original Message-----
From: wdmaudiodev-bounce@xxxxxxxxxxxxx 
[mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of 
=?iso-8859-1?Q?Br??ler@xxxxxxxxxxxxx
Sent: Tuesday, January 09, 2007 12:52 AM
To: wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] Vista Core API: Changing audio device sample rate via 
PKEY_AudioEngine_DeviceFormat does not work

Hi,

for a certain audio device that we are distributing, the default sampling rate 
is not working correctly and needs to be changed. This can be done by the end 
user via control panel:

Vista allows to configure the sampling rate of a sound device:

- Context menu of speaker icon in system tray, menu entry "Recording Devices"
- Choose handset or headset and click on "Properties"
- Go to tab "Advanced"
- By default the sampling rate for a capture device is "1 channel, 16 bit, 
44100 Hz (CD Quality)"

We cannot live with the situation that all users have to do this configuration 
so I was looking for a way to do this programatically.

Vista provides some new API documented in "Core Audio APIs in Windows Vista". A 
property store (IPropertyStore) can now be used to read and (write) audio 
device properties. The documentation reads: "Header file Mmdeviceapi.h defines 
a number of properties of audio endpoint devices. The Windows audio service 
sets the values of these properties. Clients can read these properties, but 
should not set them." Ok, they write: "should not set them". Nevertheless it 
does not read "must not". So I gave it a try.

The PKEY_AudioEngine_DeviceFormat property contains in fact the sampling rate 
settings (in a WAVEFORMATEXTENSIBLE struct) that are configured in the sound 
device control panel. The IPropertyStore interface allows to read and set the 
property as well. But when I do this (you need elevated rights for this) the 
changed settings are not written correctly: As a result the audio device 
control panel will hang when you later on open the respective recording devices 
property tab.

An analysis shows that the sampling rate is stored in registry key 
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture\{device
 GUID}\Properties]. There are two values 
"{f19f064d-082c-4e27-bc73-6882a1bb8e4c},0" and 
"{e4870e26-3cc5-4cd2-ba46-ca0a9a70ed04},0" that are used for storing the 
settings. In fact these values are binaries containing an unknown header and 
the WAVEFORMATEXTENSIBLE struct.

When I change the settings using the control panel, both values will be 
changed. When I change the settings using the property store interface, only 
one of the two values is changed. I consider this as a Vista bug. Later on the 
respective control panel tab is hanging. A reboot of Vista does not help, 
unplug and replug of the device does not help either. The only way to repair 
this is to uninstall the device using the device manager, unplug and replug it. 
Then the device is installed again correctly.

When looking at the registry values I can see that one of the values contains 
the configured sample rate for 16 bit, the other value contains the same 
sampling rate for 32 bit. Knowing this I wrote some test code that changes the 
sampling rate of the device by reading both registry values, decode the 
contained WAVEFORMATEXTENSIBLE struct, adjust the sampling rate if required and 
write it back. This works without problems.

Here is a sample of the not working API (ignoring error handling and clean up):

hr=CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, 
IID_IMMDeviceEnumerator, (void**)&pEnumerator); hr = 
pEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &pCollection); 
hr=pCollection->GetCount(&count);

for (ULONG i = 0; i < count; i++)
{
    //......
    hr = pCollection->Item(i, &pEndpoint);
    //......
    hr = pEndpoint->OpenPropertyStore(STGM_READWRITE, &pProps);

    PROPVARIANT varConfigBuf;
    PropVariantInit(&varConfigBuf);
    hr = pProps->GetValue(PKEY_AudioEngine_DeviceFormat, &varConfigBuf);
    if( (hr==S_OK) && (varConfigBuf.vt==VT_BLOB) )
    {
        if(varConfigBuf.blob.cbSize>0)
        {
            WAVEFORMATEX 
*pWaveFormatExBlob=(WAVEFORMATEX*)(varConfigBuf.blob.pBlobData);
            WAVEFORMATEXTENSIBLE 
*pWaveFormatExtensibleBlob=(WAVEFORMATEXTENSIBLE*)pWaveFormatExBlob;

            if(bFixSampleRate && (pWaveFormatExBlob->nSamplesPerSec!=8000) )
            {
                pWaveFormatExBlob->nChannels=1;
                pWaveFormatExBlob->nSamplesPerSec=8000;
                
pWaveFormatExBlob->nBlockAlign=pWaveFormatExBlob->nChannels*pWaveFormatExBlob->wBitsPerSample/8;
                
pWaveFormatExBlob->nAvgBytesPerSec=pWaveFormatExBlob->nSamplesPerSec*pWaveFormatExBlob->nBlockAlign;
                
pWaveFormatExtensibleBlob->Samples.wValidBitsPerSample=pWaveFormatExBlob->wBitsPerSample;

                //this works when I run this code with administrative 
privileges; otherwise I get access denied error
                hr=pProps->SetValue(PKEY_AudioEngine_DeviceFormat, 
varConfigBuf);
                if(hr==S_OK)
                {
                    hr=pProps->Commit();
                }
            }
        }
        PropVariantClear(&varConfigBuf);
    }
}

Did anyone try this before?

Best regards
Wolfgang Bruessler
******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.com/

******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.com/

******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.com/

Other related posts:

  • » [wdmaudiodev] AW: Re: Vista Core API: Changing audio device sample rate via PKEY_AudioEngine_DeviceFormat does not work