Question

In Windows 7 there are multiple playback devices.

Example (on my laptop): Speakers and Dual Headphones Independent Dual Headphones SPDIF (Digital Out via HP Dock)

The situation is thus: I am writing an app that lets the user choose the output device and save this into the settings of the app. So it offers the user a choice of all Directsound devices in a combobox. The user selects the one he prefers and saves it.

My requirement is: On initial load of this list, I want to select the default device (as set in Windows 7 - Control Panel -> Sound -> Playback tab)

So my code to enumerate the audio output devices is:

Code:

procedure TForm1.FillDevices;
var
  AudioDevEnum: TSysDevEnum;
  n: string;
  i, ps: integer;
begin

  AudioDevEnum := TSysDevEnum.Create(CLSID_AudioRendererCategory);
  try

    if AudioDevEnum.CountFilters = 0 then
      Exit;

    for i := 0 to AudioDevEnum.CountFilters - 1 do
    begin
      n  := AudioDevEnum.Filters[i].FriendlyName;
      ps := pos('DirectSound: ', n);
      if ps <> 0 then
      begin
        ps := pos('Modem', n);
        if ps = 0 then
        begin
          // Delete(n, 1, 13);
          lstDevices.Items.Add(n);
        end;
      end;
    end;
    lstDevices.ItemIndex := 0;

  finally
    AudioDevEnum.Free;
  end;
end;

After getting the list, I want to detect the item which is set as the 'default device' in the sound control panel, and select it. This is so that application saves the correct device the first time without needing the user to do this job.

Can this be done? How?

Thanks in advance.

EDIT: Note that I want to select and save (to INI file) the default device so that it can be used by my application to output sound (via the DSPack component). I do not want to change the Windows setting.

Was it helpful?

Solution

Here's a method that queries the driver for preferred playback device(http://msdn.microsoft.com/en-us/library/aa909815.aspx), GetWaveOutDeviceList will return the list of devices, GetWaveOutDevice will return the index in the list of the prefered device.

// this method will return the index in the list
function GetWaveOutDevice: Cardinal;
const
  DRVM_MAPPER=$2000;
  DRVM_MAPPER_PREFERRED_GET = DRVM_MAPPER + 21;
  DRVM_MAPPER_PREFERRED_SET = DRVM_MAPPER + 22;
var
 LDW2: Cardinal;
begin
 Result := $FFFFFFFF;
 LDW2 := 0;
 waveOutMessage( WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, DWORD( @Result ), DWORD( @LDW2 ) );
end;

// this method will retrieve the list of devices
procedure GetWaveOutDeviceList(List: TStrings);
var
 Index: Integer;
 LCaps: WAVEOUTCAPS;
begin
  List.Clear;
  for Index := 0 to waveOutGetNumDevs -1 do begin
    waveOutGetDevCaps( Index, @LCaps, SizeOf( LCaps ) );
    List.add( LCaps.szPname );
  end;
end;

If you would like to get the recording devices, just replace "WaveOut" with "WaveIn" in the above to methods.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top