Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details

If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.

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 »

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 »

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 »

Error = <no description>
:(
Post Reply