Re: [python-win32] Control Volume on Windows [SEC=UNCLASSIFIED]

2014-03-12 Thread Tim Roberts
Andrew MacIntyre wrote:
 Trevor Haba wrote:
 I'm looking for a way to use python to change the volume on windows.
 After some googling the best I could come up with was this script I 
 got from a relatively ancient entry on this mailing list (I think it 
 was from 2005 or something). I'm using windows 7, and I would like it 
 to work on windows 8 if possible, though its not necessary. I don't 
 need to support any previous versions of windows.
 To which Tim Roberts replied:
 Alas, the news is not good.
 I think that comtypes (https://pypi.python.org/pypi/comtypes) can deal with 
 early binding interfaces?

You are quite right, and the attached script does it.  NOTE! that I have
not correctly defined all of the IMM interfaces for the general case;
I've only created enough of them to make this particular example work. 
On my Win 7 machine, this is able to fetch the default endpoint, display
the volume range (from -65.25 to 0 in steps of 0.75) and change the setting.

I'm glad you brought this up.  I've never played with comtypes before,
and this was a revealing exercise.

-- 
Tim Roberts, t...@probo.com
Providenza  Boekelheide, Inc.

import win32com
from comtypes import *
import comtypes.client
from ctypes import POINTER
from ctypes.wintypes import DWORD, BOOL

MMDeviceApiLib = \
GUID('{2FDAAFA3-7523-4F66-9957-9D5E7FE698F6}')
IID_IMMDevice = \
GUID('{D666063F-1587-4E43-81F1-B948E807363F}')
IID_IMMDeviceEnumerator = \
GUID('{A95664D2-9614-4F35-A746-DE8DB63617E6}')
CLSID_MMDeviceEnumerator = \
GUID('{BCDE0395-E52F-467C-8E3D-C4579291692E}')
IID_IMMDeviceCollection = \
GUID('{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}')
IID_IAudioEndpointVolume = \
GUID('{5CDF2C82-841E-4546-9722-0CF74078229A}')

class IMMDeviceCollection(IUnknown):
_iid_ = GUID('{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}')
pass

class IAudioEndpointVolume(IUnknown):
_iid_ = GUID('{5CDF2C82-841E-4546-9722-0CF74078229A}')
_methods_ = [
STDMETHOD(HRESULT, 'RegisterControlChangeNotify', []),
STDMETHOD(HRESULT, 'UnregisterControlChangeNotify', []),
STDMETHOD(HRESULT, 'GetChannelCount', []),
COMMETHOD([], HRESULT, 'SetMasterVolumeLevel',
(['in'], c_float, 'fLevelDB'),
(['in'], POINTER(GUID), 'pguidEventContext')
),
COMMETHOD([], HRESULT, 'SetMasterVolumeLevelScalar',
(['in'], c_float, 'fLevelDB'),
(['in'], POINTER(GUID), 'pguidEventContext')
),
COMMETHOD([], HRESULT, 'GetMasterVolumeLevel',
(['out','retval'], POINTER(c_float), 'pfLevelDB')
),
COMMETHOD([], HRESULT, 'GetMasterVolumeLevelScalar',
(['out','retval'], POINTER(c_float), 'pfLevelDB')
),
COMMETHOD([], HRESULT, 'SetChannelVolumeLevel',
(['in'], DWORD, 'nChannel'),
(['in'], c_float, 'fLevelDB'),
(['in'], POINTER(GUID), 'pguidEventContext')
),
COMMETHOD([], HRESULT, 'SetChannelVolumeLevelScalar',
(['in'], DWORD, 'nChannel'),
(['in'], c_float, 'fLevelDB'),
(['in'], POINTER(GUID), 'pguidEventContext')
),
COMMETHOD([], HRESULT, 'GetChannelVolumeLevel',
(['in'], DWORD, 'nChannel'),
(['out','retval'], POINTER(c_float), 'pfLevelDB')
),
COMMETHOD([], HRESULT, 'GetChannelVolumeLevelScalar',
(['in'], DWORD, 'nChannel'),
(['out','retval'], POINTER(c_float), 'pfLevelDB')
),
COMMETHOD([], HRESULT, 'SetMute',
(['in'], BOOL, 'bMute'),
(['in'], POINTER(GUID), 'pguidEventContext')
),
COMMETHOD([], HRESULT, 'GetMute',
(['out','retval'], POINTER(BOOL), 'pbMute')
),
COMMETHOD([], HRESULT, 'GetVolumeStepInfo',
(['out','retval'], POINTER(c_float), 'pnStep'),
(['out','retval'], POINTER(c_float), 'pnStepCount'),
),
COMMETHOD([], HRESULT, 'VolumeStepUp',
(['in'], POINTER(GUID), 'pguidEventContext')
),
COMMETHOD([], HRESULT, 'VolumeStepDown',
(['in'], POINTER(GUID), 'pguidEventContext')
),
COMMETHOD([], HRESULT, 'QueryHardwareSupport',
(['out','retval'], POINTER(DWORD), 'pdwHardwareSupportMask')
),
COMMETHOD([], HRESULT, 'GetVolumeRange',
(['out','retval'], POINTER(c_float), 'pfMin'),
(['out','retval'], POINTER(c_float), 'pfMax'),
(['out','retval'], POINTER(c_float), 'pfIncr')
),

]

class IMMDevice(IUnknown):
_iid_ = GUID('{D666063F-1587-4E43-81F1-B948E807363F}')
_methods_ = [
COMMETHOD([], HRESULT, 'Activate',
(['in'], POINTER(GUID), 'iid'),
(['in'], DWORD, 'dwClsCtx'),
(['in'], POINTER(DWORD), 'pActivationParans'),
(['out','retval'], POINTER(POINTER(IAudioEndpointVolume)), 
'ppInterface')
),
STDMETHOD(HRESULT, 

Re: [python-win32] Control Volume on Windows [SEC=UNCLASSIFIED]

2014-03-11 Thread Andrew MacIntyre
Trevor Haba wrote:
 I'm looking for a way to use python to change the volume on windows.
 After some googling the best I could come up with was this script I 
 got from a relatively ancient entry on this mailing list (I think it 
 was from 2005 or something). I'm using windows 7, and I would like it 

 to work on windows 8 if possible, though its not necessary. I don't 
 need to support any previous versions of windows.

To which Tim Roberts replied:
 Alas, the news is not good.
 
 The simple and easy-to-use winmm APIs are no longer supported.  They
 still work in many cases, but the mapping from the winmm device
 numbering to the new audio API device numbering is mysterious, as you
 have learned, and there is no good recipe to find them that works on
 every system.
 
 The blessed method of adjusting the volume in the Vista-and-beyond
 audio world requires the use of COM.  You fetch an IMMDeviceEnumerator
 interface, use that to fetch an IMMDevice for your device, then fetch an
 IAudioEndpoint interface and call SetMasterVolumeLevel to adjust the
 volume.  That's not really very much code in C++ terms, BUT none of those
 interfaces have late-binding support, which means Python cannot use them.

I think that comtypes (https://pypi.python.org/pypi/comtypes) can deal with 
early binding interfaces?

- These thoughts are mine alone! -
Andrew MacIntyre   Operations and Services Branch
tel:   +61 2 6219 5356 Communications Infrastructure Division
fax:   +61 2 6219 5347 Australian Communications  Media Authority
email: andrew.macint...@acma.gov.auhttp://www.acma.gov.au/


NOTICE: This email message is for the sole use of the intended recipient(s) 
 and may contain confidential and privileged information. Any unauthorized 
 review, use, disclosure or distribution is prohibited. If you are not the 
 intended recipient, please contact the sender by reply email and destroy all 
 copies of the original message.
___
python-win32 mailing list
python-win32@python.org
https://mail.python.org/mailman/listinfo/python-win32