[python-win32] Control Volume on Windows

Trevor Haba habahut at gmail.com
Tue Mar 11 04:35:17 CET 2014


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.

Here is the code:

#!/usr/bin/env python
#Boa:PyApp:main
modules = {}


import ctypes

mixerSetControlDetails = (
    ctypes.windll.winmm.mixerSetControlDetails)

mixerGetControlDetails = (
    ctypes.windll.winmm.mixerGetControlDetailsA)

# Some constants
MIXER_OBJECTF_MIXER = 0 # mmsystem.h
VOLUME_CONTROL_ID = 1     # Same on all machines?
SPEAKER_LINE_FADER_ID = 1 # "Identifier <identifier> in OID value does not
resolve to a positive integer"
MINIMUM_VOLUME = 0     # fader control (MSDN Library)
MAXIMUM_VOLUME = 65535 # fader control (MSDN Library)

class MIXERCONTROLDETAILS(ctypes.Structure):
    _pack_ = 1
    _fields_ = [('cbStruct', ctypes.c_ulong),
                ('dwControlID', ctypes.c_ulong),
                ('cChannels', ctypes.c_ulong),
                ('cMultipleItems', ctypes.c_ulong),
                ('cbDetails', ctypes.c_ulong),
                ('paDetails', ctypes.POINTER(ctypes.c_ulong))]

def setVolume(volume):
    """Set the speaker volume on the 'Volume Control' mixer"""
    if not (MINIMUM_VOLUME <= volume <= MAXIMUM_VOLUME):
        raise ValueError, "Volume out of range"
    cd = MIXERCONTROLDETAILS(ctypes.sizeof(MIXERCONTROLDETAILS),
                             SPEAKER_LINE_FADER_ID,
                             1, 0,
                             ctypes.sizeof(ctypes.c_ulong),
                             ctypes.pointer(ctypes.c_ulong(volume)))
    ret = mixerSetControlDetails(VOLUME_CONTROL_ID,
                                 ctypes.byref(cd),
                                 MIXER_OBJECTF_MIXER)
    if ret != 0:
        print WindowsError, "Error %d while setting volume" % ret

    ret = mixerGetControlDetails(VOLUME_CONTROL_ID,
                                 ctypes.byref(cd),
                                 MIXER_OBJECTF_MIXER)
    if ret != 0:
        print WindowsError, "Error %d while setting volume" % ret
    else:
        print 'cbStruct', cd.cbStruct
        print 'dwControlID', cd.dwControlID
        print 'cChannels', cd.cChannels
        print 'cMultipleItems', cd.cMultipleItems
        print 'cbDetails', cd.cbDetails
        print 'paDetails', cd.paDetails.contents
    return

#setVolume((2**16-1)/2)
setVolume(0)   ## added by me, neither value does anything

If I run this, the ret value is 0 and it prints out all the data from the
cd struct. But it doesn't change the volume at all. If I change the
SPEAKER_LINE_FADER_ID to 0 the program crashes with: windows error 1025 -
error setting the volume. I've tried googling that error, winmm,
ctypes.windll, and a bunch of other things but I seem unable to find any
resources with any information at all. The original poster of this script
said the constants might need to be changed, and that finding the right
constants could "take some work" but never elaborated on how to actually do
it.

I've looked at the relevant MSDN C++ docs that windows provides, and while
they are somewhat informative I would really like to keep this project to
python only. I have been unable to find much of any documentation on
pywin32 itself. Is it hidden somewhere?

Anyone have any ideas?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-win32/attachments/20140310/327fa478/attachment.html>


More information about the python-win32 mailing list