Peak meters for individual programs on Windows 7
Asked Answered
I

3

13

Is it possible to obtain the peak meter readings for individual programs on Windows 7, and if so, how?

With WASAPI one can capture the entire system audio through a loopback device, but this does not differentiate between outputs from different programs. This question regards capturing audio for a single specified application, but the answers seem prohibitive when dealing with capturing all programs that are playing audio individually. This must be possible because SndVol can do it, as shown in the image below. The question is how is it being accomplished? Is it being done through unexposed API calls or is it actually possible to achieve something like this through WASAPI as well?

enter image description here

Thanks.

Ivatts answered 14/1, 2013 at 5:29 Comment(0)
S
14

You are enumerating audio sessions and getting IAudioSessionControl interfaces (MSDN code snippet). The missing part is that you can query IAudioMeterInformation inteface from IAudioSessionControl you are already holding.

If the audio endpoint supports peak meters, you will be able to obtain this interface, and use IMeterInformation::GetPeakValue for individual sessions. And this is what SndVol supposedly doing.

Here is a piece of code that does the thing:

CComPtr<IAudioSessionControl> pSessionControl;
...
CComQIPtr<IAudioMeterInformation> pMeterInformation = pSessionControl;
FLOAT fPeakValue;
pMeterInformation->GetPeakValue(&fPeakValue);
_tprintf(_T("nSessionIndex %d, fPeakValue %.2f\n"), nSessionIndex, fPeakValue);
Safe answered 16/1, 2013 at 21:5 Comment(7)
Hey, I liked how you shared the larger piece of code without cluttering things up here. I'm going to use your idea when I need to do something like that to help someone with a question. (I'm kinda new here.)Ascites
Thanks! That worked as a charm. Two follow up questions: Is it possible to get the actual stream data from individual programs or is the peak value the most information available? Second, is there a list of what can be obtained with QueryInterface on various objects? I was already getting an ISimpleAudioVolume from the sessioncontrol but never thought of trying it on an IAudioMeterInformation. Thanks!Ivatts
1 You can only obtain mixed output of the entire end point, provided that hardware supports it and loopback (the keyword) device is enabled, in which case it acts like a microphone and delviers you back mixed content which is being played back; Note that you are not even guaranteed to be given the peak meters (e.g. on my system I don't have them at all) 2 No, you cannot enumerate what is supported on QueryInterfaceSafe
Hm, so is there a guaranteed method for retrieving at least the peak information? I'm guessing that SndVol still functions properly on your machine, thus there must be some way?Ivatts
No, SndVol does not show peaks on my Windows 7 machine (Realtek onboard audio). However I checked that peaks are still returned and they make sense. IAudioMeterInformation::QueryHardwareSupport returns zero mask, and I suppose that this make SndVol not visualize peaks, because there is no HW support for them. But they are still available (software calculated? - not 100% sure here).Safe
Does Powershell have cmdlets for accessing IAudioSessionControl interface?Laxation
@Suncatcher: you're probably looking for this project: github.com/cdhunt/WindowsAudioDevice-Powershell-CmdletSafe
A
0

Looking at WASAPI there is an interface to capture audio from a given client, but I don't see any higher level interface for determining peak levels. You may need to write some code to do that, unless there is a library out there that someone has created to do some higher level audio work with this WASPI. CHEERS!

Ascites answered 14/1, 2013 at 5:55 Comment(8)
Thanks for the answer, but unfortunately the audio capture is only from endpoint devices, which include microphones, speakers, etc, stuff that are plugged into your computer. This includes the loopback device I mentioned in the question, but that captures the entire system audio, instead of each program separately.Ivatts
Ok, that makes sense, what about (msdn.microsoft.com/en-us/library/windows/desktop/…) to access channel volume?Ascites
That gets you where that little slider nub sits at (see screenshot in main post) instead of where the top of the green bar is at. In other words, that returns the same value whether or not music is actually playing, and is in general useless.Ivatts
Yes I know that. My point is that I think unless you can find another higher order library you are going to have to do some coding. The peak is going to be the highest value in the stream.Ascites
I'd be really happy if I could get the stream, but I haven't been able to figure out how.Ivatts
You apparently aren't the only person who is interested in this, see #13107868 CHEERS!Ascites
There may be something here for you: jackaudio.org/jack_on_windows JACK works with JACK works with ASIO applications also, not just JACK built audio applications. This may be what you are looking for. A lot of professional audio recording / patching / effects audio applications make use of it. It does not just connect up "endpoint sources" like WASPI; it seems more capable. Check it out. CHEERS!Ascites
let us continue this discussion in chatIvatts
A
0

Here is another shot at it: IChannelAudioVolume::GetChannelVolume. I followed the thread on MSDN from SndVol, and this is where I ended up. Quoting from the web page: "The GetChannelVolume method retrieves the volume level for the specified channel in the audio session." You would have to write some software to extract the peak value from this stream. My quick guess would be just to compare if the current value is larger than the last largest value. If so, then the current value becomes the peak.

CHEERS!

Ascites answered 16/1, 2013 at 18:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.