PeakMeter values from SoundMixer.py

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
Post Reply
ShelleyJohnson
Posts: 2
Joined: Fri Aug 07, 2009 4:04 pm

PeakMeter values from SoundMixer.py

Post by ShelleyJohnson » Fri Aug 07, 2009 4:42 pm

I want to get the peakmeter values from the Windows volume mixer for whatever sound is coming out of my speakers. I'm using Soundmixer.py (which is/was part of EventGhost) to get master volume levels, I'd like to tack a few lines on and get the peakmeter values too.

I've added the code below, which is based on the GetMasterVolume() found in SoundMixer.py. http://support.microsoft.com/kb/181550 mirrors what's supposed to happen for the peakmeter which in turn looks like the GetMasterVolume() process in SoundMixer.

My problem is
rc = mixerGetLineControls(hmixer, byref(mxlc), MIXER_GETLINECONTROLSF_ONEBYTYPE)
in
def GetPeakControl(hmixer, componentType, ctrlType)
returns error code 1025, which I don't know what it means (msdn shows the strings not the codes), and if I did I'm not sure I'd understand what to fix. Anyone know what I've did wrong?

Thanks.

Code: Select all

# ---------------------------------    
    
def GetPeakLevel():
    hmixer = HMIXER()
    volCtrl = MIXERCONTROL()
    
    # Obtain the hmixer struct
    err = mixerOpen(byref(hmixer), 0, 0, 0, 0)
    #print err
    if err != 0:
        return None

    # get peak meter control
    #MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
    #MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT
    peakCtrl = GetPeakControl(hmixer, MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT, 
                                MIXERCONTROL_CONTROLTYPE_PEAKMETER)
    if peakCtrl is None:
        print 'None: step 1'
        return None
    print 'OK: step 1'
    
    # Then get the volume
    vol = GetPeakVolumeValue(hmixer, volCtrl)
    
    #max = volCtrl.Bounds.lBounds.lMaximum
    #min = volCtrl.Bounds.lBounds.lMinimum
    #vol = 100.0 * (vol - min) / (max - min)
    return vol
    
    
def GetPeakControl(hmixer, componentType, ctrlType):
    '''Obtains an appropriate pointer and info for the volume control
       This function attempts to obtain a mixer control. Returns True if successful.'''
    mxlc = MIXERLINECONTROLS()
    mxl = MIXERLINE()
    mxc = MIXERCONTROL()

    mxl.cbStruct = sizeof(mxl)
    mxl.dwComponentType = componentType

    # Obtain a line corresponding to the component type
    rc = mixerGetLineInfo(hmixer, byref(mxl), MIXER_GETLINEINFOF_COMPONENTTYPE)
    print str(rc) + ' step2 rc1'
    
    if (MMSYSERR_NOERROR == rc):
        mxlc.cbStruct = sizeof(mxlc)
        mxlc.dwLineID = mxl.dwLineID
        mxlc.dwControl.Type = ctrlType
        mxlc.cControls = 1
        mxlc.cbmxctrl = sizeof(mxc)

        # Allocate a buffer for the control
        mxlc.pamxctrl = pointer(mxc)
        mxc.cbStruct = sizeof(mxc)

        # Get the control
        rc = mixerGetLineControls(hmixer, byref(mxlc), MIXER_GETLINECONTROLSF_ONEBYTYPE)
        print str(rc) + ' step2 rc2'
        if (MMSYSERR_NOERROR == rc):
            return mxc

    return None
    
def GetPeakVolumeValue(hmixer, mxc):
    mxcd = MIXERCONTROLDETAILS()
    vol = MIXERCONTROLDETAILS_UNSIGNED()

    mxcd.item = 0
    mxcd.dwControlID = mxc.dwControlID
    mxcd.cbStruct = sizeof(mxcd)
    mxcd.cbDetails = sizeof(vol)

    #' Allocate a buffer for the control value buffer
    mxcd.paDetails = addressof(vol)
    mxcd.cChannels = 1
    #vol.dwValue = volume

    #' Get the control value
    #err = mixerGetControlDetails(hmixer, byref(mxcd), 0)
    err = mixerGetControlDetails(hmixer, byref(mxcd), MIXER_GETCONTROLDETAILSF_VALUE)
    

    if err != MMSYSERR_NOERROR:
        return None
    return vol.dwValue
edit:
I just realized I'm using an older version of SoundMixer.py from SourceForge, this should still work though (I think? Well when what's wrong is fixed).

stottle
Plugin Developer
Posts: 636
Joined: Sun Apr 26, 2009 10:59 pm

Re: PeakMeter values from SoundMixer.py

Post by stottle » Fri Aug 07, 2009 6:20 pm

If you import FormatError (from eg.WinApi.Dynamic import FormatError), then you can print a human readable error message instead of just the number.

So where it has

Code: Select all

print str(rc) + " step2 rc2"
add the following:

Code: Select all

from eg.WinApi.Dynamic import FormatError
print "Error = " + FormatError()
That should make searching for the problem easier. This is a Windows error message, not an eg message, so Google may be your best bet once you get the error string.

Good luck,
Brett

ShelleyJohnson
Posts: 2
Joined: Fri Aug 07, 2009 4:04 pm

Re: PeakMeter values from SoundMixer.py

Post by ShelleyJohnson » Sat Aug 08, 2009 3:10 pm

Error = <no description>
:(

Post Reply