Delphi-PRAXiS
Seite 1 von 2  1 2      

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 14. Okt 2023 09:10


Get/Set Master Volume Lautstärke?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo! Wie kann man in Delphi den Wert der Master Volume Lautstärke erhalten und setzen?

Mein System: Delphi 11 in Windows 10

Anhang 56332

PeterPanino 14. Okt 2023 10:31

AW: Get/Set Master Volume Lautstärke?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Wenn ich in den Windows Settings den Mixer-Kanal meiner App anzeige, so steht dieser auf 100:

Anhang 56333

Wenn ich dann die JEDI-Komponente TJvSoundControl verwende, kann ich Wave.Volume auf einen Wert einstellen:

Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
begin
  // TJvSoundControl:
  JvSoundControl1.Wave.Volume := 50;
end;
Das Setzen dieses Wertes auf 50 (s.o.) stellt den Regler auf 39 ein:

Anhang 56334

So weit so gut. Ich möchte aber nicht die Lautstärke meiner App setzen, sondern die allgemeine Lautstärke MASTER VOLUME. Wie kann man das bewerkstelligen?

PeterPanino 14. Okt 2023 11:57

AW: Get/Set Master Volume Lautstärke?
 
Ich habe jetzt endlich eine funktionierende Lösung gefunden, um den Wert von Master Volume (Mute/Unmute, Volume Percent) AUSZULESEN:

Es ist die Lösung von Andreas Rejbrand auf Stack Overflow:

https://stackoverflow.com/questions/...on-mute-unmute

Aber leider weiß ich jetzt noch immer nicht, wie ich den Wert von Master Volume SETZEN kann. Weiß jemand einen Rat?

Sherlock 14. Okt 2023 12:04

AW: Get/Set Master Volume Lautstärke?
 
Hast Du mal gegoogelt? Bei SO findet sich zumindest dies hier: https://stackoverflow.com/questions/...e-in-windows-7 Keine Ahnung inwieweit das mittlerweile in irgendwelchen MS API Units gekapselt sein könnte.

PeterPanino 14. Okt 2023 13:57

AW: Get/Set Master Volume Lautstärke?
 
Ich habe jetzt (mit der AudioEndpoint Unit von Andreas Rejbrand) selbst eine funktionierende Methode gefunden, um den Master Volume Level einzustellen:

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

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

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

    if not Succeeded(FAudioEndpointVolume.RegisterControlChangeNotify(Self)) then
    begin
      CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: 4');
      ExitProcess(1);
    end;

    if Assigned(FAudioEndpointVolume) then
    begin
      // Get the current mute status
      FAudioEndpointVolume.GetMute(MuteStatus);

      // Unmute if it was muted:
      if MuteStatus then
        FAudioEndpointVolume.SetMute(False, nil); // This line is executed, but the master volume is NOT unmuted!

      // Ensure the level is within the valid range (0.0 to 1.0):
      Level := Max(0.0, Min(1.0, Level));

      // Set the master volume level as a scalar:
      FAudioEndpointVolume.SetMasterVolumeLevelScalar(Level, nil); // it works!

      // Optionally, you can send a notification or update your UI here
    end
    else
    begin
      CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
    end;
  {except
    on E: Exception do
    begin
      // Handle any exceptions here
      CodeSite.Send('Exception in SetMasterVolumeLevelScalar', E.Message);
    end;
  end;}
end;
Leider wird jedoch der MUTED STATUS nicht unmuted, wenn er vorher muted war!

Weiß jemand, wie man diesen Fehler beheben kann?

Kas Ob. 14. Okt 2023 16:05

AW: Get/Set Master Volume Lautstärke?
 
My two cents on this, Mute and Enable are intentionally undocumented by Microsoft, these will compromise the user privacy, like .. by simply enabling the disabled microphone in first place, or just unmute the speakers without the user consent and play some audio.

It is doable and it is not a hack, but unethical to share, so you have to ask the user himself to enable (eg. the Mic) or unmute the speakers.

PeterPanino 14. Okt 2023 17:56

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

Zitat von Kas Ob. (Beitrag 1528080)
My two cents on this, Mute and Enable are intentionally undocumented by Microsoft, these will compromise the user privacy, like .. by simply enabling the disabled microphone in first place, or just unmute the speakers without the user consent and play some audio.

It is doable and it is not a hack, but unethical to share, so you have to ask the user himself to enable (eg. the Mic) or unmute the speakers.

In fact, that's what I am planning: The user should be able to simply click a button on my app to quickly mute or unmute his master volume without having to awkwardly call the Windows settings each time. With my apps, I always strive to make the operation of Windows easier, which is often unnecessarily complicated on many advanced settings. One usage example is: quickly switching off the sound while annoying commercials are playing in a movie. The user should always be in control of his computer's sound!

tomkupitz 14. Okt 2023 19:21

AW: Get/Set Master Volume Lautstärke?
 
gefunden...

Code:
uses MMSystem;

...

procedure GetWaveVolume(var volL, volR: DWord);
var
  hWO: HWAVEOUT;
  waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  volL:= 0;
  volR:= 0;
  // init TWAVEFORMATEX
  FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  waveOutOpen(@hWO, WAVE_MAPPER, @waveF, 0, 0, 0);
  // get volume
  waveOutGetVolume(hWO, @vol);
  volL:= vol and $FFFF;
  volR:= vol shr 16;
  waveOutClose(hWO);
end;

procedure SetWaveVolume(const volL, volR: DWord);
var
  hWO: HWAVEOUT;
  waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  // init TWAVEFORMATEX
  FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  waveOutOpen(@hWO, WAVE_MAPPER, @waveF, 0, 0, 0);
  vol:= volL + volR shl 16;
  // set volume
  waveOutSetVolume(hWO, vol);
  waveOutClose(hWO);
end;

PeterPanino 14. Okt 2023 20:11

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

Zitat von tomkupitz (Beitrag 1528082)
gefunden...

Code:
uses MMSystem;

...

procedure GetWaveVolume(var volL, volR: DWord);
var
  hWO: HWAVEOUT;
  waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  volL:= 0;
  volR:= 0;
  // init TWAVEFORMATEX
  FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  waveOutOpen(@hWO, WAVE_MAPPER, @waveF, 0, 0, 0);
  // get volume
  waveOutGetVolume(hWO, @vol);
  volL:= vol and $FFFF;
  volR:= vol shr 16;
  waveOutClose(hWO);
end;

procedure SetWaveVolume(const volL, volR: DWord);
var
  hWO: HWAVEOUT;
  waveF: TWAVEFORMATEX;
  vol: DWORD;
begin
  // init TWAVEFORMATEX
  FillChar(waveF, SizeOf(waveF), 0);
  // open WaveMapper = std output of playsound
  waveOutOpen(@hWO, WAVE_MAPPER, @waveF, 0, 0, 0);
  vol:= volL + volR shl 16;
  // set volume
  waveOutSetVolume(hWO, vol);
  waveOutClose(hWO);
end;

Diesem Irrtum bin ich vorher auch verfallen: Das betrifft nicht den Wert von MASTER VOLUME, sondern den Volume-Wert des eigenen Programms.

Kannst du in Settings -> App volume and device preferences genau beobachten.

Danke jedenfalls für deinen Beitrag! Much appreciated!

Kas Ob. 15. Okt 2023 11:11

AW: Get/Set Master Volume Lautstärke?
 
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:
procedure TForm10.SetMasterMuteState(Muted: Boolean);
var
  MuteStatus: Boolean;
  FAudioEndpointVolume: AudioEndpoint.IAudioEndpointVolume; // from the Andreas Rejbrand unit
  FDeviceEnumerator: IMMDeviceEnumerator;
  FMMDevice: IMMDevice;
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
    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)))
  end
  else
  begin
    OutputDebugString('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
      //CodeSite.Send('TForm1.SetMasterVolumeLevelScalar: FAudioEndpointVolume not assigned!');
  end;
end;
It is working on my Windows 10 (1803)


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

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