AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Vista Audio Control Functions v2.0
Goto page Previous  1, 2, 3, 4  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
bmcclure



Joined: 24 Nov 2007
Posts: 487

PostPosted: Tue Dec 11, 2007 2:57 am    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Tue Dec 11, 2007 5:25 am    Post subject: Reply with quote

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
View user's profile Send private message
bmcclure



Joined: 24 Nov 2007
Posts: 487

PostPosted: Tue Dec 11, 2007 5:46 am    Post subject: Reply with quote

Yes, please interpret DLL as COM, heh Smile 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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Tue Dec 11, 2007 6:03 am    Post subject: Reply with quote

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
View user's profile Send private message
bmcclure



Joined: 24 Nov 2007
Posts: 487

PostPosted: Thu Dec 13, 2007 2:15 am    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Thu Dec 13, 2007 4:36 am    Post subject: Reply with quote

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
View user's profile Send private message
bmcclure



Joined: 24 Nov 2007
Posts: 487

PostPosted: Thu Dec 13, 2007 4:34 pm    Post subject: Reply with quote

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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Thu Dec 13, 2007 11:55 pm    Post subject: Reply with quote

-2147221008 = 0x800401F0
Code:
//
// CoInitialize has not been called.
//
#define CO_E_NOTINITIALIZED              _HRESULT_TYPEDEF_(0x800401F0L)

Mad

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:
Code:
COM_Init()
(Same as COM_CoInitialize(), but shorter.)
Back to top
View user's profile Send private message
bmcclure



Joined: 24 Nov 2007
Posts: 487

PostPosted: Fri Dec 14, 2007 12:01 am    Post subject: Reply with quote

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 Smile

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 Smile
_________________
-Ben

SteamLab Wiki
SteamLab Trac site
[Broken] - My industrial music
Back to top
View user's profile Send private message
bitlisz
Guest





PostPosted: Wed Jan 23, 2008 3:12 pm    Post subject: Re: Vista Audio/Volume Control Functions Reply with quote

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

PostPosted: Wed Jan 23, 2008 11:20 pm    Post subject: Reply with quote

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. Sad

There is a solution, but it requires a window to be shown briefly. See Select sound source.
Back to top
View user's profile Send private message
Guest






PostPosted: Wed Jan 30, 2008 10:14 pm    Post subject: Reply with quote

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

PostPosted: Thu Jan 31, 2008 6:40 am    Post subject: Reply with quote

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:
Quote:
- Windows Vista. The script should NOT be run in XP-compatibility mode.
- Sean's Standard Library COM.ahk
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2699
Location: Australia, Qld

PostPosted: Mon Feb 11, 2008 9:59 am    Post subject: Reply with quote

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
View user's profile Send private message
bla
Guest





PostPosted: Wed Feb 27, 2008 8:18 pm    Post subject: Reply with quote

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 Smile

thanks to you it's not anymore tho. thank you!
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3, 4  Next
Page 2 of 4

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group