 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
bmcclure
Joined: 24 Nov 2007 Posts: 487
|
Posted: Tue Dec 11, 2007 2:57 am Post subject: |
|
|
OK, I have confirmed that there is an issue.
Randomly, your functions stop returning proper values. It always seems to correct itself after a while, or after some unknown action, I don't know which.
But for instance, I'm always getting nothing for VA_GetMasterMute() at the moment even when it's muted. I'm also getting a blank value for VA_GetMasterVolume() at the moment.
Yet in a little while, it will start working properly again.
Could it not be releasing Dlls properly or something? I can't figure out what would cause this odd behavior. _________________ -Ben
SteamLab Wiki
SteamLab Trac site
[Broken] - My industrial music |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Tue Dec 11, 2007 5:25 am Post subject: |
|
|
Are you using any other VA functions? I only use the script rarely, to control line in and for VA_GetPeakValue. However, running VA_GetMasterMute and VA_GetMasterVolume in a loop gives predictably reliable results. I have left a script running, repeatedly polling volume/mute and counting the number of bad results (currently 0.)
| Quote: | | Could it not be releasing Dlls properly or something? | I find that unlikely (even interpreting "Dlls" as "COM references.") VA doesn't explicitly load any Dlls, and it releases every COM interface reference it retrieves. (Re-confirmed for COM_GetMasterMute/Volume and functions called by them.)
Try these modified functions, and let me know the values of _hResult_, _ErrorLevel_ and endptVolume (directly) after the function fails. _hResult_ and _ErrorLevel_ should be zero, indicating success, while endptVolume should be a non-zero integer.
| Code: | VA_GetMasterVolume(channel="")
{
global _hResult_, _ErrorLevel_, endptVolume
endptVolume := VA_GetDefaultAudioEndpointVolume()
if channel = ; endptVolume->GetMasterVolumeLevelScalar(vol)
_hResult_:=DllCall(NumGet(NumGet(endptVolume+0)+36), "uint",endptVolume, "float*",vol)
else ; endptVolume->GetChannelVolumeLevelScalar(channel,vol)
_hResult_:=DllCall(NumGet(NumGet(endptVolume+0)+52), "uint",endptVolume, "uint",channel, "float*",vol)
_ErrorLevel_ := ErrorLevel
COM_Release(endptVolume)
return vol*100
}
VA_GetMasterMute()
{
global _hResult_, _ErrorLevel_, endptVolume
endptVolume := VA_GetDefaultAudioEndpointVolume()
; endptVolume->GetMute(mute)
_hResult_:=DllCall(NumGet(NumGet(endptVolume+0)+60), "uint",endptVolume, "int*",mute)
_ErrorLevel_ := ErrorLevel
COM_Release(endptVolume)
return mute
} |
|
|
| Back to top |
|
 |
bmcclure
Joined: 24 Nov 2007 Posts: 487
|
Posted: Tue Dec 11, 2007 5:46 am Post subject: |
|
|
Yes, please interpret DLL as COM, heh Though I thought the com include used dll calls, guess not.
Anyway, thanks for the tip. Next time it occurs, I'll use your function and let you know what values I receive. _________________ -Ben
SteamLab Wiki
SteamLab Trac site
[Broken] - My industrial music |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Tue Dec 11, 2007 6:03 am Post subject: |
|
|
| bmcclure wrote: | | Though I thought the com include used dll calls, guess not. | Well, Vista's audio API (MMDevice API) does reside in a dll/dlls. The point is that the script has no knowledge of the dll itself, only the COM interfaces. |
|
| Back to top |
|
 |
bmcclure
Joined: 24 Nov 2007 Posts: 487
|
Posted: Thu Dec 13, 2007 2:15 am Post subject: |
|
|
On GetMasterVolume:
_hResult_ : null
_ErrorLevel_ : -4
endptVolume : null
Note: above, 'null' means it was empty
On GetMasterMute:
same
Then it started working again a few minutes later, and stopped again a few minutes after that... ugh! _________________ -Ben
SteamLab Wiki
SteamLab Trac site
[Broken] - My industrial music
Last edited by bmcclure on Thu Dec 13, 2007 2:19 am; edited 1 time in total |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Thu Dec 13, 2007 4:36 am Post subject: |
|
|
That means VA_GetDefaultAudioEndpointVolume (or VA_GetDefaultAudioDevice) is failing. DllCall sets ErrorLevel=-4 when "the specified function could not be found inside the dll", or as in this case, when the function pointer is invalid (since endptVolume is invalid.)
Now we need to narrow it down further... return VA_GetMasterVolume and VA_GetMasterMute to the way they were (or leave them as is), and use the following modified functions:
| Code: | VA_GetDefaultAudioEndpointVolume()
{
if defaultDevice := VA_GetDefaultAudioDevice()
{
; defaultDevice->Activate(...)
; [out] IAudioEndpointVolume endptVolume
iid := "{5CDF2C82-841E-4546-9722-0CF74078229A}"
_hResult_:=DllCall(NumGet(NumGet(defaultDevice+0)+12), "uint",defaultDevice, "uint",COM_GUID4String(iid,iid), "uint",1, "uint",0, "uint*",endptVolume)
COM_Release(defaultDevice), defaultDevice=0
if !endptVolume
MsgBox Failed to get IAudioEndpointVolume, HRESULT: %_hResult_%
}
return endptVolume
}
VA_GetDefaultAudioDevice()
{
global _hResult_, deviceEnumerator
; deviceEnumerator := COM_CreateObject("MMDeviceEnumerator","IMMDeviceEnumerator",CLSCTX_INPROC_SERVER)
; (CLSCTX_INPROC_SERVER = execution context: this process)
deviceEnumerator := COM_CreateObject("{BCDE0395-E52F-467C-8E3D-C4579291692E}","{A95664D2-9614-4F35-A746-DE8DB63617E6}",1)
if deviceEnumerator
{
; deviceEnumerator->GetDefaultAudioEndpoint(...)
; [out] IMMDevice defaultDevice
_hResult_:=DllCall(NumGet(NumGet(deviceEnumerator+0)+16), "uint",deviceEnumerator, "int",0, "int",0, "uint*",defaultDevice)
COM_Release(deviceEnumerator), deviceEnumerator=0
if !defaultDevice
MsgBox GetDefaultAudioEndpoint failed, HRESULT: %_hResult_%
}
else
MsgBox Failed to create MMDeviceEnumerator, HRESULT: %_hResult_%
return defaultDevice
} | A MsgBox should be shown the instant either of them fail.
You'll also need to change COM_CreateObject for the "Failed to create MMDeviceEnumerator" message to have a meaningful HRESULT (assuming it fails.)
| Code: | COM_CreateObject(CLSID, IID = "{00020400-0000-0000-C000-000000000046}", CLSCTX = 5)
{
Global _hResult_
_hResult_:=DllCall("ole32\CoCreateInstance", "Uint", SubStr(CLSID,1,1)="{" ? COM_GUID4String(CLSID,CLSID) : COM_CLSID4ProgID(CLSID,CLSID), "Uint", 0, "Uint", CLSCTX, "Uint", COM_GUID4String(IID,IID), "UintP", ppv)
Return ppv
} |
|
|
| Back to top |
|
 |
bmcclure
Joined: 24 Nov 2007 Posts: 487
|
Posted: Thu Dec 13, 2007 4:34 pm Post subject: |
|
|
Thanks a lot for taking the time to help me with this.
With the 2 modified VA functions and one modified COM function, I get the following error whenever I experience this problem:
| Quote: | | Failed to create MMDeviceEnumerator, HRESULT: -2147221008 |
_________________ -Ben
SteamLab Wiki
SteamLab Trac site
[Broken] - My industrial music |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Thu Dec 13, 2007 11:55 pm Post subject: |
|
|
-2147221008 = 0x800401F0
| Code: | //
// CoInitialize has not been called.
//
#define CO_E_NOTINITIALIZED _HRESULT_TYPEDEF_(0x800401F0L) |
I had discarded that possibility, assuming if you don't initialize COM, the functions never work. Are you perhaps CoInitializing, CoUninitializing, and forgetting to CoInitialize again?
I simply call the following once at script start-up:
(Same as COM_CoInitialize(), but shorter.) |
|
| Back to top |
|
 |
bmcclure
Joined: 24 Nov 2007 Posts: 487
|
Posted: Fri Dec 14, 2007 12:01 am Post subject: |
|
|
Oh, no, I haven't messed with COM at all outside of these VA functions. I completely missed the instructions in the first post to manually initialize COM in my script. I'll try that now. Sorry!
Though it usually works right away upon script start. That seems odd that it is sporadic.
I added COM_Init() to my script, and the world is still turning; I'll let you know if the problem crops up again now that I'm actually using your functions properly
Edit: It's been over 24 hours and everything's A-OK so far. I still don't understand why it was even working at all before, heh. But I'm happy now  _________________ -Ben
SteamLab Wiki
SteamLab Trac site
[Broken] - My industrial music |
|
| Back to top |
|
 |
bitlisz Guest
|
Posted: Wed Jan 23, 2008 3:12 pm Post subject: Re: Vista Audio/Volume Control Functions |
|
|
Hi!
I can use this script to toggle beetween audio outputs?
Like Digital to Analog? |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Wed Jan 23, 2008 11:20 pm Post subject: |
|
|
If you mean toggle the default audio device, then no. Microsoft decided that only the user should be able to do this, so they did not provide an API for it.
There is a solution, but it requires a window to be shown briefly. See Select sound source. |
|
| Back to top |
|
 |
Guest
|
Posted: Wed Jan 30, 2008 10:14 pm Post subject: |
|
|
What is the easiest way in AHK to unmute and set the volume at 50?
Does it involve this script, or is there another way?
(Vista)
Thanks! |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Thu Jan 31, 2008 6:40 am Post subject: |
|
|
What is "easiest" is subjective. You could put AutoHotkey in XP compatiblity mode and use SoundSet (as explained on the SoundSet page in the AutoHotkey help file), or use this script. You may notice at the top of my first post:
| Quote: | Provide Windows Vista-compatible alternatives to some SoundSet/SoundGet subcommands. The script currently has the following capabilities:
- Get or Set volume, preserving balance.
- Get or Set the volume of each individual channel - left (0) or right (1); surround-sound not tested.
- Get or Set mute.
- Work with any component listed on the Levels tab of the Speakers Properties dialog. For me this includes the master volume, microphone, line in, and a bunch of components that don't really exist.
- New: Detect when sound is playing through the default output device. (see example further down this page.)
|
| Code: | VA_SetMasterMute(false)
VA_SetMasterVolume(50) | Note also the script requirements: |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2699 Location: Australia, Qld
|
Posted: Mon Feb 11, 2008 9:59 am Post subject: |
|
|
Vista Audio Control Functions v2.0 has been released. I've rewritten most of the script and added a few new features. In particular, multiple devices are now supported.
The peak meter functions have completely changed, so if you used those, be sure to check out the example in the new help file. |
|
| Back to top |
|
 |
bla Guest
|
Posted: Wed Feb 27, 2008 8:18 pm Post subject: |
|
|
i only got to AutoHotkey in the first place because i wanted to mute the microphone in vista.
and then it turns out exactly thats an issue
thanks to you it's not anymore tho. thank you! |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|