change volume of single audio device

Discussion in 'Python' started by moldevort87@gmail.com, Nov 13, 2013.

  1. Guest

    hi,

    i'd like to change the volume of my av-receiver (HDMI) and speakers (analogue) simultaneously. in order to use both outputs i'm using virtual audio cable but if i set it as default device and change volume, hdmi and analogue remains unchanged.
    i intend to script a command line tool in python providing to change the volume of a single device (eg "setvolume {deviceID} {volume}")

    i've been looking for a similar tool, but none of them worked (eg nircmd); i'm using Win7.

    while looking for a solution i found that snippet of code

    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 = 0     # Same on all machines?
    SPEAKER_LINE_FADER_ID = 0 # "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)
    
    from ctypes import *
    from struct import *
    
    winmm= windll.winmm
    print
    print 'waveOutGetNumDevs=',winmm.waveOutGetNumDevs()
    print 'mixerGetNumDevs', winmm.mixerGetNumDevs()
    
    wvcps= ' '*52
    print 'res:', winmm.waveOutGetDevCapsA(0,wvcps,len(wvcps))
    
    res = unpack('IIL32cLI', wvcps)
    wMid=res[0]
    wPid=res[1]
    vDriverVersion=res[2]
    szPname=''.join(res[3:35])
    dwFormats=res[35]
    wChannels=res[36]
    print 'wMid=',wMid
    print 'wPid=',wPid
    print 'vDriverVersion=',vDriverVersion
    print 'szPname=',szPname
    print 'dwFormats=',dwFormats
    print 'wChannels=',wChannels
    
    vol=c_ulong()
    print 'res', winmm.waveOutGetVolume(0, byref(vol))
    
    print 'l:', vol.value & 0xffff, 'r:',vol.value >> 16 # left, right
    

    on executing i get
    Code:
    <<type 'exceptions.WindowsError'> Error 11 while setting volume
    <type 'exceptions.WindowsError'> Error 11 while setting volume
    
    waveOutGetNumDevs= 3
    mixerGetNumDevs 4
    res: 0
    wMid= 6553601
    wPid= 1537
    vDriverVersion= 2037083727
    szPname= o (AMD High Definition Audi
    dwFormats= 2
    wChannels= 36
    res 0
    l: 65535 r: 0
    
    Could anyone tell me why this error occurs?
    , Nov 13, 2013
    #1
    1. Advertising

  2. On Wed, 13 Nov 2013 06:40:02 -0800, moldevort87 wrote:

    > on executing i get
    >
    Code:
    >     <<type 'exceptions.WindowsError'> Error 11 while setting volume
    >     <type 'exceptions.WindowsError'> Error 11 while setting volume
    >
    >     waveOutGetNumDevs= 3
    >     mixerGetNumDevs 4
    >     res: 0
    >     wMid= 6553601
    >     wPid= 1537
    >     vDriverVersion= 2037083727
    >     szPname= o (AMD High Definition Audi
    >     dwFormats= 2
    >     wChannels= 36
    >     res 0
    >     l: 65535 r: 0
    > 
    >
    > Could anyone tell me why this error occurs?


    It's a Windows error, not a Python error. You'll need to look up the
    documentation for the Windows API used (I think it is
    mixerSetControlDetails) and see what return code 11 means. I don't even
    know if it's documented.

    Start by googling for "mixerSetControlDetails return value 11" and go on
    from there.



    --
    Steven
    Steven D'Aprano, Nov 13, 2013
    #2
    1. Advertising

  3. Tim Chase Guest

    On 2013-11-13 16:05, Steven D'Aprano wrote:
    > Start by googling for "mixerSetControlDetails return value 11" and
    > go on from there.


    Sounds like Nigel at work.[1]

    -tkc


    http://en.wikipedia.org/wiki/Up_to_eleven
    Tim Chase, Nov 13, 2013
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. aeonsun
    Replies:
    2
    Views:
    417
    Luc The Perverse
    Mar 11, 2007
  2. sick dick
    Replies:
    0
    Views:
    383
    sick dick
    Apr 3, 2006
  3. Sven
    Replies:
    2
    Views:
    170
  4. Ned Deily
    Replies:
    0
    Views:
    106
    Ned Deily
    Apr 3, 2013
  5. Sven
    Replies:
    0
    Views:
    132
Loading...

Share This Page