Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Zuweisung der Hauptlautstärke (https://www.delphipraxis.net/191566-zuweisung-der-hauptlautstaerke.html)

EWeiss 28. Jan 2017 13:29


Zuweisung der Hauptlautstärke
 
Hab die Balance zu TAudioVolume addiert aber ein kleines Berechnungsproblem.

Der Ausgang soll so sein das der rechte und linke Kanal jeweils 100% hat wenn meine Trackbar auf 50 also der hälfte steht.
Das Problem ist aber das im Moment bei meiner Berechnung die Lautstärke sowie beide Kanäle auf 50% stehen.

Schiebe ich den regler ganz nach links ist die Lautstärke 100% und der linke Kanal genauso.
Das gleiche wenn ich ganz nach rechts schiebe.

Meine Funktion sieht so aus.

Delphi-Quellcode:
procedure TAudioVolume.tbMasterBalanceChange(Sender: TObject);
var
  Balance: single;
  rightVol: single;
  leftVol: single;
begin

  if AudioEndpointVolume = nil then
    exit;

  Balance := Max(-tbMasterBalance.Max, Min(tbMasterBalance.Max, tbMasterBalance.Position));

  leftVol := 1.0 - Max(0.0, Balance / tbMasterBalance.Max);
  rightVol := 1.0 + Min(0.0, -leftVol);

  AudioEndpointVolume.SetChannelVolumeLevelScalar(0, leftVol, @GUID_TAudioVolume);
  AudioEndpointVolume.SetChannelVolumeLevelScalar(1, rightVol, @GUID_TAudioVolume);

end;
Wo ist mein Denkfehler ? Das die Lautstärke sich immer mit verändert.. bzw. die Kanäle bei 50% der Trackbar.Position nicht 100% sind.
Bewege ich den linken bzw.. den rechten Slider unter den Eigenschaften "Wiedergabegerät" separat ändert sich die Hauptlautstärke nicht.
Aber ich möchte keine zwei Trackbars dafür verwenden.

gruss

EWeiss 28. Jan 2017 13:57

AW: Zuweisung der Hauptlautstärke
 
Ich Antworte mal selber.
Ok so geht's..

Delphi-Quellcode:
procedure TAudioVolume.tbMasterBalanceChange(Sender: TObject);
var
  Balance: single;
  rightVol: single;
  leftVol: single;
  Channels: UINT;
  HR: HResult;
begin

  if AudioEndpointVolume = nil then
    exit;

  HR := AudioEndpointVolume.GetChannelCount(Channels);
  if HR = S_OK then
  begin
    if Channels < 2 then
      exit;
  end else
  exit;

  Balance := Max(-tbMasterBalance.Max, Min(tbMasterBalance.Max, tbMasterBalance.Position));

  leftVol := 1.0 - Max(0.0, (Balance / tbMasterBalance.Max));
  rightVol := 1.0 + Min(0.0, -leftVol);

  AudioEndpointVolume.SetChannelVolumeLevelScalar(0, leftVol * Channels, @GUID_TAudioVolume);
  AudioEndpointVolume.SetChannelVolumeLevelScalar(1, rightVol * Channels, @GUID_TAudioVolume);

end;
Musste die Kanäle noch mit Channels Multiplizieren.
Hat sich dann vorerst mal erledigt.

Muss jetzt noch die Position beim initialisieren berechnen.

gruss

EWeiss 29. Jan 2017 13:42

AW: Zuweisung der Hauptlautstärke
 
Ich bekomme die Values beider Kanäle nicht auf die Trackbar umgelegt.

Meine Ausgangs function.

Delphi-Quellcode:
function TAudioVolume.GetMasterBalance(): integer;
 var
  HR: HResult;
  f: Single;
  i: Integer;
  Chans: Uint;
  Channels: TChannels;
  MasterVolPos: Integer;
begin
  Result := (tbMasterVolume.Max div 2); //Center 100% für alles

  if AudioEndpointVolume = nil then
    exit;

  HR := AudioEndpointVolume.GetChannelCount(Chans);
  if HR = S_OK then
  begin
    if Chans < 2 then
      exit;
  end else
  exit;

  MasterVolPos := round(GetMasterVolume * tbMasterVolume.Max);

  for i := 0 to Chans - 1 do
  begin
    HR := AudioEndpointVolume.GetChannelVolumeLevelScalar(i, f);
    if HR = S_OK then
    begin
      case i of
        0:
          Channels.LeftVol := f;
        1:
          Channels.RightVol := f;
      end;
    end;
  end;
 
  Result := ???
end;
Ich habe jetzt 3 Werte die auf die Trackbar.Position umgelegt werden müssen.
1. MasterVol
Ändert sich dieser Wert dann passen sich die Werte der Kanäle entsprechend der Gesamtlautstärke an.
2. linker Kanal
Ändert sich die Gesamtlautstärke passt sich der Gesamtwert des linken Kanal an. Dieser soll dann die linke hälfte der Maximalen Value der Trackbar einnehmen.
3. rechte Kanal
Quasi das gleiche wie beim linken Kanal nur das hier die rechte hälfte der Maximalen Value der Trackbar dafür zuständig ist.

Die Maximale Value der Trackbar sollte sich dabei nicht verändern so das wenn als bsp.
Die Gesamtlautstärke 50% beträgt, dann ist der linke und rechte Kanal ebenfalls 50 % die Trackbar soll dann trotzdem zentriert sein.

Bin im Moment etwas überfordert das alles der Trackbar.Position zu zuweisen.

Jemand Interesse zu helfen?

PS:
Denke habe auch im ersten Beitrag noch einen Fehler da hier das MasterVol nicht mit berücksichtigt wird.

gruss

nahpets 29. Jan 2017 15:01

AW: Zuweisung der Hauptlautstärke
 
Bin mir von technischer Seite her nicht sicher, wie das Ganze geregelt wird.

Meine naive Annahme ist erstmal:

Links und rechts werden einzeln geregelt.

Die linke Trackbar zeigt die Lautstärke von links an.
Die rechte Trackbar zeigt die Lautstärke von rechts an.

Die gesamte Lautstärke ist der Mittelwert von links und rechts. Also: Gesamt = (Links + Rechts) div 2.

Ändert man nun links oder rechts, so muss gesamt (wie oben) neu berechnet werden.

Ändert man nun gesamt, so muss diese Änderung anteilig auf links und rechts verteilt werden.

Der Einfachheithalber würde ich bei einem Plus von 10 auf gesamt auch links und rechts jeweils 10 draufrechnen.

Wenn Links = 50 und Rechts = 30 wäre Gesamt = 40.

Ändert sich jetzt Gesamt um 20 auf 60, wäre Links = 70 und Rechts = 50. Probe: (70 + 50) div 2 = 60.
Natürlich muss man sicherstellen, dass der Maximalwert nicht überschritten werden kann.

Ist es aus rechnerischer Sicht das, was Du suchst?


Oder eher sowas in der Richtung?

Links und rechts seien jeweils von 0 bis 100 regelbar.
Gesamt von 0 bis 1000.

Links sei aktuell 25 und rechts 75, Gesamt sei 500.

Nun wird Gesamt um 250 noch oben verändert (= 750)

?% = 750, wenn 500 = 100%: ?% = 750 * 100 / 500 = 150%

Links wird demnach nun: 25 * 150 / 100 = 37,5.
Rechts wird demnach nun: 75 * 150 / 100 = 112,5.
Da der Maximalwert aber 100 ist wird Rechts = Min(100, 75 * 150 / 100)
Dadurch würde sich die Balance zwischen links und rechts verändern.

Oder hab' ich hier gerade einfach nur Bahnhof verstanden, bin mir da nicht so sicher.

EWeiss 29. Jan 2017 15:13

AW: Zuweisung der Hauptlautstärke
 
Am besten kannst du das ermitteln (Visuell) indem du in der Infoleiste auf das Soundsymbol klickst ( Menu Wiedergabegeräte)
Dort bei Lautstärke Eigenschaft von Lautsprecher, Tab Pegel öffnest und dort etwas mit der Balance und Lautstärke rumspielst.
Dann siehst du mit welchen Problemen ich zu kämpfen habe. ;)

Die ganzen Änderungen unter einen Hut zu bringen ist nicht so einfach.
Das auslesen der einzelnen werte ist nicht das Problem das ist fertig.
Lediglich die Zuweisung zu Trackbar.position.

Ist alles irgendwie gemixt das ganze.
Was das ganze zusätzlich verkompliziert.

gruss

markus5766h 29. Jan 2017 16:21

AW: Zuweisung der Hauptlautstärke
 
Liste der Anhänge anzeigen (Anzahl: 2)
Moin,

hab's vor ein paar Jahren so gelöst :

Code:
unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls, ComObj, ActiveX, MMDeviceApi, ComCtrls, ExtCtrls, IniFiles;

const
  CLSID_TaskbarList: TGUID = '{56fdf344-fd6d-11d0-958a-006097c9a090}';
  IID_ITaskbarList: TGUID = '{56FDF342-FD6D-11d0-958A-006097C9A090}';
  IID_ITaskbarList2: TGUID = '{602D4995-B13A-429b-A66E-1935E44F4317}';
  IID_ITaskbarList3: TGUID = '{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}';

type
  TBPF =  (TBPF_NOPROGRESS = 0,
           TBPF_INDETERMINATE = 1,
           TBPF_NORMAL = 2,
           TBPF_ERROR = 4,
           TBPF_PAUSED = 8);
  TBATF = (TBATF_USEMDITHUMBNAIL = 1,
           TBATF_USEMDILIVEPREVIEW = 2);

   ITaskbarList = interface(IUnknown)
      ['{56FDF342-FD6D-11d0-958A-006097C9A090}']
      function HrInit : HResult; stdcall;
      function AddTab(hWndOwner : HWND) : HResult; stdcall;
      function DeleteTab(hWndOwner : HWND) : HResult; stdcall;
      function ActivateTab(hWndOwner : HWND) : HResult; stdcall;
      function SetActiveAlt(hWndOwner : HWND) : HResult; stdcall;
   end; { ITaskbarList }

  ITaskbarList2 = interface(ITaskbarList)
    ['{602D4995-B13A-429b-A66E-1935E44F4317}']
    function MarkFullscreenWindow(wnd : HWND; fFullscreen : bool) : HResult; stdcall;
  end;

  ITaskbarList3 = interface (ITaskbarList2)
  ['{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}']
    function SetProgressValue (hWnd: HWND; ullCompleted: int64; ullTotal: int64): HResult; stdcall;
    function SetProgressState (hWnd: HWND; tbpFlags: TBPF): HResult; stdcall;
    function RegisterTab (hwndTab: HWND; hwndMDI: HWND): HResult; stdcall;
    function UnregisterTab (hwndTab: HWND): HResult; stdcall;
    function SetTabOrder (hwndTab: HWND; hwndInsertBefore: HWND): HResult; stdcall;
    function SetTabActive (hwndTab: HWND; hwndMDI: HWND; tbatFlags: TBATF): HResult; stdcall;
    function ThumbBarAddButtons (hWnd: HWND; cButtons: integer; pButtons: pointer): HResult; stdcall;
    function ThumbBarUpdateButtons (hWnd: HWND; cButtons: cardinal; pButtons: pointer): HResult; stdcall;
    function ThumbBarSetImageList (hWnd: HWND; himl: pointer): HResult; stdcall;
    function SetOverlayIcon (hWnd: HWND; hIcon: HICON; pszDescription: PWideChar): HResult; stdcall;
    function SetThumbnailTooltip (hWnd: HWND; pszTip: PWideChar): HResult; stdcall;
    function SetThumbnailClip (hWnd: HWND; prcClip: PRect): HResult; stdcall;
  end;

type
   TForm1 = class(TForm)
    imgRegler1: TImage;
    Label1: TLabel;
    imgLeft: TImage;
    imgRight: TImage;
    lbMaster: TLabel;
    cbMasterMute: TCheckBox;
    lbLeft: TLabel;
    lbRight: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Led1: TImage;
    Label5: TLabel;
    Panel1: TPanel;
    WheelLabel: TLabel;
      procedure FormCreate(Sender: TObject);
    procedure cbMasterMuteClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure SetMasterVolume;
    procedure SetChannelsVolume;
    procedure SetChannelsFlagVolume;
    procedure imgLeftClick(Sender: TObject);
    procedure Label5Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure WheelLabelClick(Sender: TObject);
   private
      { Private-Deklarationen }
    FTaskBarList : ITaskbarList3;
    SetPosition : Boolean;
    procedure OnMove(var Msg: TWMMove); message WM_MOVE;
   public
      { Public-Deklarationen }
   end;

type
 TepVolEvents = Procedure(f:byte) of object;


var
   Form1: TForm1;
   endpointVolume   : IAudioEndpointVolume = nil;
   deviceEnumerator : IMMDeviceEnumerator;
   defaultDevice    : IMMDevice;
   pProps           : IPropertyStore;
   epVolEvents      : TepVolEvents;
  VolumeLevel      : Single;
  OldVolume        : Single;
  OldLeft, OldRight : Single;
  vLeft, vRight    : Single;
  wheel            : Integer;
  reg1, reg2, reg3  : Boolean;

  IFile            : TIniFile;
  ProgDir          : String;
  PosX, PosY       : Integer;

implementation

{$R *.dfm}

function IsMouseOver(Control: TControl): Boolean;
var
  p: TPoint;
begin
  if GetCursorPos(p) then
  begin
    p := Control.ScreenToClient(p);
    Result := (p.X >= 0) and (p.X = 0) and (p.Y <= Control.Height) {AND Control.Visible};
  end
    else Result := False;
end;

var
   ChannelCnt              : Cardinal;
   ChannelLeft,ChannelRight : Single;
   VolMaster               : Single;
   VolMute                 : Bool;
  Percent                 : Integer;
  ChannelFlag             : Boolean;

procedure TForm1.OnMove(var Msg: TWMMove);
begin
  inherited;
  if SetPosition then
    begin
      PosX := Form1.Left;
      PosY := Form1.Top;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
begin
  SetPosition := False;
  ProgDir := ExtractFilePath(ParamStr(0));
  IFile  := TIniFile.Create(ProgDir + 'mastervolume.ini');
  PosX   := IFile.ReadInteger('Position', 'Left', 240);
  PosY   := IFile.ReadInteger('Position', 'Top', 240);
  IFile.Free;

  FTaskBarList := CreateComObject(CLSID_TaskbarList) as ITaskbarList3;
  ChannelFlag := False;
  Form1.DoubleBuffered := True;
  wheel := 2;
   CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
end;

procedure TForm1.cbMasterMuteClick(Sender: TObject);
begin

  if cbMasterMute.Checked then
    begin
      OldLeft := vLeft;
      OldRight := vRight;
      if endpointVolume = nil then Exit;
       VolumeLevel := 0;
       endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
      FTaskBarList.SetProgressState(Application.handle, TBPF_Indeterminate);
    end
      else
        begin
          if endpointVolume = nil then Exit;
          if not ChannelFlag then
            begin // not ChannelFlag
               VolumeLevel := OldVolume;
               endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
            end
              else SetChannelsFlagVolume; // ChannelFlag
          FormShow(self);
        end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  Form1.Left := PosX;
  Form1.Top := PosY;
 
   if deviceEnumerator = nil then begin ShowMessage('NIL'); Exit; end;
   deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
   if defaultDevice <> nil then defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
   endpointVolume.GetChannelCount(ChannelCnt);
   endpointVolume.GetMasterVolumeLevelScalar(VolMaster);
  VolumeLevel := VolMaster;
  imgRegler1.Top := 20 + (200 - Round(VolumeLevel * 200));
   endpointVolume.GetChannelVolumeLevelScalar(0,ChannelLeft);
   endpointVolume.GetChannelVolumeLevelScalar(1,ChannelRight);
  vLeft := ChannelLeft;
  vRight := ChannelRight;
   endpointVolume.GetMute(VolMute);
   if VolMute=True then cbMasterMute.Checked := True else cbMasterMute.Checked := False;
  lbMaster.Caption := Format('%1.3f', [VolMaster]);

  imgLeft.Top := 20 + (200 - Round(vLeft * 200));
  imgRight.Top := 20 + (200 - Round(vRight * 200));
  lbLeft.Caption := Format('%1.3f', [vLeft * 1]);
  lbRight.Caption := Format('%1.3f', [vRight * 1]);
  OldLeft := vLeft;
  OldRight := vRight;
  if vLeft <> vRight then ChannelFlag := True else ChannelFlag := False;
  if lbLeft.Caption <> lbRight.Caption then Led1.Visible := True else Led1.Visible := False;

  Percent := Round(VolumeLevel * 100);
  // FTaskBarList.SetProgressState(Application.handle, TBPF_Normal);
  case Round(VolumeLevel * 1000) of
   0 .. 749    : FTaskBarList.SetProgressState(Application.handle, TBPF_Normal);
   750 .. 1001 : FTaskBarList.SetProgressState(Application.handle, TBPF_Error);
  end; // end case of
  FTaskBarList.SetProgressValue(Application.handle, Percent, 100);
  SetPosition := True;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  reg1 := ((X > 7) and (X < 53));
  reg2 := ((X > 67) and (X < 93));
  reg3 := ((X > 103) and (X < 129));
end;

procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  if reg1 then
    begin
      if imgRegler1.Top > 20 then imgRegler1.Top := imgRegler1.Top - wheel;
      VolumeLevel := ( (200 - (imgRegler1.Top - 20)) / 200);
      SetMasterVolume;
    end;
  if ((reg2) or (reg3)) then
    begin
      if reg2 then
        if imgLeft.Top > 20 then imgLeft.Top := imgLeft.Top - wheel;
      if reg3 then
        if imgRight.Top > 20 then imgRight.Top := imgRight.Top - wheel;
      vLeft   := ( (200 - (imgLeft.Top - 20)) / 200);
      vRight  := ( (200 - (imgRight.Top - 20)) / 200);
      SetChannelsVolume;
    end;
end;

procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  if reg1 then
    begin
      if imgRegler1.Top < 220 then imgRegler1.Top := imgRegler1.Top + wheel;
      VolumeLevel := ( (200 - (imgRegler1.Top - 20)) / 200);
      SetMasterVolume;
    end;
  if reg2 or reg3 then
    begin
      if reg2 then
        if imgLeft.Top < 220 then imgLeft.Top := imgLeft.Top + wheel;
      if reg3 then
        if imgRight.Top < 220 then imgRight.Top := imgRight.Top + wheel;

      vLeft := ( (200 - (imgLeft.Top - 20)) / 200);
      vRight := ( (200 - (imgRight.Top - 20)) / 200);
      SetChannelsVolume;
    end;
end;

procedure TForm1.SetMasterVolume;
begin
   if endpointVolume = nil then Exit;
  cbMasterMute.Checked := False;
  OldVolume  := VolumeLevel;
  OldLeft := vLeft;
  OldRight := vRight;
   endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
  lbMaster.Caption := Format('%1.3f', [VolumeLevel]);
  FormShow(Self);
end;

procedure TForm1.SetChannelsVolume;
begin
  if endpointVolume = nil then Exit;
  endpointVolume.SetChannelVolumeLevelScalar(0, vLeft, nil);
   endpointVolume.SetChannelVolumeLevelScalar(1, vRight, nil);
  lbLeft.Caption := Format('%1.3f', [vLeft * 1]);
  lbRight.Caption := Format('%1.3f', [vRight * 1]);
  SetMasterVolume;
end;

procedure TForm1.SetChannelsFlagVolume;
begin
  if endpointVolume = nil then Exit;
  endpointVolume.SetChannelVolumeLevelScalar(0, OldLeft, nil);
   endpointVolume.SetChannelVolumeLevelScalar(1, OldRight, nil);
  lbLeft.Caption := Format('%1.3f', [OldLeft * 1]);
  lbRight.Caption := Format('%1.3f', [OldRight * 1]);
  //SetMasterVolume;
end;

procedure TForm1.imgLeftClick(Sender: TObject);
begin
  vLeft := VolumeLevel;
  vRight := VolumeLevel;
  SetChannelsVolume;
  imgLeft.Top := imgRegler1.Top;
  imgRight.Top := imgRegler1.Top;

  FormShow(Self);
end;

procedure TForm1.Label5Click(Sender: TObject);
begin
  ShowMessage('Copyright : M.Huwert, 2010,  markus_huwert@yahoo.de');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  PosX := Form1.Left;
  PosY := Form1.Top;

  IFile := TIniFile.Create(ProgDir + 'mastervolume.ini');
  IFile.WriteInteger('Position', 'Left', PosX);
  IFile.WriteInteger('Position', 'Top', PosY);
  IFile.Free;
end;

procedure TForm1.WheelLabelClick(Sender: TObject);
begin
  if wheel = 4 then wheel := 1
    else if wheel = 2 then wheel := 4
      else if wheel = 1 then wheel := 2;
  WheelLabel.Caption := IntToStr(wheel);  
end;

end.
Bedienung durch Mouse-Wheel,
ein Klick auf den Regler für rechten oder linken Kanal gleicht beide wieder an,
falls rechts <> links

EWeiss 29. Jan 2017 16:59

AW: Zuweisung der Hauptlautstärke
 
Danke! Aber das ist für mich so nicht anwendbar. (Daher möchte ich auf einen Download verzichten)
Ich will das alles über eine Trackbar regeln mit 3 stellt das kein Problem dar.

Muss halt noch was tüfteln.

gruss

markus5766h 29. Jan 2017 17:38

AW: Zuweisung der Hauptlautstärke
 
wenn ich das richtig verstehe :
eine Trackbar für die Lautstärke und eine Trackbar für links/rechts . . .
Gesamtlautstärke und Channel rechts, Channel links können maximal den Wert 1 annehmen.
Mit einer Trackbar von -100 ... +100 wäre das doch machbar,
wobei man dann nur jeweils den verminderten Kanal reduzieren kann :
-100 ... < 0 : rechter Kanal := Lautstärke * ((TrakBar.Position*-1) / 100), linker Kanal = Lautstärke
> 0 ... 100 : linker Kanal := Lautstärke * (TrakBar.Position / 100), rechter Kanal = Lautstärke


. . . to be continued . . .

EWeiss 29. Jan 2017 17:46

AW: Zuweisung der Hauptlautstärke
 
Zitat:

eine Trackbar für die Lautstärke und eine Trackbar für links/rechts . . .
Ja wie in den Bildern gezeigt.

Dabei wird aber nicht berücksichtigt das wenn der linke bzw. rechte Kanal auf 0 steht
und ich dann diesen betätige der nicht 0 ist geht auch die Gesamtlautstärke runter und umgekehrt.
Zudem kann die Lautstärke auch 25 betragen destotrotz muss sich dann der rechte und linke Kanal Trackbar.Max gegeben falls anpassen.

Das ist einer der gründe warum ich die MaxVolPos des Slider ermittel um damit wenn möglich die Trackbar.Max Position zu verändern.
Das bereitet mir zur zeit noch Probleme weil in dem Fall der Lautstärkeregler sich ändert.
Das soll er aber nicht.

Kann man selbst testen wenn man die Regler seiner Soundkarte verändert.

Danke.
Wie gesagt muss noch was tüfteln mit der Zeit komme ich schon auf den Trichter ;)
Die Daten sind ja alle da muss sie nur richtig einsetzen.

gruss

markus5766h 29. Jan 2017 18:00

AW: Zuweisung der Hauptlautstärke
 
in diesem Fall musst Du wohl dann den Wert vor der Änderung (links / rechts) zwischenspeichern
und die Differenz nach dem li/re-Regeln wieder aufaddieren bzw. subtrahieren.
Ich habe aus diesem Grund meine Rechts-Links-Slider praktisch als "Schleppzeiger" angelegt,
d.h. beide Kanalregler folgen dem Hauptlautstärkeregler mit Ihrer aktuell eingestellten prozentualen
Differenz bis 1.0 oder 0 - woraus sich aber auch ein Regler (Trackbar) ableiten ließe.

EWeiss 29. Jan 2017 18:03

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von markus5766h (Beitrag 1360269)
in diesem Fall musst Du wohl dann den Wert vor der Änderung (links / rechts) zwischenspeichern
und die Differenz nach dem li/re-Regeln wieder aufaddieren bzw. subtrahieren.
Ich habe aus diesem Grund meine Rechts-Links-Slider praktisch als "Schleppzeiger" angelegt,
d.h. beide Kanalregler folgen dem Hauptlautstärkeregler mit Ihrer aktuell eingestellten prozentualen
Differenz bis 1.0 oder 0 - woraus sich aber auch ein Regler (Trackbar) ableiten ließe.

Ich lade mal eine Testversion hoch.
Testen tue ich das in dem ich die Registerkarte meiner Soundkarte öffne um dann zu verfolgen was dort geschieht.
Wenn ich jetzt keine Lösung finde kann es halt zur Final noch etwas dauern. (Kein Problem für mich.)

gruss

markus5766h 29. Jan 2017 18:16

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von EWeiss (Beitrag 1360270)
Ich lade mal eine Testversion hoch.
Testen tue ich das in dem ich die Registerkarte meiner Soundkarte öffne um dann zu verfolgen was dort geschieht.
Wenn ich jetzt keine Lösung finde kann es halt zur Final noch etwas dauern. (Kein Problem für mich.)

gruss

o.k. runtergeladen, ausprobiert, verstanden ...

den Effekt habe ich nicht, da ich die Lautstärke über
endpointVolume.SetChannelVolumeLevelScalar(0, OldLeft, nil);
endpointVolume.SetChannelVolumeLevelScalar(1, OldRight, nil);
setze.

EWeiss 29. Jan 2017 18:21

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von markus5766h (Beitrag 1360272)
Zitat:

Zitat von EWeiss (Beitrag 1360270)
Ich lade mal eine Testversion hoch.
Testen tue ich das in dem ich die Registerkarte meiner Soundkarte öffne um dann zu verfolgen was dort geschieht.
Wenn ich jetzt keine Lösung finde kann es halt zur Final noch etwas dauern. (Kein Problem für mich.)

gruss

o.k. runtergeladen, ausprobiert, verstanden ...

den Effekt habe ich nicht, da ich die Lautstärke über
endpointVolume.SetChannelVolumeLevelScalar(0, OldLeft, nil);
endpointVolume.SetChannelVolumeLevelScalar(1, OldRight, nil);
setze.

Ich denke mal ist nicht zu viel gesagt das dass nicht so einfach ist.
Aber manchmal kommt ein Geistesblitz dann funktioniert das ;)

Das setzen des rechten und linken Kanal ist kein Problem solange die Lautstärke 100% ist
Setzt man diese runter kann man beim ändern der Balance sehen das sich der Lautstärkeregler ändert. (Was er nicht soll)
Dafür ermittle ich die MasterVolPos um damit dieses Manko noch ausbügeln zu können.
Nur wie gesagt habe dafür noch keine Lösung.

gruss

markus5766h 29. Jan 2017 18:30

AW: Zuweisung der Hauptlautstärke
 
Liste der Anhänge anzeigen (Anzahl: 3)
Zitat:

Zitat von EWeiss (Beitrag 1360273)
...
Das setzen des rechten und linken Kanal ist kein Problem solange die Lautstärke 100% ist
Setzt man diese runter kann man beim ändern der Balance sehen das sich der Lautstärkeregler ändert. (Was er nicht soll)
Dafür ermittle ich die MasterVolPos um damit dieses Manko noch ausbügeln zu können.
Nur wie gesagt habe dafür noch keine Lösung.

gruss

Die Lautstärke ändert sich bei mir nicht - solange die einzelnen Kanäle nicht über den Wert
der Lautstärke geregelt werden - für mich war das damals der beste Weg.
siehe Screenshots

EWeiss 29. Jan 2017 18:34

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Die Lautstärke ändert sich bei mir nicht - solange die einzelnen Kanäle nicht über den Wert
der Lautstärke geregelt werden - für mich war das damals der beste Weg.
Ja das glaube ich dir weil du für jeden Regler eine Trackbar verwendest das ist bei mir genau so.
Ich kann aber in der Komponente aus Platzgründen keine 2 zusätzliche Trackbars einbauen.

Aber zu einer Lautstärkesteuerung gehört nun mal die Balance dazu. ;)

PS:
Ich würde aber an deiner stelle für
Delphi-Quellcode:
endpointVolume.SetChannelVolumeLevelScalar(0, OldLeft, nil);


eine gültige GUIDE vergeben bedenke es könnten auch andere Programme zur gleichen zeit die Lautstärke regeln.
Die GUIDE ist dafür gedacht zwischen den einzelnen Prozessen zu unterscheiden. (EventContext)

Zitat:

Context value for the IAudioEndpointVolumeCallback::OnNotify method. This parameter points to an event-context GUID. If the SetChannelVolumeLevelScalar call changes the volume level of the endpoint, all clients that have registered IAudioEndpointVolumeCallback interfaces with that endpoint will receive notifications. In its implementation of the OnNotify method, a client can inspect the event-context GUID to discover whether it or another client is the source of the volume-change event. If the caller supplies a NULL pointer for this parameter, the notification routine receives the context GUID value GUID_NULL.
Bedenke das nochmal.. ;)
Wenn du keine IAudioEndpointVolumeCallback verwendest so wie wir dann nutze GUID_NULL.

gruss

markus5766h 29. Jan 2017 18:42

AW: Zuweisung der Hauptlautstärke
 
deswegen ja auch meine Idee mit der Trackbar von -100 ... 100,
wobei 100 bzw. (-100*-1) dem aktuell eingestelltem Lautstärkewert entspricht.
In meinen Screenshots wäre dann 30 (bei einer Lautstärke von 65) 46,154 %
Werte < 0 : Rechts reduzieren
Werte > 0 : Links reduzieren
0 : beide Channels = Hauptlautstärke
somit bleibt immer ein Channel bei der Hauptlautstärke, wobei sich diese dann nicht verändert.

Die zwei Regler bei mir sind eigentlich nur aus optischen Gründen vorhanden . . .

EWeiss 29. Jan 2017 18:54

AW: Zuweisung der Hauptlautstärke
 
Ich überdenke das nochmal alles kann was dauern.
Falls jemand helfen möchte ein Test Projekt im TAudioVolume Thread wurde hochgeladen da kann sich jeder austoben.

gruss

markus5766h 29. Jan 2017 19:26

AW: Zuweisung der Hauptlautstärke
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hab' mal kurz meine Version mit einer Trackbar ausgestattet
(einfach auf's Formular gepappt, zum Test wird's gehen).

Die Änderungen sind mit "// BALANCE TEST" gekennzeichnet.

Code:
unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls, ComObj, ActiveX, MMDeviceApi, ComCtrls, ExtCtrls, IniFiles;

const
  CLSID_TaskbarList: TGUID = '{56fdf344-fd6d-11d0-958a-006097c9a090}';
  IID_ITaskbarList: TGUID = '{56FDF342-FD6D-11d0-958A-006097C9A090}';
  IID_ITaskbarList2: TGUID = '{602D4995-B13A-429b-A66E-1935E44F4317}';
  IID_ITaskbarList3: TGUID = '{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}';

type
  TBPF =  (TBPF_NOPROGRESS = 0,
           TBPF_INDETERMINATE = 1,
           TBPF_NORMAL = 2,
           TBPF_ERROR = 4,
           TBPF_PAUSED = 8);
  TBATF = (TBATF_USEMDITHUMBNAIL = 1,
           TBATF_USEMDILIVEPREVIEW = 2);

   ITaskbarList = interface(IUnknown)
      ['{56FDF342-FD6D-11d0-958A-006097C9A090}']
      function HrInit : HResult; stdcall;
      function AddTab(hWndOwner : HWND) : HResult; stdcall;
      function DeleteTab(hWndOwner : HWND) : HResult; stdcall;
      function ActivateTab(hWndOwner : HWND) : HResult; stdcall;
      function SetActiveAlt(hWndOwner : HWND) : HResult; stdcall;
   end; { ITaskbarList }

  ITaskbarList2 = interface(ITaskbarList)
    ['{602D4995-B13A-429b-A66E-1935E44F4317}']
    function MarkFullscreenWindow(wnd : HWND; fFullscreen : bool) : HResult; stdcall;
  end;

  ITaskbarList3 = interface (ITaskbarList2)
  ['{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}']
    function SetProgressValue (hWnd: HWND; ullCompleted: int64; ullTotal: int64): HResult; stdcall;
    function SetProgressState (hWnd: HWND; tbpFlags: TBPF): HResult; stdcall;
    function RegisterTab (hwndTab: HWND; hwndMDI: HWND): HResult; stdcall;
    function UnregisterTab (hwndTab: HWND): HResult; stdcall;
    function SetTabOrder (hwndTab: HWND; hwndInsertBefore: HWND): HResult; stdcall;
    function SetTabActive (hwndTab: HWND; hwndMDI: HWND; tbatFlags: TBATF): HResult; stdcall;
    function ThumbBarAddButtons (hWnd: HWND; cButtons: integer; pButtons: pointer): HResult; stdcall;
    function ThumbBarUpdateButtons (hWnd: HWND; cButtons: cardinal; pButtons: pointer): HResult; stdcall;
    function ThumbBarSetImageList (hWnd: HWND; himl: pointer): HResult; stdcall;
    function SetOverlayIcon (hWnd: HWND; hIcon: HICON; pszDescription: PWideChar): HResult; stdcall;
    function SetThumbnailTooltip (hWnd: HWND; pszTip: PWideChar): HResult; stdcall;
    function SetThumbnailClip (hWnd: HWND; prcClip: PRect): HResult; stdcall;
  end;

type
   TForm1 = class(TForm)
    imgRegler1: TImage;
    Label1: TLabel;
    imgLeft: TImage;
    imgRight: TImage;
    lbMaster: TLabel;
    cbMasterMute: TCheckBox;
    lbLeft: TLabel;
    lbRight: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Led1: TImage;
    Label5: TLabel;
    Panel1: TPanel;
    WheelLabel: TLabel;
    BalanceBar: TTrackBar;
      procedure FormCreate(Sender: TObject);
    procedure cbMasterMuteClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure SetMasterVolume;
    procedure SetChannelsVolume;
    procedure SetChannelsFlagVolume;
    procedure imgLeftClick(Sender: TObject);
    procedure Label5Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure WheelLabelClick(Sender: TObject);
    procedure BalanceBarChange(Sender: TObject);
   private
      { Private-Deklarationen }
    FTaskBarList : ITaskbarList3;
    SetPosition : Boolean;
    procedure OnMove(var Msg: TWMMove); message WM_MOVE;
   public
      { Public-Deklarationen }
   end;

type
 TepVolEvents = Procedure(f:byte) of object;


var
   Form1: TForm1;
   endpointVolume   : IAudioEndpointVolume = nil;
   deviceEnumerator : IMMDeviceEnumerator;
   defaultDevice    : IMMDevice;
   pProps           : IPropertyStore;
   epVolEvents      : TepVolEvents;
  VolumeLevel      : Single;
  OldVolume        : Single;
  OldLeft, OldRight : Single;
  vLeft, vRight    : Single;
  wheel            : Integer;
  reg1, reg2, reg3  : Boolean;

  IFile            : TIniFile;
  ProgDir          : String;
  PosX, PosY       : Integer;

implementation

{$R *.dfm}

function IsMouseOver(Control: TControl): Boolean;
var
  p: TPoint;
begin
  if GetCursorPos(p) then
  begin
    p := Control.ScreenToClient(p);
    Result := (p.X >= 0) and (p.X = 0) and (p.Y <= Control.Height) {AND Control.Visible};
  end
    else Result := False;
end;

var
   ChannelCnt              : Cardinal;
   ChannelLeft,ChannelRight : Single;
   VolMaster               : Single;
   VolMute                 : Bool;
  Percent                 : Integer;
  ChannelFlag             : Boolean;

procedure TForm1.OnMove(var Msg: TWMMove);
begin
  inherited;
  if SetPosition then
    begin
      PosX := Form1.Left;
      PosY := Form1.Top;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
begin
  SetPosition := False;
  ProgDir := ExtractFilePath(ParamStr(0));
  IFile  := TIniFile.Create(ProgDir + 'mastervolume.ini');
  PosX   := IFile.ReadInteger('Position', 'Left', 240);
  PosY   := IFile.ReadInteger('Position', 'Top', 240);
  IFile.Free;

  FTaskBarList := CreateComObject(CLSID_TaskbarList) as ITaskbarList3;
  ChannelFlag := False;
  Form1.DoubleBuffered := True;
  wheel := 2;
   CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
end;

procedure TForm1.cbMasterMuteClick(Sender: TObject);
begin

  if cbMasterMute.Checked then
    begin
      OldLeft := vLeft;
      OldRight := vRight;
      if endpointVolume = nil then Exit;
       VolumeLevel := 0;
       endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
      FTaskBarList.SetProgressState(Application.handle, TBPF_Indeterminate);
    end
      else
        begin
          if endpointVolume = nil then Exit;
          if not ChannelFlag then
            begin // not ChannelFlag
               VolumeLevel := OldVolume;
               endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
            end
              else SetChannelsFlagVolume; // ChannelFlag
          FormShow(self);
        end;
end;

procedure TForm1.FormShow(Sender: TObject);
var
  unbalanced : Boolean;
begin
  unbalanced := False;
  Form1.Left := PosX;
  Form1.Top := PosY;
 
   if deviceEnumerator = nil then begin ShowMessage('NIL'); Exit; end;
   deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
   if defaultDevice <> nil then defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
   endpointVolume.GetChannelCount(ChannelCnt);
   endpointVolume.GetMasterVolumeLevelScalar(VolMaster);
  VolumeLevel := VolMaster;
  imgRegler1.Top := 20 + (200 - Round(VolumeLevel * 200));
   endpointVolume.GetChannelVolumeLevelScalar(0,ChannelLeft);
   endpointVolume.GetChannelVolumeLevelScalar(1,ChannelRight);
  vLeft := ChannelLeft;
  vRight := ChannelRight;
   endpointVolume.GetMute(VolMute);
   if VolMute=True then cbMasterMute.Checked := True else cbMasterMute.Checked := False;
  lbMaster.Caption := Format('%1.3f', [VolMaster]);

  // BALANCE TEST
  unbalanced := (vLeft <> vRight);
  if unbalanced then
    begin
      if vLeft < VolumeLevel then BalanceBar.Position := Round(0 + (100-(100/VolumeLevel*vLeft)));
      if vRight < VolumeLevel then BalanceBar.Position := Round(0 - (100-(100/VolumeLevel*vRight)));
    end
      else BalanceBar.Position := 0;
  // BALANCE TEST  

  imgLeft.Top := 20 + (200 - Round(vLeft * 200));
  imgRight.Top := 20 + (200 - Round(vRight * 200));
  lbLeft.Caption := Format('%1.3f', [vLeft * 1]);
  lbRight.Caption := Format('%1.3f', [vRight * 1]);
  OldLeft := vLeft;
  OldRight := vRight;
  if vLeft <> vRight then ChannelFlag := True else ChannelFlag := False;
  if lbLeft.Caption <> lbRight.Caption then Led1.Visible := True else Led1.Visible := False;

  Percent := Round(VolumeLevel * 100);
  // FTaskBarList.SetProgressState(Application.handle, TBPF_Normal);
  case Round(VolumeLevel * 1000) of
   0 .. 749    : FTaskBarList.SetProgressState(Application.handle, TBPF_Normal);
   750 .. 1001 : FTaskBarList.SetProgressState(Application.handle, TBPF_Error);
  end; // end case of
  FTaskBarList.SetProgressValue(Application.handle, Percent, 100);
  SetPosition := True;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  reg1 := ((X > 7) and (X < 53));
  reg2 := ((X > 67) and (X < 93));
  reg3 := ((X > 103) and (X < 129));
end;

procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  if reg1 then
    begin
      if imgRegler1.Top > 20 then imgRegler1.Top := imgRegler1.Top - wheel;
      VolumeLevel := ( (200 - (imgRegler1.Top - 20)) / 200);
      SetMasterVolume;
    end;
  if ((reg2) or (reg3)) then
    begin
      if reg2 then
        if imgLeft.Top > 20 then imgLeft.Top := imgLeft.Top - wheel;
      if reg3 then
        if imgRight.Top > 20 then imgRight.Top := imgRight.Top - wheel;
      vLeft   := ( (200 - (imgLeft.Top - 20)) / 200);
      vRight  := ( (200 - (imgRight.Top - 20)) / 200);
      SetChannelsVolume;
    end;
end;

procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  if reg1 then
    begin
      if imgRegler1.Top < 220 then imgRegler1.Top := imgRegler1.Top + wheel;
      VolumeLevel := ( (200 - (imgRegler1.Top - 20)) / 200);
      SetMasterVolume;
    end;
  if reg2 or reg3 then
    begin
      if reg2 then
        if imgLeft.Top < 220 then imgLeft.Top := imgLeft.Top + wheel;
      if reg3 then
        if imgRight.Top < 220 then imgRight.Top := imgRight.Top + wheel;

      vLeft := ( (200 - (imgLeft.Top - 20)) / 200);
      vRight := ( (200 - (imgRight.Top - 20)) / 200);
      SetChannelsVolume;
    end;
end;

procedure TForm1.SetMasterVolume;
begin
   if endpointVolume = nil then Exit;
  cbMasterMute.Checked := False;
  OldVolume  := VolumeLevel;
  OldLeft := vLeft;
  OldRight := vRight;
   endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
  lbMaster.Caption := Format('%1.3f', [VolumeLevel]);
  FormShow(Self);
end;

procedure TForm1.SetChannelsVolume;
begin
  if endpointVolume = nil then Exit;
  endpointVolume.SetChannelVolumeLevelScalar(0, vLeft, nil);
   endpointVolume.SetChannelVolumeLevelScalar(1, vRight, nil);
  lbLeft.Caption := Format('%1.3f', [vLeft * 1]);
  lbRight.Caption := Format('%1.3f', [vRight * 1]);
  SetMasterVolume;
end;

procedure TForm1.SetChannelsFlagVolume;
begin
  if endpointVolume = nil then Exit;
  endpointVolume.SetChannelVolumeLevelScalar(0, OldLeft, nil);
   endpointVolume.SetChannelVolumeLevelScalar(1, OldRight, nil);
  lbLeft.Caption := Format('%1.3f', [OldLeft * 1]);
  lbRight.Caption := Format('%1.3f', [OldRight * 1]);
  //SetMasterVolume;
end;

procedure TForm1.imgLeftClick(Sender: TObject);
begin
  vLeft := VolumeLevel;
  vRight := VolumeLevel;
  SetChannelsVolume;
  imgLeft.Top := imgRegler1.Top;
  imgRight.Top := imgRegler1.Top;

  FormShow(Self);
end;

procedure TForm1.Label5Click(Sender: TObject);
begin
  ShowMessage('Copyright : M.Huwert, 2010,  markus_huwert@yahoo.de');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  PosX := Form1.Left;
  PosY := Form1.Top;

  IFile := TIniFile.Create(ProgDir + 'mastervolume.ini');
  IFile.WriteInteger('Position', 'Left', PosX);
  IFile.WriteInteger('Position', 'Top', PosY);
  IFile.Free;
end;

procedure TForm1.WheelLabelClick(Sender: TObject);
begin
  if wheel = 4 then wheel := 1
    else if wheel = 2 then wheel := 4
      else if wheel = 1 then wheel := 2;
  WheelLabel.Caption := IntToStr(wheel);  
end;

// BALANCE TEST
procedure TForm1.BalanceBarChange(Sender: TObject);
begin
  if BalanceBar.Position = 0 then
    begin
      vLeft := VolumeLevel;
      vRight := VolumeLevel;
    end;
  if BalanceBar.Position < 0 then
    begin
      vLeft := VolumeLevel;
      vRight := VolumeLevel/100*(100-BalanceBar.Position*-1);
    end;
  if BalanceBar.Position > 0 then
    begin
      vRight := VolumeLevel;
      vLeft := VolumeLevel/100*(100-BalanceBar.Position);
    end;

      SetChannelsVolume;
end;
// BALANCE TEST

end.

EWeiss 29. Jan 2017 19:35

AW: Zuweisung der Hauptlautstärke
 
Danke für die mühe werde das mal durchgehen.
Ist das gleich wie bei mir. (Das geht auch mit meiner Balance in TAudioVolume)

PS:
Du verwendest leider keine Callback deshalb kann ich das nicht testen wie es sich verhält wenn
die Gesamtlautstärke nur 25% ist.

gruss

markus5766h 29. Jan 2017 19:38

AW: Zuweisung der Hauptlautstärke
 
... lässt sich bestimmt noch verbessern, z.B. BalanceBar.OnChange könnte man per case of .. abhandeln,
aber für's Prinzip sollte es so mal reichen.

EWeiss 29. Jan 2017 19:44

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von markus5766h (Beitrag 1360280)
... lässt sich bestimmt noch verbessern, z.B. BalanceBar.OnChange könnte man per case of .. abhandeln,
aber für's Prinzip sollte es so mal reichen.

Was passiert wenn zur Laufzeit die Gesamtlautstärke verändert wird?
Wie gesagt kann ich nicht testen da du kein Callback verwendest.

Ansonsten ist es so wie ich mir das vorstelle.

Danke für deine Mühe.
Werde versuchen das mal so bei mir umzusetzen.

gruss

markus5766h 29. Jan 2017 19:56

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von EWeiss (Beitrag 1360281)
Was passiert wenn zur Laufzeit die Gesamtlautstärke verändert wird?
Wie gesagt kann ich nicht testen da du kein Callback verwendest.
gruss

... nichts, das hatte ich damals nicht vorgesehen, bei einem Callback müssten die Werte
wie im Bereich Form.OnShow zugewiesen werden.

EWeiss 29. Jan 2017 19:59

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von markus5766h (Beitrag 1360282)
Zitat:

Zitat von EWeiss (Beitrag 1360281)
Was passiert wenn zur Laufzeit die Gesamtlautstärke verändert wird?
Wie gesagt kann ich nicht testen da du kein Callback verwendest.
gruss

... nichts, das hatte ich damals nicht vorgesehen, bei einem Callback müssten die Werte
wie im Bereich Form.OnShow zugewiesen werden.

Ok.. Werde es testen sollte kein Problem mehr sein dank deiner Hilfe.
Werde das Projekt aktualisieren wenn fertig.

gruss

EWeiss 29. Jan 2017 21:21

AW: Zuweisung der Hauptlautstärke
 
Hatte gerade was zeit zum implementieren aber funktioniert nicht.

Delphi-Quellcode:
function TAudioVolume.GetMasterBalance(): integer;
 var
  HR: HResult;
  f: Single;
  i: Integer;
  Chans: Uint;
  MasterVol: Single;
  VerifyChannels: BOOL;

begin
  Result := (tbMasterVolume.Max div 2); //Center 100% für alles

  if AudioEndpointVolume = nil then
    exit;

  HR := AudioEndpointVolume.GetChannelCount(Chans);
  if HR = S_OK then
  begin
    if Chans < 2 then
      exit;
  end else
  exit;

  for i := 0 to Chans - 1 do
  begin
    HR := AudioEndpointVolume.GetChannelVolumeLevelScalar(i, f);
    if HR = S_OK then
    begin
      case i of
        0:
          Channels.LeftVol := f;
        1:
          Channels.RightVol := f;
      end;
    end;
  end;

  MasterVol := GetMasterVolume;

  VerifyChannels := Channels.LeftVol <> Channels.RightVol;
  if VerifyChannels then
  begin
    if Channels.LeftVol < MasterVol then
      Result := Round(0 + (tbMasterBalance.Max -
        (tbMasterBalance.Max / MasterVol * Channels.LeftVol)))
    else
    if Channels.RightVol < MasterVol then
      Result := Round(0 - (tbMasterBalance.Max -
        (tbMasterBalance.Max / MasterVol * Channels.RightVol)));
  end;
end;
Delphi-Quellcode:
procedure TAudioVolume.tbMasterBalanceChange(Sender: TObject);
var
  MasterVol: single;
begin

  if AudioEndpointVolume = nil then
    exit;

  MasterVol := GetMasterVolume;

  if tbMasterBalance.Position = 0 then
  begin
    Channels.LeftVol := MasterVol;
    Channels.RightVol := MasterVol;
  end;
  if tbMasterBalance.Position < 0 then
  begin
    Channels.LeftVol := MasterVol;
    Channels.RightVol := MasterVol / tbMasterBalance.Max *
      (tbMasterBalance.Max - tbMasterBalance.Position * -1);
  end;
  if tbMasterBalance.Position > 0 then
  begin
    Channels.LeftVol := MasterVol / tbMasterBalance.Max *
      (tbMasterBalance.Max - tbMasterBalance.Position);
    Channels.RightVol := MasterVol;
  end;

  AudioEndpointVolume.SetChannelVolumeLevelScalar(0, Channels.LeftVol, @GUID_TAudioVolume);
  AudioEndpointVolume.SetChannelVolumeLevelScalar(1, Channels.RightVol, @GUID_TAudioVolume);
end;
Es ändert sich nur der Linke Kanal.
Hab erst mal genug muss mich mal mit was anderem beschäftigen.
Du darfst es aber gerne mit meinem Test Projekt versuchen.
Solche Probleme hatte ich schon lange nicht mehr. :duck: :wall:

PS:
Ich denke es liegt ganz einfach daran das du keine Callback verwendest deshalb ändert sich bei dir auch das MasterVolumen nicht.
Bei mir schon deshalb funktioniert deine Lösung nicht.

gruss

t.roller 30. Jan 2017 05:54

AW: Zuweisung der Hauptlautstärke
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von EWeiss (Beitrag 1360281)
Was passiert, wenn zur Laufzeit die Gesamtlautstärke verändert wird?

Wenn ich in einem Project die Lautstärke ändere, geschieht das relativ zur Gesamtlautstärke.
Stelle ich in einem Project 50%-Lautstärke ein und die Gesamtlautstärke ist 70%, dann ist die resultierende Project-Lautstärke tatsächlich 35%.
Ändere ich die Gesamtlautstärke, dann ändert sich auch die Project-Lautstärke - sie bleibt aber 50% der Gesamtlautstärke.

EWeiss 30. Jan 2017 10:10

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von t.roller (Beitrag 1360295)
Zitat:

Zitat von EWeiss (Beitrag 1360281)
Was passiert, wenn zur Laufzeit die Gesamtlautstärke verändert wird?

Wenn ich in einem Project die Lautstärke ändere, geschieht das relativ zur Gesamtlautstärke.
Stelle ich in einem Project 50%-Lautstärke ein und die Gesamtlautstärke ist 70%, dann ist die resultierende Project-Lautstärke tatsächlich 35%.
Ändere ich die Gesamtlautstärke, dann ändert sich auch die Project-Lautstärke - sie bleibt aber 50% der Gesamtlautstärke.

Ich weis jetzt nicht auf was du hinaus willst.
Aber es geht nicht um die Lautstärke der Anwendung das ist etwas ganz anderes.

gruss

mm1256 30. Jan 2017 15:46

AW: Zuweisung der Hauptlautstärke
 
Hallo Fangemeinde des musikalischen Hörgenusses,

ich bin kein Mathematiker und darum versuche ich es mal mit einfachen Worten zu erklären. Wenn man zwei Fader bzw. Werte (Volume rechts und links) mit einem einzigen Balance-Regler steuern will/muss/möchte dann ist das Maximum jeder Seite immer die Gesamtlautstärke und dann muss man ja nur noch abziehen:

Delphi-Quellcode:
procedure TFrmPlayer.BalanceChange(Sender: TObject);
var
  Vol, BalanceOffset, LeftVol, RightVol: Single;

  function CheckValue(const aValue: Single): Single;
  begin
    Result := aValue;
    if Result > 1.0 then Result := 1.0 else
    if Result < 0 then Result := 0;
  end;

begin
  Vol := GetMasterVolume;
  LeftVol := Vol;
  RightVol := Vol;
  BalanceOffset := Balance.Position * 0.01 * Vol; // Trackbar: Min = -100...Max = 100
  if BalanceOffset < 0 // Fader = links, Lautstärke rechts anpassen
  then RightVol := CheckValue(Vol + BalanceOffset) else
  if BalanceOffset > 0 // Fader = rechts, Lautstärke links anpassen
  then LeftVol := CheckValue(Vol - BalanceOffset);
  SetVolumeChannel(LeftVol, ch_LEFT);
  SetVolumeChannel(RightVol, ch_RIGHT);
end;
So funktioniert das zumindest bei mir. Die Adaption auf die Komponente dürfte dann wohl nicht mehr schwer fallen. HTH

Nachtrag: ch_LEFT und ch_RIGHT sind Konstanten die ich bei Bedarf vertauschen kann. Der User hat Ausgang-links => rechts angeschlossen ;-)

EWeiss 30. Jan 2017 15:51

AW: Zuweisung der Hauptlautstärke
 
Werde es mal testen Danke.

EDIT:
Nein Funktioniert nicht deine Auslegung ist auf 1 Kanal beschränkt.
Es ändert sich nur der Linke Kanal.

Wenn die Trackbar zentriert ist soll die erste Hälfte für den Linken Kanal
und die andere für den Rechten zuständig sein.

Aber du darfst es gerne selbst nochmal testen.

Delphi-Quellcode:
procedure TAudioVolume.tbMasterBalanceChange(Sender: TObject);
var
  Balance: single;
  Chans: UINT;
  Channels: TChannels;
  MasterVol: single;
  HR: HResult;
  BalanceOffset: Single;

  function CheckValue(const aValue: Single): Single;
   begin
     Result := aValue;
     if Result > 1.0 then Result := 1.0 else
     if Result < 0 then Result := 0;
   end;
begin

  if AudioEndpointVolume = nil then
    exit;

  HR := AudioEndpointVolume.GetChannelCount(Chans);
  if HR = S_OK then
  begin
    if Chans < 2 then
      exit;
  end else
  exit;

  MasterVol := GetMasterVolume();

  Channels.LeftVol := MasterVol;
  Channels.RightVol := MasterVol;

  BalanceOffset := tbMasterBalance.Position * 0.01;

  if BalanceOffset < 0 then
    Channels.RightVol := CheckValue(MasterVol + BalanceOffset)
  else
  if BalanceOffset > 0 then
    Channels.LeftVol := CheckValue(MasterVol - BalanceOffset);

  AudioEndpointVolume.SetChannelVolumeLevelScalar(0, Channels.LeftVol, @GUID_TAudioVolume);
  AudioEndpointVolume.SetChannelVolumeLevelScalar(1, Channels.RightVol, @GUID_TAudioVolume);

end;

gruss

EWeiss 30. Jan 2017 16:08

AW: Zuweisung der Hauptlautstärke
 
Funktioniert nicht siehe editierten Post drüber..

gruss

mm1256 30. Jan 2017 16:41

AW: Zuweisung der Hauptlautstärke
 
Bei mir in der Anwendung funktioniert es so. Dann hast du irgendwo anders noch ein Problem. Nur der Vollständigkeit halber: Bei mir Windows 10 und Delphi 10.1.

BTW das einzige mir bekannte Optimierungsmöglichkeit ist noch, dass man den Wert vom Trackbar nicht absolut sondern prozentual korrigiert. Bei einer Gesamtlautstärke von 1.0 spielt das keine Rolle, aber wenn die Laustärke weit unten ist, dann reagiert der Fader nicht linear.

Nachtrag: Hab es angepasst:
Delphi-Quellcode:
...
BalanceOffset := Balance.Position * 0.01 * Vol; // Trackbar: Min = -100...Max = 100

EWeiss 30. Jan 2017 16:51

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von mm1256 (Beitrag 1360393)
Bei mir in der Anwendung funktioniert es so. Dann hast du irgendwo anders noch ein Problem. Nur der Vollständigkeit halber: Bei mir Windows 10 und Delphi 10.1.

BTW das einzige mir bekannte Optimierungsmöglichkeit ist noch, dass man den Wert vom Trackbar nicht absolut sondern prozentual korrigiert. Bei einer Gesamtlautstärke von 1.0 spielt das keine Rolle, aber wenn die Laustärke weit unten ist, dann reagiert der Fader nicht linear.

Ich kann nur sagen das er auf nur einen Kanal ausgelegt ist.
der Linke Kanal wird von 0 > 100 verändert der Rechte bleibt von deinem Sample unberührt.

Ausgenommen davon das die Lautstärke über eine Callback geregelt wird gibt es keine anderen Probleme.

Mein Code..
Delphi-Quellcode:
  Balance := Max(-tbMasterBalance.Max, Min(tbMasterBalance.Max, tbMasterBalance.Position));

  leftVol := 1.0 - Max(0.0, (Balance / tbMasterBalance.Max));
  rightVol := 1.0 + Min(0.0, -leftVol);

  AudioEndpointVolume.SetChannelVolumeLevelScalar(0, (leftVol * Channels), @GUID_TAudioVolume);
  AudioEndpointVolume.SetChannelVolumeLevelScalar(1, (rightVol * Channels), @GUID_TAudioVolume);

Behandelt den rechten und linken Kanal gleichzeitig und funktioniert solange wie die Maixmale Lautstärke nicht verändert wird.

Siehe insbesondere auf "-leftVol"

EDIT:
Habe das mal auf das von dir verlinkte sample umgelegt.
Das veranschaulicht das Problem..
Stelle alle Trackbars auf max dann navigiere mit der Mittleren.


Ich muss wohl davon ausgehen das es über eine Trackbar wohl nicht machbar ist.

gruss

EWeiss 4. Feb 2017 11:53

AW: Zuweisung der Hauptlautstärke
 
Bitte wer Bock hat kann die Angehängte Datei gerne mal testen.
Die Balance sollte nun korrekt funktionieren.

Nebenbei:
Als Anmerkung alle hier versuchten Korrekturen (Beispiele) verwenden NUR 1 Kanal.
Das bedeutet der Linke Kanal wird ausgeschaltet der Rechte bleibt unberührt.
Dieses verhalten hat aber nichts mit einem Balance Regler zu tun.

Sollten positive Feedbacks kommen werde ich den Source von TAudioVolume Komponente aktualisieren.
Andernfalls muss ich davon ausgehen das es nicht funktioniert.

gruss

Delphi-Laie 4. Feb 2017 17:09

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von EWeiss (Beitrag 1360805)
Bitte wer Bock hat kann die Angehängte Datei gerne mal testen.
Die Balance sollte nun korrekt funktionieren.

Tut sie auf meinem Windows XP nicht. Es funktionieren ("nur") die Lautstärke und Mute der Summe.

EWeiss 4. Feb 2017 17:14

AW: Zuweisung der Hauptlautstärke
 
Zitat:

Zitat von Delphi-Laie (Beitrag 1360812)
Zitat:

Zitat von EWeiss (Beitrag 1360805)
Bitte wer Bock hat kann die Angehängte Datei gerne mal testen.
Die Balance sollte nun korrekt funktionieren.

Tut sie auf meinem Windows XP nicht. Es funktionieren ("nur") die Lautstärke und Mute der Summe.

Ja Danke..
Im Moment wird nur Win7 -> Unterstützt Balance für den (Mixer XP) wird noch kommen.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:26 Uhr.

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