AutoHotkey Community

It is currently May 27th, 2012, 5:34 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 151 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10, 11  Next
Author Message
 Post subject:
PostPosted: March 3rd, 2010, 9:32 pm 
Offline

Joined: February 10th, 2007, 5:18 am
Posts: 92
I'm trying to get the active levels of my microphone, however, there seems to be something wrong with VA_IAudioMeterInformation_GetPeakValue(audioMeter, peakValue) as it always returns null

Here is my code

Code:
#SingleInstance, Force
MeterLength = 30
COM_Init()

device := VA_GetDevice("Microphone Array")
audioMeter := VA_GetAudioMeter(device)

VA_IAudioMeterInformation_GetMeteringChannelCount(audioMeter, channelCount)

; "The peak value for each channel is recorded over one device
;  period and made available during the subsequent device period."
VA_GetDevicePeriod("playback", devicePeriod)

Loop
{
    ; Get the peak value across all channels.
    VA_IAudioMeterInformation_GetPeakValue(audioMeter, peakValue)   
   meter := MakeMeter(peakValue, MeterLength)
   
    ; Get the peak values of all channels.
    VarSetCapacity(peakValues, channelCount*4)
    VA_IAudioMeterInformation_GetChannelsPeakValues(audioMeter, channelCount, &peakValues)
   Loop %channelCount%
        meter .= "`n" MakeMeter(NumGet(peakValues, A_Index*4-4, "float"), MeterLength)

    ToolTip, %meter%
    Sleep, %devicePeriod%
}

MakeMeter(fraction, size)
{
    global MeterLength
   Loop % fraction*size
        meter .= "|"
    Loop % (1-fraction)*size
        meter .= "."
    meter .= "  " fraction
    return meter
}


I have the right device selected as VA_GetDeviceName returns the name of my recording microphone.

Any ideas?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 4th, 2010, 1:57 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
VA_GetAudioMeter expects a device_desc, the same as VA_GetDevice's first parameter. When you pass it a pointer value, it is misinterpreted as a numeric index. In retrospect, a pointer value is extremely unlikely to ever be in the range of a valid index, so VA_GetDevice (which is used internally by functions such as VA_GetAudioMeter) could simply return the value it is given as-is. However, in this case you have no need for the device pointer anyway.

Instead pass the device name directly to VA_GetAudioMeter, or pass "capture" to use your default recording device.

Also, the "playback" in VA_GetDevicePeriod("playback",...) should be changed to whatever device_desc is passed to VA_GetAudioMeter.


Edit: I've updated VA.zip so that VA_GetDevice(device_pointer) will return device_pointer. I also fixed a "pointer leak" in VA_GetAudioMeter.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 4th, 2010, 5:51 pm 
Offline

Joined: February 10th, 2007, 5:18 am
Posts: 92
Ahh, that works perfectly. Thank you :D


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 4th, 2010, 9:33 pm 
Offline

Joined: February 10th, 2007, 5:18 am
Posts: 92
Sorry for the double post, but I noticed something odd. The levels are only displayed if another program starts up the capture drivers. For example, if I load up Audacity and hit record, or open up recording devices (which has a meter next to ever device) only then does this script show the meters.

If I close out all programs that, upon exit, disable the record drivers, the meters for this script go back down to 0.

I'm no expert at calling the proper drivers so how exactly do I load up my main capture device driver?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 5th, 2010, 3:31 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
I wrote:
The peak meter only reports meaningful values when something is actually capturing audio. I'm not sure how it is done, and haven't spent the necessary time to find out as I don't have a need to detect sound input.
Source: Microphone Peak Value - Vista Audio (Lexikos)
Sorry.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 5th, 2010, 7:49 pm 
Offline

Joined: February 10th, 2007, 5:18 am
Posts: 92
Ahh gotcha Lexikos, didn't really read that. Thanks for the script nontheless. Works like a charm for output devices. I'll try to find a way to load the input device and will post my solution when (and if) I find it.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 13th, 2010, 8:58 am 
Offline

Joined: March 13th, 2010, 8:40 am
Posts: 2
Hi,
First of all thanks for the script, it makes the move to windows 7 seem a bit less painful. :p

I'm having a small problem though. I use hotkeys to control the volume on line in coming from my ps3. It works great except for when I lower the volume down to 0 and then press twice on the volume down key. The sound level goes up to 89 and it'll get ear shatteringly loud. The same thing doesn't happen if I try to increase the volume over 100, not that it'd matter much if it did. :>

Here's my code, hope you can help me.

Code:
COM_Init()

+Volume_Mute::
VA_SetMute(!VA_GetMute(4),4)
return

+Volume_Up::VA_SetVolume(VA_GetVolume(4) + 1, 4)

+Volume_Down::VA_SetVolume(VA_GetVolume(4) - 1, 4)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 13th, 2010, 2:22 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
Thanks for the bug report. I've fixed a divide-by-zero error in VA_SetVolume which seemed to be the cause. Please download and try again.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 14th, 2010, 3:28 am 
Offline

Joined: March 13th, 2010, 8:40 am
Posts: 2
Seems to work flawlessly now. Thanks for the quick response!


Report this post
Top
 Profile  
Reply with quote  
PostPosted: May 11th, 2010, 1:57 pm 
Offline

Joined: December 9th, 2009, 12:28 am
Posts: 9
Is it possible with application specific sound control in windows 7 with this script?

Lets say if you only want to mute the sound in a specific program, but let others stay the same volume.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Re: Er, problem solved
PostPosted: June 10th, 2010, 10:13 pm 
Offline

Joined: June 10th, 2010, 2:24 pm
Posts: 6
Dustin wrote:
Sorry, I'm pretty new to this stuff so I don't really understand much.

With that said, I think I've solved it.

I used this line
Code:
F11::VA_SetMasterMute(!VA_GetMasterMute("capture"), "capture")


This appears to just toggle mute the default input device, exactly what I need! If there's some way I can get it to mute just the mic instead of the default input device, that would be better. But really, this is just splitting hairs and I'm just overjoyed to actually have it working!

Much thanks!

i've used your finding as base for the following
Code:
COM_Init()




startup=1
while startup=1
{
mutestatus := VA_GetMasterMute("microphone")
if (mutestatus = 0)
{
menu, tray, icon, ON.ico,,1
}

else
{
menu, tray, icon, OFF.ico,,1
}
startup=0
}
return




YOURHOTKEY::
mutestatus := VA_GetMasterMute("microphone")
if (mutestatus = 1)
{
VA_SetMasterMute(0, "microphone")
menu, tray, icon, ON.ico,,1
CoordMode, ToolTip, Screen
Tooltip, ON, 0, 0
}

else
{
VA_SetMasterMute(1, "microphone")
menu, tray, icon, OFF.ico,,1
CoordMode, ToolTip, Screen
Tooltip, OFF, 0, 0
}

SetTimer, RemoveToolTip, 1500
Return




RemoveToolTip:
  SetTimer, RemoveToolTip, Off
  ToolTip
return

in addition to just toggling it always show the current mute status in the traybar with custom icons (even when just started)
and it shows the status as a tooltip when you toggle (handy at fullscreen games)





it would be nice if someone could help me with my own audio problem:
i need to find a way to change the windows 7 speaker setup (2.0 speakers, 5.1 speakers, etc) with a hotkey
but i have found nothing about how one could do it for hours

my old thread in the help forum:
http://www.autohotkey.com/forum/topic59091.html


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 16th, 2010, 12:30 pm 
Offline

Joined: June 15th, 2010, 6:48 pm
Posts: 13
maximo3491 wrote:
I'm trying to get the active levels of my microphone, however, there seems to be something wrong with VA_IAudioMeterInformation_GetPeakValue(audioMeter, peakValue) as it always returns null

Here is my code

Code:
#SingleInstance, Force
MeterLength = 30
COM_Init()

device := VA_GetDevice("Microphone Array")
audioMeter := VA_GetAudioMeter(device)

VA_IAudioMeterInformation_GetMeteringChannelCount(audioMeter, channelCount)

; "The peak value for each channel is recorded over one device
;  period and made available during the subsequent device period."
VA_GetDevicePeriod("playback", devicePeriod)

Loop
{
    ; Get the peak value across all channels.
    VA_IAudioMeterInformation_GetPeakValue(audioMeter, peakValue)   
   meter := MakeMeter(peakValue, MeterLength)
   
    ; Get the peak values of all channels.
    VarSetCapacity(peakValues, channelCount*4)
    VA_IAudioMeterInformation_GetChannelsPeakValues(audioMeter, channelCount, &peakValues)
   Loop %channelCount%
        meter .= "`n" MakeMeter(NumGet(peakValues, A_Index*4-4, "float"), MeterLength)

    ToolTip, %meter%
    Sleep, %devicePeriod%
}

MakeMeter(fraction, size)
{
    global MeterLength
   Loop % fraction*size
        meter .= "|"
    Loop % (1-fraction)*size
        meter .= "."
    meter .= "  " fraction
    return meter
}


I have the right device selected as VA_GetDeviceName returns the name of my recording microphone.

Any ideas?


I would like to do something like that. So, what is the final code? How can I get microphone peak levels? TY

EDIT: I found the problem. "capure" device must be opened, in some way. If I run the code with "Recording Devices" window opened from volume icon, it works correctly. So, ho can I "open" the device?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 16th, 2010, 3:03 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
From the device pointer (IMMDevice Interface), you need to create and initialize an audio client (IAudioClient Interface). It can be tricky to call the interface functions correctly, so I've written a complete example:
Code:
COM_Init()
; Get the device which we'll be monitoring.
device := VA_GetDevice("capture")

; Get IAudioClient interface.
VA_IMMDevice_Activate(device, IID_IAudioClient:="{1CB9AD4C-DBFA-4c32-B178-C2F568A703B2}", 7, 0, audioClient)
; Get mixer format to pass to Initialize.
VA_IAudioClient_GetMixFormat(audioClient, format)
; Initialize audio client to ensure peak meter is active.
VA_IAudioClient_Initialize(audioClient, 0, 0, 0, 0, format, 0)

; Get IAudioMeterInformation interface.
audioMeter := VA_GetAudioMeter(device)
; No longer needed, so free it:
COM_Release(device)

MeterLength = 30

; "The peak value for each channel is recorded over one device
;  period and made available during the subsequent device period."
VA_GetDevicePeriod("capture", devicePeriod)

Loop
{
    VA_IAudioMeterInformation_GetPeakValue(audioMeter, peakValue)   
   
    meter =
    ; Make the meter.
    Loop % peakValue*MeterLength
        meter .= "|"
    Loop % (1-peakValue)*MeterLength
        meter .= "."
    meter .= "  " peakValue

    ToolTip, %meter%
    Sleep, %devicePeriod%
}

/* To clean up:
COM_Release(audioMeter)
COM_Release(audioClient)
*/

;
; IAudioClient
;
VA_IAudioClient_Initialize(this, ShareMode, StreamFlags, BufferDuration, Periodicity, Format, AudioSessionGuid) {
    return DllCall(NumGet(NumGet(this+0)+12), "uint", this, "int", ShareMode, "uint", StreamFlags, "int64", BufferDuration, "int64", Periodicity, "uint", Format, "uint", SubStr(AudioSessionGuid,1,1)="{" ? COM_GUID4String(AudioSessionGuid,AudioSessionGuid) : AudioSessionGuid)
}
VA_IAudioClient_GetBufferSize(this, ByRef NumBufferFrames) {
    return DllCall(NumGet(NumGet(this+0)+16), "uint", this, "uint*", NumBufferFrames)
}
VA_IAudioClient_GetStreamLatency(this, ByRef Latency) {
    return DllCall(NumGet(NumGet(this+0)+20), "uint", this, "int64*", Latency)
}
VA_IAudioClient_GetCurrentPadding(this, ByRef NumPaddingFrames) {
    return DllCall(NumGet(NumGet(this+0)+24), "uint", this, "uint*", NumPaddingFrames)
}
VA_IAudioClient_IsFormatSupported(this, ShareMode, Format, ByRef ClosestMatch) {
    return DllCall(NumGet(NumGet(this+0)+28), "uint", this, "int", ShareMode, "uint", Format, "uint*", ClosestMatch)
}
VA_IAudioClient_GetMixFormat(this, ByRef Format) {
    return DllCall(NumGet(NumGet(this+0)+32), "uint", this, "uint*", Format)
}
VA_IAudioClient_GetDevicePeriod(this, ByRef DefaultDevicePeriod, ByRef MinimumDevicePeriod) {
    return DllCall(NumGet(NumGet(this+0)+36), "uint", this, "int64*", DefaultDevicePeriod, "int64*", MinimumDevicePeriod)
}
VA_IAudioClient_Start(this) {
    return DllCall(NumGet(NumGet(this+0)+40), "uint", this)
}
VA_IAudioClient_Stop(this) {
    return DllCall(NumGet(NumGet(this+0)+44), "uint", this)
}
VA_IAudioClient_Reset(this) {
    return DllCall(NumGet(NumGet(this+0)+48), "uint", this)
}
VA_IAudioClient_SetEventHandle(this, eventHandle) {
    return DllCall(NumGet(NumGet(this+0)+52), "uint", this, "uint", eventHandle)
}
VA_IAudioClient_GetService(this, iid, ByRef Service) {
    return DllCall(NumGet(NumGet(this+0)+56), "uint", this, "uint", COM_GUID4String(iid,iid), "uint*", Service)
}

I had attempted this previously but had overlooked IAudioClient::GetMixFormat, which is needed to get the stream format to pass to IAudioClient::Initialize.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Per app volume level?
PostPosted: July 17th, 2010, 2:32 am 
Offline

Joined: April 2nd, 2010, 12:46 pm
Posts: 24
Can this library be used to set app-specific volume levels visible in the Win7 audio mixer? My mp3/TV/video players produce uneven audio levels. When a particular player starts, I'd like to set the relevant application volume to, say, 50% of current master volume. I can do this manually in the mixer and it works. However, every now and then I may inadvertently hit an app-specific volume hotkey, and the app will reset its volume level to 100%. Then I have to adjust the level manually again. I want to automate this.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: July 17th, 2010, 8:59 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7503
Location: Australia
element wrote:
Can this library be used to set app-specific volume levels visible in the Win7 audio mixer?
No.

After spending several hours researching it, wrapping various COM interfaces and experimenting I'm able to enumerate audio sessions and determine which app owns them, but not control their volume. Basically, I got to the same point as this guy before realising it was impossible.
Anton Hansson wrote:
According to Larry Osterman
"There is no publicly documented mechanism for doing what you're trying to do."

Source: Controlling the volume of other applications - Stack Overflow


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 151 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10, 11  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Google Feedfetcher, sks, Stigg, Yahoo [Bot] and 11 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group