Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi GetChannelsPeakValues (https://www.delphipraxis.net/215157-getchannelspeakvalues.html)

DaCoda 18. Mai 2024 22:11

GetChannelsPeakValues
 
Hallo,
ich hab mich da etwas mit GetChannelsPeakValues verzettelt und finde die Lösung einfach nicht.
Hat da jemand einen Tip ?

Code:
procedure TfrmMain.Timer100msTimer(Sender: TObject);
var
  Levels: array[0..1] of Single;
  ChannelCount: UInt;
begin
  Peak.GetMeteringChannelCount(ChannelCount);
  if (ChannelCount = 2) then begin

    (* NUR ZUR AUFRUF-INFO:
    IAudioMeterInformation = interface(IUnknown)
      ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
      function GetPeakValue(out pfPeak: Single): HRESULT; stdcall;
      function GetMeteringChannelCount(out pnChannelCount: UINT): HRESULT; stdcall;
      function GetChannelsPeakValues(u32ChannelCount: UINT; out afPeakValues: pSingle): HRESULT; stdcall;
      function QueryHardwareSupport(out pdwHardwareSupportMask: UINT): HRESULT; stdcall;
    end;
    *)
   
    Peak.GetChannelsPeakValues(ChannelCount, @Levels[0]); <- Hier hab ich mich festgefummelt mit dem @Levels, das ist falsch! Soll ja pSingle sein (?)
    VuMeterL.Position := Round(Levels[0] * 100);
    VuMeterR.Position := Round(Levels[1] * 100);
  end else begin
    Peak.GetPeakValue(Levels[0]);
    VuMeterL.Position := Round(Levels[0] * 100);
    VuMeterR.Position := VuMeterL.Position;
  end;
end;

Kas Ob. 19. Mai 2024 09:48

AW: GetChannelsPeakValues
 
Hi,

From my own tested and working code :
Code:
  //Peak.GetChannelsPeakValues(ChannelCount, @Levels[0]); <- Hier hab ich mich festgefummelt mit dem @Levels, das ist falsch! Soll ja pSingle sein (?)
  // should be
  Peak.GetChannelsPeakValues(ChannelCount, pSingle(@Levels[0]));
Also you can use absolute to eliminate the use of casting.

DaCoda 19. Mai 2024 11:54

AW: GetChannelsPeakValues
 
Thank you for your Answer,

I have made a modification in the procedure:
Code:
procedure TfrmMain.Timer100msTimer(Sender: TObject);
var
  ChannelCount: UInt;
  PeakLevels: array[0..1] of Single;
  poPeakLevels: PSingle;

  procedure ClearPeakLevels;
  begin
    PeakLevels[0] := MinProzentValue;
    PeakLevels[1] := MinProzentValue;
  end;

begin
  ClearPeakLevels;
  Peak.GetMeteringChannelCount(ChannelCount);
  if (ChannelCount = 2) then begin
    poPeakLevels := pSingle(@PeakLevels[0]);
    if Succeeded(Peak. GetChannelsPeakValues(ChannelCount, poPeakLevels)) then begin
      VuMeterL.Position := Round(PeakLevels[0] * MaxProzentValue);
      VuMeterR.Position := Round(PeakLevels[1] * MaxProzentValue);
    end else begin
      ClearPeakLevels;
    end;
  end else begin
    if Succeeded(Peak.GetPeakValue(PeakLevels[0])) then begin
      VuMeterL.Position := Round(PeakLevels[0] * MaxProzentValue);
      VuMeterR.Position := VuMeterL.Position;
    end else begin
      ClearPeakLevels;
    end;
  end;
end;
Now i have no errors, but the PeakValues are everytime 0.0
The Rsult from Peak.GetPeakValues = S_Ok
Now i have no Idea was is wrong...

DaCoda 19. Mai 2024 12:10

AW: GetChannelsPeakValues
 
Nun ist der Groschen gefallen :-D

So hat es dann geklappt:
Code:
if Succeeded(Peak. GetChannelsPeakValues(ChannelCount, pSingle(PeakLevels))) then begin
  VuMeterL.Position := Round(PeakLevels[0] * MaxProzentValue);
  VuMeterR.Position := Round(PeakLevels[1] * MaxProzentValue);
end
Vielen Dank Kas Ob. :spin2:

Kas Ob. 19. Mai 2024 12:25

AW: GetChannelsPeakValues
 
Liste der Anhänge anzeigen (Anzahl: 1)
Glad it did help !

Just few points :
1) No need to ClearPeakLevels, they will be overwritten if the GetPeakValue was success.
2) By using timer you are losing too much volume calculations and it will not be so accurate, it is better to capture the sound and only then assuming you are capturing 1/20 or 1/50 (preferably) in a second then on that event (or callback) get the peak volume hence you will have exactly the same values you in Sound Control Panel. (you can replicate the same volume the system show , pointed in a screenshot)
3) you can use absolute and make it cleaner
Code:
var
  ChannelCount: UInt;
  PeakLevels: array[0..1] of Single;
  pPeakLevels: PSingle absolute PeakLevels;

Anhang 56841

DaCoda 19. Mai 2024 12:56

AW: GetChannelsPeakValues
 
@Kas Ob.

Thank you, i have made your suggestions. And it works perfect!


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:42 Uhr.

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