Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Peak vom Audioausgang (https://www.delphipraxis.net/152935-peak-vom-audioausgang.html)

Masteric 13. Jul 2010 15:13

Peak vom Audioausgang
 
Hi,
gibt es eine Möglichkeit den Peak des Audioausgangs eines Rechners zu bekommen, so ähnlich wie beim Bassdllplayer? Oder eben den Auschlag, den Win 7 bei den Audiogeräten angezeigt wird(Levelmeter am Mischpult)? Wenn das nicht geht wäre es auch okay, wenn man ihn vom Aufnahmeeingang einlesen kann, ich müsste halt nur an den Peak kommen, der von ITunes, WMP o.ä ausgegeben wird.

Gibt es da eine Möglichkeit, am besten nicht zu umständlich aber jede Lösung wäre okay.

Gruß Masteric

turboPASCAL 13. Jul 2010 19:41

AW: Peak vom Audioausgang
 
Liste der Anhänge anzeigen (Anzahl: 2)
Joa, es gibt da ein paar Möglichkeiten...

mit der Bass.dll, siehe in den Beispielen nach (livefx.dpr)

oder über die WinAPI per "Fuss" ;)


(irgend ein User aus der DP hat dies Demo erstellt.. wer, weis ich leider nicht mehr )

igel457 13. Jul 2010 20:03

AW: Peak vom Audioausgang
 
Unter Windows 7/Vista solltest du relativ einfach über die "Core Audio"-Schnittstelle an diese Daten herankommen. Leider ist für WASAPI kein Header für Pascal vorhanden - im Notfall einfach mit Microsoft Visual Studio C eine kleine Bibliothek schreiben, die das kann.

Hier sind die nötigen Sachen detailiert beschrieben: http://msdn.microsoft.com/en-us/libr...=VS.85%29.aspx

Masteric 14. Jul 2010 15:44

AW: Peak vom Audioausgang
 
hallo und danke für die tipps schon mal!
so habe mir nun die Vorschläge angeschaut und habe gesehen, dass es doch etwas komplizierter ist mit dem Programm, da dieses die frequenzen noch aufteilt. Nun habe ich mir auch den 2. Vorschlag angeschaut und bemerkt, dass es da etwas einfach zu sein scheint. Da gibt es auf der MSDN sogar einen Vorschlag für ein Levelmeter, nur da ich leider kein VS habe und noch weniger c kann, wodurch das erstellen einer dll noch schwieriger ist wollte ich fragen, ob mir jemand eine dll erstellen kann mit dem Bsp. hier: http://msdn.microsoft.com/en-us/libr...=VS.85%29.aspx und am besten so, dass der peak nicht gezeichnet wird sondern z.B. in einer funktion abgerufen werden kann. Wäre echt super, da ich mich mit c oder dem hier verwendeten c++ so gar nicht auskenne.

Gruß Masteric

lbccaleb 14. Jul 2010 16:50

AW: Peak vom Audioausgang
 
Du kannst da auch auf DirectShow zugreifen...

igel457 14. Jul 2010 17:58

AW: Peak vom Audioausgang
 
Zitat:

Zitat von lbccaleb (Beitrag 1035309)
Du kannst da auch auf DirectShow zugreifen...

Hm... Den Zusammenhang zwischen Core Audio und DirectShow verstehe ich jetzt nicht wirklich...

himitsu 14. Jul 2010 18:06

AW: Peak vom Audioausgang
 
Vermutlich meint er DirectSound oder gleich XAudio 2? (sind alles Teile von DirectX)

Masteric 14. Jul 2010 18:22

AW: Peak vom Audioausgang
 
Da hier nun neue begriffe im raum stehen, gibt es eine möglichkeit an die daten des levelmeters zu kommen? Am besten eine, die mir prozent oder einen wert ausgibt, mit dem ich die prozent ausrechnen kann? Vielleicht schon eine fertige dll?
Gruß Masteric

Masteric 14. Jul 2010 18:54

AW: Peak vom Audioausgang
 
Ich habe eben nochmal auf MSDN ein bisschen gestöbert und das hier LINK gefunden und denke mal, dass das das ist was ich suche, jedoch weiss ich nicht wie ich diese funktion implementieren soll, ohne den headder und da ich mir auch keine dll aus dem c++ code erstellen kann(wie gesagt, fehlende Software und knowhow) wollte ich fragen, ob diese funktion erstmal das ist was ich suche und ob es eine möglichkeit gibt sie in delphi zu implementieren...


gruß masteric

lbccaleb 14. Jul 2010 19:26

AW: Peak vom Audioausgang
 
Wie man das ganze mit DirectShow lösen kann wird HIER gezeigt. Allerdings ist das schon ne ganze Ecke komplizierter als noch mit purer DirectShow Unit oder DSPack zu programmieren.

Möchtest du jetzt angezeigt bekommen, wie der Pegel direkt am Ausgang ist oder wie er in Windows ist?

Wenn du zb einen Film in Windows auf volle Lautstärke abspielst, kannst du am Ausgang auch keinen Ausschlag haben, wenn in Windows der "Main-Pegel" auf null steht.

himitsu 14. Jul 2010 19:29

AW: Peak vom Audioausgang
 
GetPeakValue ist eine Methode des Interfaces IAudioMeterInformation.

IAudioMeterInformation müßtest du also irgendwie importieren.


Bei Google suchenIAudioMeterInformation Delphi

http://social.msdn.microsoft.com/For...9-2e27eb9ec058
http://www.experts-exchange.com/Prog..._25085582.html

lbccaleb 14. Jul 2010 19:38

AW: Peak vom Audioausgang
 
Mit himitsus Bsp. konnte ich jetzt auf die schnelle das hier finden:

Zitat:

it's work in Delphi 7
//////////////////////////

Delphi-Quellcode:
unit MMDevApi;

interface

uses
  Windows, ActiveX, ComObj;

const
  CLASS_IMMDeviceEnumerator            : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
  IID_IMMDeviceEnumerator              : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
  IID_IMMDevice                        : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
  IID_IMMDeviceCollection              : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
  IID_IAudioEndpointVolume             : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
  IID_IAudioMeterInformation           : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
  IID_IAudioEndpointVolumeCallback     : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';

  DEVICE_STATE_ACTIVE                  = $00000001;
  DEVICE_STATE_UNPLUGGED               = $00000002;
  DEVICE_STATE_NOTPRESENT              = $00000004;
  DEVICE_STATEMASK_ALL                 = $00000007;

type
  EDataFlow = TOleEnum;

const
  eRender                              = $00000000;
  eCapture                             = $00000001;
  eAll                                 = $00000002;
  EDataFlow_enum_count                 = $00000003;

type
  ERole = TOleEnum;

const
  eConsole                             = $00000000;
  eMultimedia                          = $00000001;
  eCommunications                      = $00000002;
  ERole_enum_count                     = $00000003;

type
  IAudioEndpointVolumeCallback = interface(IUnknown)
  ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
  end;

  IAudioEndpointVolume = interface(IUnknown)
  ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
    function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
    function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
    function GetChannelCount(out PInteger): Integer; stdcall;
    function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
    function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
    function GetMasterVolumeLevel(out fLevelDB: single): Integer; stdcall;
    function GetMasterVolumeLevelScaler(out fLevelDB: single): Integer; stdcall;
    function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
    function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
    function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double): Integer; stdcall;
    function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double): Integer; stdcall;
    function SetMute(bMute: Boolean; pguidEventContext: PGUID): Integer; stdcall;
    function GetMute(out bMute: Boolean): Integer; stdcall;
    function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): Integer; stdcall;
    function VolumeStepUp(pguidEventContext: PGUID): Integer; stdcall;
    function VolumeStepDown(pguidEventContext: PGUID): Integer; stdcall;
    function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;
    function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;
  end;

  IAudioMeterInformation = interface(IUnknown)
  ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
  end;

  IPropertyStore = interface(IUnknown)
  end;

  IMMDevice = interface(IUnknown)
  ['{D666063F-1587-4E43-81F1-B948E807363F}']
    function Activate(const refId: TGUID;
                      dwClsCtx: DWORD;
                      pActivationParams: PInteger;
                      out pEndpointVolume: IAudioEndpointVolume): Hresult; stdCall;
    function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): Hresult; stdcall;
    function GetId(out ppstrId: PLPWSTR): Hresult; stdcall;
    function GetState(out State: Integer): Hresult; stdcall;
  end;


  IMMDeviceCollection = interface(IUnknown)
  ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
  end;

  IMMNotificationClient = interface(IUnknown)
  ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
  end;

  IMMDeviceEnumerator = interface(IUnknown)
  ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
    function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection: IMMDeviceCollection): Hresult; stdcall;
    function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult; stdcall;
    function GetDevice(pwstrId: pointer; out Dev: IMMDevice): HResult; stdcall;
    function RegisterEndpointNotificationCallback(pClient: IMMNotificationClient): Hresult; stdcall;
  end;

implementation

end.
Delphi-Quellcode:
///////////////////////
simple sample :)
///////////////////////

//...... other code

uses ... ActiveX, MMDevApi, ...;

//...... other code

var
  endpointVolume: IAudioEndpointVolume = nil;

procedure TForm1.FormCreate(Sender: TObject);
var
  deviceEnumerator: IMMDeviceEnumerator;
  defaultDevice: IMMDevice;
begin
  CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
  deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
  defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  VolumeLevel: Single;
begin
  if endpointVolume = nil then Exit;
  VolumeLevel := 0.50;
  endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
  Caption := Format('%1.8f', [VolumeLevel])
end;
/////////////////////////////////////

// with best regards ToxicDream

Edit:
Nicht getestet :)

Masteric 14. Jul 2010 20:37

AW: Peak vom Audioausgang
 
mich würde es direkt am ausgang interessieren, also was auf die lautsprecher rausgeht,

Masteric 14. Jul 2010 22:12

AW: Peak vom Audioausgang
 
Zitat:

Zitat von lbccaleb (Beitrag 1035334)
Mit himitsus Bsp. konnte ich jetzt auf die schnelle das hier finden:

Zitat:

it's work in Delphi 7
//////////////////////////

Delphi-Quellcode:
unit MMDevApi;

interface

uses
  Windows, ActiveX, ComObj;

const
  CLASS_IMMDeviceEnumerator            : TGUID = '{BCDE0395-E52F-467C-8E3D-C4579291692E}';
  IID_IMMDeviceEnumerator              : TGUID = '{A95664D2-9614-4F35-A746-DE8DB63617E6}';
  IID_IMMDevice                        : TGUID = '{D666063F-1587-4E43-81F1-B948E807363F}';
  IID_IMMDeviceCollection              : TGUID = '{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}';
  IID_IAudioEndpointVolume             : TGUID = '{5CDF2C82-841E-4546-9722-0CF74078229A}';
  IID_IAudioMeterInformation           : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';
  IID_IAudioEndpointVolumeCallback     : TGUID = '{657804FA-D6AD-4496-8A60-352752AF4F89}';

  DEVICE_STATE_ACTIVE                  = $00000001;
  DEVICE_STATE_UNPLUGGED               = $00000002;
  DEVICE_STATE_NOTPRESENT              = $00000004;
  DEVICE_STATEMASK_ALL                 = $00000007;

type
  EDataFlow = TOleEnum;

const
  eRender                              = $00000000;
  eCapture                             = $00000001;
  eAll                                 = $00000002;
  EDataFlow_enum_count                 = $00000003;

type
  ERole = TOleEnum;

const
  eConsole                             = $00000000;
  eMultimedia                          = $00000001;
  eCommunications                      = $00000002;
  ERole_enum_count                     = $00000003;

type
  IAudioEndpointVolumeCallback = interface(IUnknown)
  ['{657804FA-D6AD-4496-8A60-352752AF4F89}']
  end;

  IAudioEndpointVolume = interface(IUnknown)
  ['{5CDF2C82-841E-4546-9722-0CF74078229A}']
    function RegisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
    function UnregisterControlChangeNotify(AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
    function GetChannelCount(out PInteger): Integer; stdcall;
    function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
    function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID): Integer; stdcall;
    function GetMasterVolumeLevel(out fLevelDB: single): Integer; stdcall;
    function GetMasterVolumeLevelScaler(out fLevelDB: single): Integer; stdcall;
    function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
    function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: double; pguidEventContext: PGUID): Integer; stdcall;
    function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: double): Integer; stdcall;
    function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: double): Integer; stdcall;
    function SetMute(bMute: Boolean; pguidEventContext: PGUID): Integer; stdcall;
    function GetMute(out bMute: Boolean): Integer; stdcall;
    function GetVolumeStepInfo(pnStep: Integer; out pnStepCount: Integer): Integer; stdcall;
    function VolumeStepUp(pguidEventContext: PGUID): Integer; stdcall;
    function VolumeStepDown(pguidEventContext: PGUID): Integer; stdcall;
    function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;
    function GetVolumeRange(out pflVolumeMindB: double; out pflVolumeMaxdB: double; out pflVolumeIncrementdB: double): Integer; stdcall;
  end;

 [COLOR="Red"] IAudioMeterInformation = interface(IUnknown)[/COLOR]
  ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
  end;

  IPropertyStore = interface(IUnknown)
  end;

  IMMDevice = interface(IUnknown)
  ['{D666063F-1587-4E43-81F1-B948E807363F}']
    function Activate(const refId: TGUID;
                      dwClsCtx: DWORD;
                      pActivationParams: PInteger;
                      out pEndpointVolume: IAudioEndpointVolume): Hresult; stdCall;
    function OpenPropertyStore(stgmAccess: DWORD; out ppProperties: IPropertyStore): Hresult; stdcall;
    function GetId(out ppstrId: PLPWSTR): Hresult; stdcall;
    function GetState(out State: Integer): Hresult; stdcall;
  end;


  IMMDeviceCollection = interface(IUnknown)
  ['{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}']
  end;

  IMMNotificationClient = interface(IUnknown)
  ['{7991EEC9-7E89-4D85-8390-6C703CEC60C0}']
  end;

  IMMDeviceEnumerator = interface(IUnknown)
  ['{A95664D2-9614-4F35-A746-DE8DB63617E6}']
    function EnumAudioEndpoints(dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection: IMMDeviceCollection): Hresult; stdcall;
    function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult; stdcall;
    function GetDevice(pwstrId: pointer; out Dev: IMMDevice): HResult; stdcall;
    function RegisterEndpointNotificationCallback(pClient: IMMNotificationClient): Hresult; stdcall;
  end;

implementation

end.
Delphi-Quellcode:
///////////////////////
simple sample :)
///////////////////////

//...... other code

uses ... ActiveX, MMDevApi, ...;

//...... other code

var
  endpointVolume: IAudioEndpointVolume = nil;

procedure TForm1.FormCreate(Sender: TObject);
var
  deviceEnumerator: IMMDeviceEnumerator;
  defaultDevice: IMMDevice;
begin
  CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
  deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
  defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  VolumeLevel: Single;
begin
  if endpointVolume = nil then Exit;
  VolumeLevel := 0.50;
  endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
  Caption := Format('%1.8f', [VolumeLevel])
end;
/////////////////////////////////////

// with best regards ToxicDream

Edit:
Nicht getestet :)

Geht leider nicht so ganz, es gibt nur die aktuelle Lautstärke aus und setzt sie vorher auf 50% er sollte aber eher den momentanen peak anzeigen, aber trotzdem danke :thumb: , denn hier steck die funktion aus der msdn drinnen, die ich brauche nämlich die IAudioMeterInformation ich versuche die gerade zu nutzen komme aber da nicht so richtig weiter, da dies mein wissen übersteigt, vielleicht hat da ja noch jemand einen tipp für mich?

himitsu 15. Jul 2010 06:24

AW: Peak vom Audioausgang
 
spotan würde ich mal sagen, du mußt nur noch das richtige Interface abfragen.
Delphi-Quellcode:
defaultDevice.Activate(IID_..., CLSCTX_INPROC_SERVER, nil, ...);
.


Delphi-Quellcode:
var
  audioMeterInformation: IAudioMeterInformation;

procedure TForm1.FormCreate(Sender: TObject);
var
  deviceEnumerator: IMMDeviceEnumerator;
  defaultDevice: IMMDevice;
begin
  CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
  deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
  defaultDevice.Activate(IID_IAudioMeterInformation, CLSCTX_INPROC_SERVER, nil, audioMeterInformation);
end;

var H: HRESULT;

H := audioMeterInformation.GetPeakValue(Peak);
if H = S_OK then Peak_anzeigen else ShowMessage(SysErrorMessage(H));
leider hat sich hier aber jemand viel Arbeit erspart und das Intereface nicht komplett deklariert (den Inhalt einfach weggelassen)

Delphi-Quellcode:
const
  IID_IAudioMeterInformation : TGUID = '{C02216F6-8C67-4B5B-9D00-D008E73E0064}';

IAudioMeterInformation = interface(IUnknown)
  ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
  ...
  function GetPeakValue(out Peak: Real): HRESULT; stdcall;
  ...
end;
Bei Interfaces kommt es aber auf die Reihenfolge der Methoden an
(hier wird meißtens über den Index und nicht über Methodenname gearbeitet)
darum mußt du nur noch den Rest der Interfacedeklaration (oder zumindestens die Anzahl der Methoden vor deiner gewünschten Methode) rausbekommen > MSDN-Library durchsuchenIAudioMeterInformation
Das schon bekannte GetPeakValue ließ sich leicht übersetzen und einfügen.

Delphi-Quellcode:
IAudioMeterInformation = interface(IUnknown)
  ['{C02216F6-8C67-4B5B-9D00-D008E73E0064}']
  procedure dummy_GetChannelsPeakValues; stdcall;
  procedure dummy_GetMeteringChannelCount; stdcall;
  function GetPeakValue(out Peak: Real): HRESULT; stdcall;
  procedure dummy_QueryHardwareSupport; stdcall;
end;
Die Deklaration der restlichen Methoden ist aber auch noch im MSDN zu finden.

PS: dort stand auch, wie man dieses Interface bekommt.
Zitat:

The client obtains a reference to the IAudioMeterInformation interface on an endpoint object by calling the IMMDevice::Activate method with parameter iid set to REFIID IID_IAudioMeterInformation.
Und auch die zu erwartenden Wertebereiche des Peak-Parameters kann man dort finden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 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