Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Get/Set Master Volume Lautstärke? (https://www.delphipraxis.net/213884-get-set-master-volume-lautstaerke.html)

PeterPanino 15. Okt 2023 13:06

AW: Get/Set Master Volume Lautstärke?
 
Zitat:

Zitat von Kas Ob. (Beitrag 1528093)
Zitat:

Zitat von PeterPanino (Beitrag 1528081)
The user should always be in control of his computer's sound!

Sure but Windows lack ability to do permissions like iOS or Android so they revert to prohibit some API without explicitly user inatraction.

I was mistaken with the mute status, my old project was on specific request from a client where he wanted to control the devices in Sound Control Panel to enable and disable a device and change the Default device for both Playback and Recording, which is not allowed without user interaction, it took me hours of debugging to extract the Windows internal code which was one freaking line!!

Anyway i tried this based on your code and it is working just fine
Code:
...
    if not Succeeded(FAudioEndpointVolume.SetMute(Muted, nil)) then
      OutputDebugString(PChar('TForm1.SetMasterVolumeLevelScalar: SetMute OK ' + BoolToStr
        (Muted, True)))
    else
      OutputDebugString(PChar('TForm1.SetMasterVolumeLevelScalar: SetMute Fail ' +
        BoolToStr(Muted, True)))
...
It is working on my Windows 10 (1803)

Isn't the logic inverted here? (if not Succeeded -> SetMute OK)

Anyway - when calling with a False parameter, checking the exact HRESULT it returns FALSE here:
Code:
    var R: System.HResult := FAudioEndpointVolume.SetMute(Muted, nil);
    case R of
      S_OK:         CodeSite.Send('TForm1.SetMasterVolumeMuteState: OK');         // successful operation with a return value of True
      S_FALSE:      CodeSite.Send('TForm1.SetMasterVolumeMuteState: FALSE');      // successful operation with a return value of False
      E_NOINTERFACE: CodeSite.Send('TForm1.SetMasterVolumeMuteState: NOINTERFACE'); // Interface not supported
      E_UNEXPECTED: CodeSite.Send('TForm1.SetMasterVolumeMuteState: UNEXPECTED'); // Catastrophic failure
      E_NOTIMPL:    CodeSite.Send('TForm1.SetMasterVolumeMuteState: NOTIMPL');    // Operation not implemented
    end;
Windows Version: 10.0 Build 19045, Windows 10 (Version 22H2, OS Build 19045.3570, 64-bit Edition)

PeterPanino 15. Okt 2023 13:43

AW: Get/Set Master Volume Lautstärke?
 
Debugging it further:

Delphi-Quellcode:
procedure TForm1.SetMasterVolumeMuteState(Muted: Boolean);
var
  MuteStatus: Boolean;
  FAudioEndpointVolume: AudioEndpoint.IAudioEndpointVolume; // from the Andreas Rejbrand unit
  FDeviceEnumerator: IMMDeviceEnumerator;
  FMMDevice: IMMDevice;
begin
  CodeSite.Send('TForm1.SetMasterVolumeMuteState: A');
  if not Succeeded(CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER,
    IID_IMMDeviceEnumerator, FDeviceEnumerator)) then
  begin
    //OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 1');
    CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 1');
    ExitProcess(1);
  end;

  if not Succeeded(FDeviceEnumerator.GetDefaultAudioEndpoint(0, 0, FMMDevice)) then
  begin
    //OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 2');
    CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 2');
    ExitProcess(1);
  end;

  if not Succeeded(FMMDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, FAudioEndpointVolume)) then
  begin
    //OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 3');
    CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 3');
    ExitProcess(1);
  end;

  CodeSite.Send('TForm1.SetMasterVolumeMuteState: B');

  if Assigned(FAudioEndpointVolume) then
  begin
    CodeSite.Send('TForm1.SetMasterVolumeMuteState: C');
    var R: System.HResult := FAudioEndpointVolume.SetMute(Muted, nil);
    case R of
      S_OK:         CodeSite.Send('TForm1.SetMasterVolumeMuteState: OK');         // successful operation with a return value of True
      S_FALSE:      CodeSite.Send('TForm1.SetMasterVolumeMuteState: FALSE');      // successful operation with a return value of False
      E_NOINTERFACE: CodeSite.Send('TForm1.SetMasterVolumeMuteState: NOINTERFACE'); // Interface not supported
      E_UNEXPECTED: CodeSite.Send('TForm1.SetMasterVolumeMuteState: UNEXPECTED'); // Catastrophic failure
      E_NOTIMPL:    CodeSite.Send('TForm1.SetMasterVolumeMuteState: NOTIMPL');    // Operation not implemented
      else          CodeSite.Send('TForm1.SetMasterVolumeMuteState: ELSE');
    end;
  end
  else
  begin
    //OutputDebugString('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
    CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
  end;
end;
When calling SetMasterVolumeMuteState(True);

I get these debug messages:

TForm1.SetMasterVolumeMuteState: A
TForm1.SetMasterVolumeMuteState: B
TForm1.SetMasterVolumeMuteState: C
TForm1.SetMasterVolumeMuteState: ELSE

Kas Ob. 15. Okt 2023 14:19

AW: Get/Set Master Volume Lautstärke?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Isn't the logic inverted here? (if not Succeeded -> SetMute OK)
Yes you are right there.

I messed that up, but in all cases the master is switching between muted and unmuted with that function, try to capture the R value.

Also it seems the behavior is different on my Windows
Anhang 56335

As you see in the Log Event first click is OK showing changing state followed by False because the state is not changed.

PeterPanino 15. Okt 2023 15:24

AW: Get/Set Master Volume Lautstärke?
 
Catching the R value on ELSE:

When calling SetMasterVolumeMuteState(True);

I get these debug messages:

TForm1.SetMasterVolumeMuteState: A
TForm1.SetMasterVolumeMuteState: B
TForm1.SetMasterVolumeMuteState: C
TForm1.SetMasterVolumeMuteState: ELSE = -2147024809

"-2147024809" is "0x80070057," which corresponds to the error code E_INVALIDARG (Invalid arguments).

How do you call SetMute?

Kas Ob. 15. Okt 2023 17:18

AW: Get/Set Master Volume Lautstärke?
 
Here is my full working example
Code:
procedure TForm10.Button3Click(Sender: TObject);
begin
  SetMasterMuteState(True);
end;

procedure TForm10.Button4Click(Sender: TObject);
begin
  SetMasterMuteState(False);
end;

procedure TForm10.SetMasterMuteState(Muted: Boolean);
var
  MuteStatus: Boolean;
  FAudioEndpointVolume: AudioEndpoint.IAudioEndpointVolume; // from the Andreas Rejbrand unit
  FDeviceEnumerator: IMMDeviceEnumerator;
  FMMDevice: IMMDevice;
  R: System.HResult;
begin
  if not Succeeded(CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER,
    IID_IMMDeviceEnumerator, FDeviceEnumerator)) then
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 1');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 1');
    ExitProcess(1);
  end;

  if not Succeeded(FDeviceEnumerator.GetDefaultAudioEndpoint(0, 0, FMMDevice)) then
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 2');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 2');
    ExitProcess(1);
  end;

  if not Succeeded(FMMDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil,
    FAudioEndpointVolume)) then
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 3');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 3');
    ExitProcess(1);
  end;

  if Assigned(FAudioEndpointVolume) then
  begin

      R := FAudioEndpointVolume.SetMute(Muted, nil);
    case R of
      S_OK: OutputDebugString('TForm1.SetMasterVolumeMuteState: OK'); // successful operation with a return value of True
      S_FALSE: OutputDebugString('TForm1.SetMasterVolumeMuteState: FALSE'); // successful operation with a return value of False
      E_NOINTERFACE: OutputDebugString('TForm1.SetMasterVolumeMuteState: NOINTERFACE'); // Interface not supported
      E_UNEXPECTED: OutputDebugString('TForm1.SetMasterVolumeMuteState: UNEXPECTED'); // Catastrophic failure
      E_NOTIMPL: OutputDebugString('TForm1.SetMasterVolumeMuteState: NOTIMPL'); // Operation not implemented
      else OutputDebugString(PChar('TForm1.SetMasterVolumeMuteState: ELSE '+ IntToHex(R,8)));
    end;

  end
  else
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
  end;
end;

PeterPanino 15. Okt 2023 18:04

AW: Get/Set Master Volume Lautstärke?
 
TForm1.FormKeyUp:
TForm1.SetMasterVolumeMuteState: A
TForm1.SetMasterVolumeMuteState: B
TForm1.SetMasterVolumeMuteState: C
TForm1.SetMasterVolumeMuteState: ELSE 80070057

There must be a difference between our versions of Windows.

Kas Ob. 16. Okt 2023 08:20

AW: Get/Set Master Volume Lautstärke?
 
Interesting !

Please try this
Code:
const
  IID_IAudioEndpointVolumeEx: TGUID = '{66E11784-F695-4F28-A505-A7080081A78F}';

type
  IAudioEndpointVolumeEx = interface(IAudioEndpointVolume)
    [IID_IAudioEndpointVolumeEx]
    function GetVolumeRangeChannel(nChannel: Integer; out pflVolumeMindB: double; out
      pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): HRESULT; stdcall;
  end;

procedure TForm10.Button3Click(Sender: TObject);
begin
  SetMasterMuteState(True);
end;

procedure TForm10.Button4Click(Sender: TObject);
begin
  SetMasterMuteState(False);
end;

procedure TForm10.SetMasterMuteState(Muted: Boolean);
var
  FAudioEndpointVolumeEx: IAudioEndpointVolumeEx;
  FDeviceEnumerator: IMMDeviceEnumerator;
  FMMDevice: IMMDevice;
  R: System.HResult;
begin
  if not Succeeded(CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER,
    IID_IMMDeviceEnumerator, FDeviceEnumerator)) then
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 1');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 1');
    ExitProcess(1);
  end;

  if not Succeeded(FDeviceEnumerator.GetDefaultAudioEndpoint(0, 0, FMMDevice)) then
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 2');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 2');
    ExitProcess(1);
  end;

  if not Succeeded(FMMDevice.Activate(IID_IAudioEndpointVolumeEx, CLSCTX_INPROC_SERVER,
    nil, IAudioEndpointVolume(FAudioEndpointVolumeEx))) then
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: 3');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 3');
    ExitProcess(1);
  end;

  if Assigned(FAudioEndpointVolumeEx) then
  begin
    R := FAudioEndpointVolumeEx.SetMute(Muted, nil);
    case R of
      S_OK:
        OutputDebugString('TForm1.SetMasterVolumeMuteState: OK'); // successful operation with a return value of True
      S_FALSE:
        OutputDebugString('TForm1.SetMasterVolumeMuteState: FALSE'); // successful operation with a return value of False
      E_NOINTERFACE:
        OutputDebugString('TForm1.SetMasterVolumeMuteState: NOINTERFACE'); // Interface not supported
      E_UNEXPECTED:
        OutputDebugString('TForm1.SetMasterVolumeMuteState: UNEXPECTED'); // Catastrophic failure
      E_NOTIMPL:
        OutputDebugString('TForm1.SetMasterVolumeMuteState: NOTIMPL'); // Operation not implemented
    else
      OutputDebugString(PChar('TForm1.SetMasterVolumeMuteState: ELSE ' + IntToStr(R)));
    end;

  end
  else
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
  end;
end;
Also did you try to run your application as Administrator ? , it could be some permission problem.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:42 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz