' ************************************************* ' * support library for standard windows * ' * audio mixer devices for * ' * note that the audio mixer implementation under* ' * Windows must have been written coded and * ' * designed by an absolute mental wreck in the * ' * service of MicroSoft ... * ' ************************************************* ' procedure and function code module. ' Separated from g_hgen 12.05.2000 ' 08.2001 researched by Kristof Lauwers '%gm = %True ' disable after debugging and for public exposure... FUNCTION GetAvailableMixerDevices$ () EXPORT ' This function is no longer in use in GMT. LOCAL aantalMixers AS LONG LOCAL Caps AS MIXERCAPS LOCAL uSize AS LONG LOCAL n AS LONG LOCAL szMessage AS ASCIIZ * 1000 szMessage =" Installed Audio Mixers" + CHR$(13) aantalMixers = MixerGetNumDevs ' win32api - mm uSize = SIZEOF (Caps) n = %False DO mixerGetDevCaps BYVAL n, Caps, uSize szMessage = szMessage + STR$(n) + " = " + Caps.szPname + CHR$(13) szMessage = szMessage + " wMid=" + STR$(Caps.wMid) + " wPid=" + STR$(Caps.wPid) + "driver:" + STR$(Caps.vDriverversion) + CHR$(13) szMessage = szMessage + " destinations=" + STR$(Caps.cDestinations) + " " +CHR$(13) ' STR$(fdwSupport) + CHR$(13) INCR n LOOP UNTIL n = aantalMixers IF aantalMixers <= 0 THEN FUNCTION = "NO MIXERS AVAILABLE IN THIS CONFIGURATION" + CHR$(13) ELSE FUNCTION = szMessage + $CRLF END IF END FUNCTION SUB GetMixers (mp() AS STRING) EXPORT ' 16.11.99 - used for building the setup menu in GMT, such that users can select a suitable mixer, in case more than ' a single mixer is available in the configuration. LOCAL NrDevs AS LONG LOCAL n AS LONG NrDevs = mixerGetNumDevs() IF NrDevs < %True THEN EXIT SUB REDIM mp(NrDevs -1) AS STRING DIM Caps AS MIXERCAPS n = %False DO mixerGetDevCaps n, Caps, SIZEOF(Caps) mp(n) = Caps.szPName & " Dest:" & STR$(Caps.cDestinations) ' geeft aantal submixers (In,Out,Low Priority) ' mixerlines in Microsoft terminology. INCR n LOOP UNTIL n = NrDevs END SUB SUB MixerLines (BYREF OutPutMixer AS AudioMixerLineType, BYREF InputMixer AS AudioMixerLineType) EXPORT ' [working o.k. - 14.05.2000] ' returns details about the complete configuration for an opened mixer device. (handle in @pgh.wMix) LOCAL deviceID AS DWORD 'LONG LOCAL MixLine AS MIXERLINE ' enumerates main lines (output mixer, input mixer...) LOCAL MixLineSub AS MIXERLINE LOCAL Caps AS MIXERCAPS LOCAL Tar AS TARGET LOCAL i AS DWORD ' mixer line counter LOCAL j AS DWORD ' mixer element counter LOCAL k AS DWORD ' mixer line-element controll counter LOCAL l AS DWORD LOCAL st AS STRING LOCAL retval AS LONG IF ISFALSE @pgh.wMix THEN MSGBOX "[Mixerlines] can only be called after opening a mixer!" EXIT SUB ELSE ' knowing the mixer handle we can retrieve the device id. by calling: ' this id nr. is the number as selected out of the list of available mixer devices in the setup menu. retval = mixerGetID (@pgh.wMix, deviceID, %MIXER_OBJECTF_HMIXER) IF retval <> %MMSYSERR_NOERROR THEN MSGBOX "Error in call to MixerGetID" END IF retval = mixerGetDevCaps (deviceID, Caps, SIZEOF(Caps)) IF retval <> %MMSYSERR_NOERROR THEN MSGBOX "Error in call to MixerGetDevCaps" END IF END IF ' the first two lines seem to always correspond to the output and input mixer respectively... ' experiment: ' FOR i = 0 TO auxGetNumDevs - 1 ' GetMixerLineIdForAux i ' NEXT i ' GetMixerLineIdForMidiSynth 0 ' GetMixerLineIdForMidiInput 0 ' GetMixerLineIdForWaveInput 0 ' GetMixerLineIdForWaveOutput 0 ' end experiment MixLine.cbStruct = SIZEOF(MixLine) ' set up an array to store data about output and input mixer: pOutPutMixer = VARPTR(Outputmixer) ' this is a GLOBAL AudioMixerLineType PTR pInputMixer = VARPTR(InputMixer) IF Caps.cDestinations < 2 THEN MSGBOX "This mixer has no output and input destinations..." END IF ' each destination is a 'mixer line' in microsoft terminology. ' mixer-line 0 is the output mixer, line 1 is the input or recording mixer. FOR i = 0 TO 1 'Caps.cDestinations - 1 ' 0 to 1 is enough for our application... MixLine.szShortname = "" MixLine.szName = "" MixLine.dwSource = %False MixLine.dwDestination = i ' Master, Record and LowPriIn mixer... - selects the mixer-line MixerGetLineInfo @pgh.wMix, Mixline,%MIXER_GETLINEINFOF_DESTINATION ' return properties of destinations ' dwSource must be %False !!! ' this is how to check the returned flags: st = "audio " IF (MixLine.fdwLine AND %MIXERLINE_LINEF_ACTIVE) = %MIXERLINE_LINEF_ACTIVE THEN st = st + "line active " END IF IF (MixLine.fdwLine AND %MIXERLINE_LINEF_DISCONNECTED) = %MIXERLINE_LINEF_DISCONNECTED THEN st = st + "disconnected " END IF IF (MixLine.fdwLine AND %MIXERLINE_LINEF_SOURCE) = %MIXERLINE_LINEF_SOURCE THEN st = st + "source line" END IF 'MSGBOX MixLine.szName & $CRLF & MixLine.szShortName & $CRLF & st ' o.k. - works fine 'st = MixLine.szName & $CRLF & MixLine.szShortName & $CRLF & st & " : " st = MixLine.szName & $CRLF & $CRLF & st & " : " SELECT CASE i CASE 0 ' this is always the output mixer line @pOutPutMixer.id = MixLine.dwLineID ' redundant @pOutputMixer.lineid(0) = MixLine.dwLineID @pOutPutMixer.linetag(0)= MixLine.szName @pOutPutMixer.nrfaders = MixLine.cConnections CASE 1 ' this is always the input mixer line @pInputMixer.id = MixLine.dwLineID ' redundant @pInputMixer.lineid(0) = MixLine.dwLineID @pInputMixer.linetag(0) = MixLine.szName @pInputMixer.nrfaders = MixLine.cConnections CASE 2 ' this is the low priority mixer. Not used in GMT. END SELECT ' now we can check each component of these two mixers: FOR j = 0 TO MixLine.cConnections -1 ' aantal elementen ('faders') in deze mixer. MixLineSub.cbStruct = SIZEOF(MixLine) MixLineSub.szShortname = "" MixLineSub.szName = "" MixLineSub.dwSource = j ' this selects the mixer element nr. MixLineSub.dwDestination = i ' this selects the mixer line. MixerGetLineInfo @pgh.wMix, MixlineSub,%MIXER_GETLINEINFOF_SOURCE ' return properties of destinations ' dwSource must be set st = st + $CRLF + HEX$(MixLineSub.dwLineID) & " " & MixLineSub.szName ' check the flags for the element: IF (MixLineSub.fdwLine AND %MIXERLINE_LINEF_ACTIVE) = %MIXERLINE_LINEF_ACTIVE THEN st = st + "line active " END IF IF (MixLineSub.fdwLine AND %MIXERLINE_LINEF_DISCONNECTED) = %MIXERLINE_LINEF_DISCONNECTED THEN st = st + "disconnected " END IF IF (MixLineSub.fdwLine AND %MIXERLINE_LINEF_SOURCE) = %MIXERLINE_LINEF_SOURCE THEN st = st + "source line" END IF st = st + " Channels=" & STR$(MixLineSub.cChannels) & " Ctrls=" & STR$(MixLineSub.cControls) 'MSGBOX MixLineSub.szName & $CRLF & MixLineSub.szShortName & $CRLF & st ' o.k. - works fine ' returns the functional names of all mixer sliders. SELECT CASE i CASE 0 @pOutputMixer.linetag(j+1) = MixLineSub.szName ' name of the element @pOutputMixer.lineID(j+1) = MixLineSub.dwLineID ' use as abstract handle to the mixer element @pOutputMixer.channels(j+1)= MixLineSub.cChannels ' number of audio channels used by the element @pOutputMixer.controls(j+1)= MixLineSub.cControls ' number of controllable components: ' sliders, switches, meters... @pOutputMixer.componenttype(j+i) = MixLineSub.dwComponenttype 'added kl010830 ' MSGBOX STR$(MixLineSub.dwComponenttype) CASE 1 @pInputMixer.linetag(j+1) = MixLineSub.szName @pInputMixer.lineID(j+1) = MixLineSub.dwLineID @pInputMixer.channels(j+1) = MixLineSub.cChannels @pInputMixer.controls(j+1) = MixLineSub.cControls @pInputMixer.componenttype(j+i) = MixLineSub.dwComponenttype 'added kl010830 END SELECT ' test: ' FOR k = 0 TO MixLineSub.cControls -1 ' DIM MixLineSubSub AS MIXERLINE ' MixLineSubSub = MixLineSub ' MixLineSubSub.cbStruct = SIZEOF(MixLine) ' MixLineSubSub.szShortname = "" ' MixLineSubSub.szName = "" ' MixLineSubSub.dwSource = j ' this selects the mixer element nr. ' MixLineSubSub.dwDestination = i ' this selects the mixer line. ' MixLineSubSub.cControls = k ' MixerGetLineInfo @pgh.wMix, MixlineSubSub,%MIXER_GETLINEINFOF_LINEID ' return properties of destinations ' MSGBOX MixLineSubSub.szName & MixLineSubSub.szShortname ' returns channel names again ' NEXT k '--------- #IF %DEF(%gm) IF i < 2 THEN ' only for lines 0 and 1 IF MixLineSub.cControls THEN ' if there are any controls in this element... ' here we can try to retrieve more information about the mixer element... 'REDIM mxct(0 TO MixLineSub.cControls-1) AS LOCAL MIXERCONTROL 'DIM mxlct AS LOCAL MIXERLINECONTROLS FOR k = 0 TO MixLineSub.cControls -1 DIM mxlct AS LOCAL MIXERLINECONTROLS ' TYPE MIXERLINECONTROLS ' cbStruct AS LONG 'size in Byte of MIXERLINECONTROLS ' dwLineID AS LONG 'line id (from MIXERLINE.dwLineID) ' ' MIXER_GETLINECONTROLSF_ONEBYID or ' dwControl AS LONG 'MIXER_GETLINECONTROLSF_ONEBYTYPE ' cControls AS LONG 'count of controls pmxctrl points to ' cbmxctrl AS LONG 'size in Byte of _one_ MIXERCONTROL ' pamxctrl AS MIXERCONTROL 'pointer to first MIXERCONTROL array ' END TYPE DIM mxct AS LOCAL MIXERCONTROL ' - receiving buffer - no elements to prepare here... ' mxct.dwControlID = k ' ?? 'mxct.dwControlType = Mixlinesub.fdwLine ' mxct.cMultipleItems = 0 ' mxct.szshortname ' returned ' mxct.szname ' returned ' mxct.cbStruct = SIZEOF(mxct) mxlct.cControls = 1 ' mxlct.dwLineID = MixLineSub.dwLineID ' o.k. not required with onebyid flag mxlct.dwControl = %MIXERCONTROL_CONTROLTYPE_VOLUME '&H806 'MixLineSub.dwLineID 'OR k ' ' or k+1?? 'OR MixLine.dwLineID ' experiment... mxlct.cbmxctrl = SIZEOF(mxct) ' o.k. mxlct.pamxctrl = mxct ' o.k. mxlct.cbstruct = SIZEOF(mxlct) ' o.k. retval = mixerGetLineControls (i,mxlct,%MIXER_GETLINECONTROLSF_ONEBYTYPE)' invalid params. 'retval = mixerGetLineControls (i,mxlct,%MIXER_GETLINECONTROLSF_ONEBYID)' OR %MIXER_OBJECTF_MIXER)' invalid params 'retval = mixerGetLineControls (MixLineSub.dwLineID,mxlct,%MIXER_GETLINECONTROLSF_ONEBYTYPE) 'invalid handle / params alternating errors 'retval = mixerGetLineControls (@pgh.wMix,mxlct,%MIXER_GETLINECONTROLSF_ONEBYID) ' inval. params 'retval = mixerGetLineControls (@pgh.wMix,mxlct,%MIXER_GETLINECONTROLSF_ONEBYID OR %MIXER_OBJECTF_HMIXER) ' inavl.params. IF retval = %MMSYSERR_NOERROR THEN ' call successfull !!! st = st + $CRLF + "element id=" & HEX$(mxct.dwControlID) & $CRLF st = st + HEX$(mxlct.dwControl) st = st & mxct.szName & " " & mxct.szShortName & $CRLF st = st & MixAppGetControlTypeName(mxct) & $CRLF MSGBOX st st = "" ELSE ' ReportMixerError retval END IF ' if above not sucessfull, we can experiment with mixerGetControlDetails... NEXT k DIM mdtl AS LOCAL MIXERCONTROLDETAILS DIM ltxt(MixLineSub.cControls -1) AS LOCAL MIXERCONTROLDETAILS_LISTTEXT mdtl.paDetails = VARPTR(ltxt(0)) 'VARPTR(ltxt(0)) mdtl.dwControlID = MixLineSub.dwLineID '@pOutputmixer.lineID(1) mdtl.cChannels = 2'1 'MixLineSub.cChannels '@pOutputmixer.channels(1) mdtl.item = 0 'MixLineSub.cControls '0 'k '1 'k-1 - problematic. mdtl.cbDetails = SIZEOF(ltxt(0)) * MixLineSub.cControls 'SIZEOF(ltxt(0)) * (UBOUND(ltxt)+1) retval = mixerGetControlDetails (@pgh.wMix,mdtl,%MIXER_GETCONTROLDETAILSF_LISTTEXT OR %MIXER_OBJECTF_HMIXER) ' %MIXER_GETCONTROLDETAILSF_LISTTEXT IF retval = %MMSYSERR_NOERROR THEN MSGBOX "Gelukt !!!" ELSE '... SELECT CASE retval CASE %MIXERR_INVALCONTROL MSGBOX "Invalid control reference" CASE %MMSYSERR_BADDEVICEID MSGBOX "Bad device Identifier" CASE %MMSYSERR_INVALFLAG MSGBOX "one or more invalid flags" CASE %MMSYSERR_INVALHANDLE MSGBOX "invalid handle passed" CASE %MMSYSERR_INVALPARAM MSGBOX "invalid parameter(s)" ' xxxx CASE %MMSYSERR_NODRIVER MSGBOX "no mixer available for object specified in hmxobj" END SELECT END IF ' NEXT k ' close mixer line/element/ controll loop END IF END IF #ENDIF NEXT j ' close mixer element counter loop 'MSGBOX st & $CRLF NEXT i ' close mixer line loop. ' g_MixerWaveOutFaders 1 ' suppose 1 is the waveout slider ' MixerFaders 0, 0 ' try line 0, fader 0 ' MixerFaders 1, 0 ' MixerFaders 0, 1 ' MixerFaders 1, 1 ' g_MixerGetControlDetails @pgh.wMix END SUB SUB MixerFaders (BYVAL lijn AS DWORD, BYVAL n AS DWORD) EXPORT ' not yet functional !!!! LOCAL mxlct AS MIXERLINECONTROLS LOCAL mxct() AS MIXERCONTROL LOCAL st AS STRING LOCAL i AS DWORD LOCAL retval AS LONG LOCAL dwControlID AS DWORD ' retrieves details about tne nth fadercontroller in an outputmixer ' @pOutPutMixer.lineID(n) mxlct.cbStruct = SIZEOF(mxlct) IF ISFALSE lijn THEN IF ISFALSE @pOutputMixer.controls(n) THEN EXIT SUB ' quit if there are no controls associated with this line... DIM mxct(@pOutputMixer.controls(n)-1) AS LOCAL MIXERCONTROL mxlct.dwControl = &H806 'dwControlID '@pOutputMixer.dwControlID ' just pointer!? mxlct.dwLineID = @pOutputMixer.lineID(n) ELSE IF ISFALSE @pInputMixer.controls(n) THEN EXIT SUB DIM mxct(@pInputMixer.controls(n)-1) AS LOCAL MIXERCONTROL mxlct.dwControl = &H807 'dwControlID '@pInputMixer.dwControlID 'dwControlID ' just pointer!? mxlct.dwLineID = @pInputMixer.lineID(n) END IF 'mxlct.dwControl = %MIXER_GETLINECONTROLSF_ONEBYID ' either controlID or dwControlType 'mxlct.dwControlType mxlct.cControls = @pOutputMixer.controls(n) mxlct.cbmxctrl = SIZEOF(mxct(0)) * (UBOUND(mxct)+1) mxlct.pamxctrl = VARPTR(mxct(0)) retval = mixerGetLineControls (@pOutPutMixer.lineID(0),mxlct,%MIXER_GETLINECONTROLSF_ONEBYID) 'retval = mixerGetLineControls (@pgh.wMix,mxlct,%MIXER_GETLINECONTROLSF_ONEBYID) ' IF retval <> %MMSYSERR_NOERROR THEN ' MSGBOX "Error calling mixerGetLineControls" ' EXIT SUB ' END IF ' to be done... FOR i = 0 TO UBOUND(mxct) st = st + "fader-ctrl id=" & HEX$(mxct(i).dwControlID) & $CRLF st = st & mxct(i).szName & " " & mxct(i).szShortName & $CRLF st = st & MixAppGetControlTypeName(mxct(i)) & $CRLF NEXT i MSGBOX st & $CRLF END SUB SUB g_MixerWaveOutFaders (BYVAL n AS DWORD) EXPORT ' n = number of the mixer element. - not yet working... LOCAL mxlct AS MIXERLINECONTROLS ' TYPE MIXERLINECONTROLS ' cbStruct AS LONG 'size in Byte of MIXERLINECONTROLS ' dwLineID AS LONG 'line id (from MIXERLINE.dwLineID) ' ' MIXER_GETLINECONTROLSF_ONEBYID or ' dwControl AS LONG 'MIXER_GETLINECONTROLSF_ONEBYTYPE ' cControls AS LONG 'count of controls pmxctrl points to ' cbmxctrl AS LONG 'size in Byte of _one_ MIXERCONTROL ' pamxctrl AS MIXERCONTROL 'pointer to first MIXERCONTROL array ' END TYPE LOCAL mxct() AS MIXERCONTROL LOCAL i AS DWORD LOCAL st AS STRING ' retrieves details about tne nth fadercontroller in an outputmixer IF ISFALSE @pOutputMixer.controls(n) THEN EXIT SUB ' quit if there are no controls associated with this line... DIM mxct(@pOutputMixer.controls(n)-1) AS LOCAL MIXERCONTROL FOR i = 0 TO @pOutputMixer.controls(n) -1 ' loop for all the controls for this mixer-channel mxlct.cbStruct = SIZEOF(mxlct) mxlct.dwLineID = @pOutputMixer.lineID(n) mxlct.pamxctrl = VARPTR(mxct(0)) ' !!! ok mxlct.dwControl = %MIXER_GETLINECONTROLSF_ONEBYID mxlct.cControls = @pOutputMixer.controls(n) mixerGetLineControls hWo(0),mxlct,%MIXER_OBJECTF_HWAVEOUT ' wave out fader/device st = "Waveout-ctrl " & STR$(i) & " id=" & HEX$(mxct(i).dwControlID) & $CRLF st = st & mxct(i).szName & " " & mxct(i).szShortName & $CRLF st = st & MixAppGetControlTypeName(mxct(i)) MSGBOX st & $CRLF NEXT i END SUB FUNCTION WinMix_Mute(BYVAL hMix AS DWORD, BYVAL componenttype AS DWORD, BYVAL mute AS LONG) EXPORT AS LONG 'mute a component in mixer with handle hmix. var mute = 1 to mute, 0 to unmute 'returns %false on succes, otherwise winapi ERR returnvalue 'componenttype: winapi constants: %MIXERLINE_COMPONENTTYPE_DST_FIRST, %MIXERLINE_COMPONENTTYPE_DST_UNDEFINED '%MIXERLINE_COMPONENTTYPE_DST_DIGITAL, %MIXERLINE_COMPONENTTYPE_DST_LINE,%MIXERLINE_COMPONENTTYPE_DST_MONITOR '%MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, %MIXERLINE_COMPONENTTYPE_DST_HEADPHONES, %MIXERLINE_COMPONENTTYPE_DST_TELEPHONE '%MIXERLINE_COMPONENTTYPE_DST_WAVEIN, %MIXERLINE_COMPONENTTYPE_DST_VOICEIN,%MIXERLINE_COMPONENTTYPE_DST_LAST '%MIXERLINE_COMPONENTTYPE_SRC_FIRST, %MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED, %MIXERLINE_COMPONENTTYPE_SRC_DIGITAL '%MIXERLINE_COMPONENTTYPE_SRC_LINE, %MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, %MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER '%MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC, %MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE, %MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER '%MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT, %MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY, %MIXERLINE_COMPONENTTYPE_SRC_ANALOG '%MIXERLINE_COMPONENTTYPE_SRC_LAST LOCAL retval AS DWORD LOCAL cChannels AS DWORD LOCAL MixLineSub AS MIXERLINE LOCAL MxCtl AS MIXERCONTROL LOCAL MxLCtl AS MIXERLINECONTROLS LOCAL mxctldetbool AS MIXERCONTROLDETAILS_BOOLEAN 'mixercontroldetails_boolean LOCAL mxctd AS MIXERCONTROLDETAILS 'mixercontroldetails MixLineSub.cbStruct = SIZEOF(MixLineSub) MixLineSub.dwComponentType = componenttype '%MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC 'DST_WAVEIN retval = mixerGetLineInfo(hMix, MixLineSub, %MIXER_GETLINEINFOF_COMPONENTTYPE) IF retval THEN FUNCTION = retval: EXIT FUNCTION MxLCtl.cbStruct = SIZEOF(MxlCtl) MxLCtl.dwLineID = MixLineSub.dwLineID MxLCtl.dwControl = %MIXERCONTROL_CONTROLTYPE_MUTE MxLCtl.cControls = 1 MxLCtl.cbMxctrl = SIZEOF(MxCtl) MxLCtl.paMxctrl = VARPTR(MxCtl) 'mxctl retval = MixerGetLineControls(hMix, MxLCtl, %MIXER_GETLINECONTROLSF_ONEBYTYPE) IF retval THEN FUNCTION = retval: EXIT FUNCTION IF %MIXERCONTROL_CONTROLF_uniform AND MxCtl.fdwControl THEN 'meaning: IF the line is multichannel (~= stereo?) the control works for all channels cChannels = 1 mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxctd.cChannels = cChannels mxCtd.item = 0 mxctd.cbDetails = SIZEOF(mxctldetbool) mxctd.paDetails = VARPTR(mxctldetbool) mxctldetbool.fvalue = mute '1 '0 retval = MixerSetControlDetails(hmix, mxctd, %MIXER_SETCONTROLDETAILSF_VALUE) IF ISFALSE retval THEN FUNCTION = retval: EXIT FUNCTION END IF FUNCTION = %false END FUNCTION FUNCTION WinMix_SetVolume(BYVAL hMix AS DWORD, BYVAL componenttype AS DWORD, BYVAL l AS WORD, BYVAL r AS WORD) EXPORT AS LONG 'sets volume for a line in the windows mixer, componenttype as in Winmix_mute, l/r = volume(percent) of left/right 'if hardware doesnt support independent channels, both are set to l value 'note: having a different l/r value equals moving the panning slider in the visual mixerinterface LOCAL retval AS LONG LOCAL cChannels AS LONG LOCAL Mxl AS MIXERLINE LOCAL MxlCtl AS MIXERLINECONTROLS LOCAL MxCtl AS MIXERCONTROL LOCAL Mxctd AS MIXERCONTROLDETAILS Mxl.cbStruct = SIZEOF(Mxl) Mxl.dwComponentType = componenttype '%MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC 'DST_WAVEIN retval = mixerGetLineInfo(hMix, mxl, %MIXER_GETLINEINFOF_COMPONENTTYPE) MxLCtl.cbStruct = SIZEOF(MxlCtl) MxLCtl.dwLineID = Mxl.dwLineID MxLCtl.dwControl = %MIXERCONTROL_CONTROLTYPE_VOLUME MxLCtl.cControls = 1 MxLCtl.cbMxctrl = SIZEOF(MxCtl) MxLCtl.paMxctrl = VARPTR(MxCtl) 'mxctl retval = MixerGetLineControls(hMix, MxLCtl, %MIXER_GETLINECONTROLSF_ONEBYTYPE) IF retval THEN FUNCTION = retval: EXIT FUNCTION cChannels = mxl.cChannels IF %MIXERCONTROL_CONTROLF_UNIFORM AND mxctl.fdwControl THEN cChannels = 1 DIM unsgn (1 TO cChannels) AS MIXERCONTROLDETAILS_UNSIGNED mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxCtd.cChannels = cChannels '1 mxCtd.item = 0 'cChannels mxctd.cbDetails = SIZEOF(unsgn(1)) mxctd.paDetails = VARPTR(unsgn(1)) retval = MixerGetControlDetails(hMix, mxctd, %MIXER_SETCONTROLDETAILSF_VALUE) IF l > 100 THEN l = 100 unsgn(1).dwvalue = mxctl.lMinimum + (l/100) * (mxctl.lMaximum - mxctl.lMinimum) IF UBOUND(unsgn) > 1 THEN IF r > 100 THEN r = 100 unsgn(2).dwvalue = mxctl.lMinimum + (r/100) * (mxctl.lMaximum - mxctl.lMinimum) END IF retval = MixerSetControlDetails(hMix, mxctd, %MIXER_SETCONTROLDETAILSF_VALUE) IF retval THEN FUNCTION = retval: EXIT FUNCTION FUNCTION = %false END FUNCTION FUNCTION WinMix_Rec_SetVolume(BYVAL hMix AS DWORD, BYVAL componenttype AS DWORD, BYVAL l AS WORD, BYVAL r AS WORD) EXPORT AS LONG 'set volume in recording mixer for componenttype (cfr. WinMix_Mute), left vol(percent), right vol(percent) 'if yr hardware doesn't allow different vol for left/right, left vol is used for both 'returns %false on succes, otherwose win retval or %true for nonexisting componenttype LOCAL i AS LONG LOCAL retval AS LONG LOCAL mxl AS MIXERLINE LOCAL mxctl AS MIXERCONTROL LOCAL mxlctl AS MIXERLINECONTROLS LOCAL unsgn AS MIXERCONTROLDETAILS_UNSIGNED LOCAL mxctd AS MIXERCONTROLDETAILS LOCAL cConnections AS DWORD LOCAL cChannels AS DWORD mxl.cbStruct = SIZEOF(mxl) mxl.dwComponentType = %MIXERLINE_COMPONENTTYPE_DST_WAVEIN retval = mixerGetLineInfo(hMix, mxl, %MIXER_GETLINEINFOF_COMPONENTTYPE) IF retval THEN FUNCTION = retval: EXIT FUNCTION cConnections = mxl.cConnections FOR i = 1 TO cConnections 'couldnt we use the code from select proc??? mxl.dwSource = i mixerGetLineInfo hMix, mxl, %MIXER_GETLINEINFOF_SOURCE IF mxl.dwComponentType = componenttype THEN EXIT FOR NEXT IF (i = cConnections) AND (mxl.dwComponentType = componenttype) THEN FUNCTION = %true: EXIT FUNCTION MxLCtl.cbStruct = SIZEOF(MxlCtl) MxLCtl.dwLineID = Mxl.dwLineID MxLCtl.dwControl = %MIXERCONTROL_CONTROLTYPE_VOLUME MxLCtl.cControls = 1 'cCtrl '1 MxLCtl.cbMxctrl = SIZEOF(MxCtl) MxLCtl.paMxctrl = VARPTR(MxCtl) retval = MixerGetLineControls (hmix, MxLCtl, %MIXER_GETLINECONTROLSF_ONEBYTYPE) IF retval THEN FUNCTION = retval: EXIT FUNCTION cChannels = mxl.cChannels IF %MIXERCONTROL_CONTROLF_UNIFORM AND mxctl.fdwControl THEN cChannels = 1 DIM unsgn (1 TO cChannels) AS MIXERCONTROLDETAILS_UNSIGNED mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxCtd.cChannels = cChannels '1 mxCtd.item = 0 'cChannels mxctd.cbDetails = SIZEOF(unsgn(1)) mxctd.paDetails = VARPTR(unsgn(1)) retval = MixerGetControlDetails(hMix, mxctd, %MIXER_SETCONTROLDETAILSF_VALUE) IF l > 100 THEN l = 100 unsgn(1).dwvalue = mxctl.lMinimum + (l/100) * (mxctl.lMaximum - mxctl.lMinimum) IF UBOUND(unsgn) > 1 THEN IF r > 100 THEN r = 100 unsgn(2).dwvalue = mxctl.lMinimum + (r/100) * (mxctl.lMaximum - mxctl.lMinimum) END IF retval = MixerSetControlDetails(hMix, mxctd, %MIXER_SETCONTROLDETAILSF_VALUE) IF retval THEN FUNCTION = retval: EXIT FUNCTION FUNCTION = %false END FUNCTION FUNCTION WinMix_Rec_Select(BYVAL hMix AS DWORD, BYVAL component AS STRING) EXPORT AS LONG 'selects line from rec mixer, component can be: MIDI CD LINE MIC AUX DAT TELEPHONE (=MODEM) VIDEO MIX 'returns false on succes, otherwise winapi retval or %true for device not found LOCAL i AS LONG LOCAL retval AS DWORD LOCAL cChannels AS DWORD LOCAL cCtrl AS DWORD LOCAL MixLineSub AS MIXERLINE LOCAL MxCtl AS MIXERCONTROL LOCAL MxLCtl AS MIXERLINECONTROLS LOCAL mxctldetlisttext AS MIXERCONTROLDETAILS_LISTTEXT LOCAL mxctd AS MIXERCONTROLDETAILS LOCAL lineID AS LONG MixLineSub.cbStruct = SIZEOF(MixLineSub) MixLineSub.dwComponentType = %MIXERLINE_COMPONENTTYPE_DST_WAVEIN retval = mixerGetLineInfo(hMix, MixLineSub, %MIXER_GETLINEINFOF_COMPONENTTYPE) IF retval THEN FUNCTION = %false: EXIT FUNCTION cCtrl = MixLineSub.cControls MxLCtl.cbStruct = SIZEOF(MxlCtl) MxLCtl.dwLineID = MixLineSub.dwLineID MxLCtl.dwControl = %MIXERCONTROL_CONTROLTYPE_MUX MxLCtl.cControls = cCtrl '1 MxLCtl.cbMxctrl = SIZEOF(MxCtl) MxLCtl.paMxctrl = VARPTR(MxCtl) retval = MixerGetLineControls(hMix, MxLCtl, %MIXER_GETLINECONTROLSF_ONEBYTYPE) '_ALL cChannels = MxcTl.cMultipleItems 'note windoze's weird behaviour: the MixLineSub.cControls field is set to 0, although we didn't pass this type here... IF retval THEN FUNCTION = %false: EXIT FUNCTION IF %MIXERCONTROL_CONTROLF_uniform AND MxCtl.fdwControl THEN DIM mxctldetlist(1 TO cChannels) AS MIXERCONTROLDETAILS_LISTTEXT mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxCtd.cChannels = 1 mxCtd.item = cChannels mxctd.cbDetails = SIZEOF(mxctldetlist(1)) mxctd.paDetails = VARPTR(mxctldetlist(1)) retval = mixerGetControlDetails(hMix, MxCtd, %MIXER_GETCONTROLDETAILSF_LISTTEXT) 'now find out wich one is what > by label. stupid, but that's the way to go according to the msdn docu! FOR i = 1 TO cchannels mxctldetlist(i).szname = UCASE$(mxctldetlist(i).szname) SELECT CASE UCASE$(TRIM$(Component)) CASE "MIDI" IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "MIDI") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "SYNTH") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR CASE "CD" IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "CD") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "COMPACT") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR CASE "LINE" IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "LINE") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR CASE "MIC" IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "MIC") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR CASE "AUX" 'pretty useless. can be anything IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "AUX") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR CASE "DAT" IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "DAT") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR CASE "TELEPHONE", "MODEM" IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "TEL") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "PHONE") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "MODEM") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR CASE "VIDEO" IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "VIDEO") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR CASE "MIX" IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "MIX") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "WAVE") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "LOOP") = mxctldetlist(i).szname) THEN lineID = i: EXIT FOR END SELECT NEXT IF ISFALSE lineID THEN MSGBOX "invalid or unsupported mixer element passed",,"WinMix_Rec_Select" FUNCTION = %true EXIT FUNCTION END IF DIM mxctldetbool(1 TO cChannels) AS MIXERCONTROLDETAILS_BOOLEAN mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxctd.cChannels = 1 'cChannels mxCtd.item = cChannels '0 mxctd.cbDetails = SIZEOF(mxctldetbool(1)) mxctd.paDetails = VARPTR(mxctldetbool(1)) FOR i = 1 TO cChannels mxctldetbool(i).fvalue = %false NEXT mxctldetbool(lineID).fvalue = %true retval = MixerSetControlDetails(hMix, mxctd, %MIXER_SETCONTROLDETAILSF_VALUE) ' IF retval THEN FUNCTION = retval: EXIT FUNCTION END IF FUNCTION = %false END FUNCTION FUNCTION WinMix_GetMute(BYVAL hMix AS DWORD, BYVAL componenttype AS DWORD) EXPORT AS LONG 'get the mute status of a component in mixer with handle hmix 'returns %false: not muted, 1: muted, -1:function failed 'componenttype: winapi constants LOCAL retval AS DWORD LOCAL cChannels AS DWORD LOCAL MixLineSub AS MIXERLINE LOCAL MxCtl AS MIXERCONTROL LOCAL MxLCtl AS MIXERLINECONTROLS LOCAL mxctldetbool AS MIXERCONTROLDETAILS_BOOLEAN 'mixercontroldetails_boolean LOCAL mxctd AS MIXERCONTROLDETAILS 'mixercontroldetails FUNCTION = -1 MixLineSub.cbStruct = SIZEOF(MixLineSub) MixLineSub.dwComponentType = componenttype '%MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC 'DST_WAVEIN retval = mixerGetLineInfo(hMix, MixLineSub, %MIXER_GETLINEINFOF_COMPONENTTYPE) IF retval THEN FUNCTION = -1: EXIT FUNCTION MxLCtl.cbStruct = SIZEOF(MxlCtl) MxLCtl.dwLineID = MixLineSub.dwLineID MxLCtl.dwControl = %MIXERCONTROL_CONTROLTYPE_MUTE MxLCtl.cControls = 1 MxLCtl.cbMxctrl = SIZEOF(MxCtl) MxLCtl.paMxctrl = VARPTR(MxCtl) 'mxctl retval = MixerGetLineControls(hMix, MxLCtl, %MIXER_GETLINECONTROLSF_ONEBYTYPE) IF retval THEN FUNCTION = -1: EXIT FUNCTION cChannels = 1 mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxctd.cChannels = cChannels mxCtd.item = 0 mxctd.cbDetails = SIZEOF(mxctldetbool) mxctd.paDetails = VARPTR(mxctldetbool) mxctldetbool.fvalue = 1 'mute '1 '0 retval = MixerGetControlDetails(hmix, mxctd, %MIXER_GETCONTROLDETAILSF_VALUE) IF ISFALSE retval THEN IF mxctldetbool.fvalue THEN FUNCTION = 1 ELSE FUNCTION = 0 END IF ELSE FUNCTION = -1 END IF END FUNCTION FUNCTION WinMix_GetVolume(BYVAL hMix AS DWORD, BYVAL componenttype AS DWORD, BYREF l AS LONG, BYREF r AS LONG) EXPORT AS LONG 'gets volume for a line in the windows mixer, componenttype as in Winmix_mute ' l/r will be filled WITH volume(percent) of LEFT/RIGHT 'returns 0 on succes, -1 on failure LOCAL retval AS LONG LOCAL cChannels AS LONG LOCAL Mxl AS MIXERLINE LOCAL MxlCtl AS MIXERLINECONTROLS LOCAL MxCtl AS MIXERCONTROL LOCAL Mxctd AS MIXERCONTROLDETAILS Mxl.cbStruct = SIZEOF(Mxl) Mxl.dwComponentType = componenttype '%MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC 'DST_WAVEIN retval = mixerGetLineInfo(hMix, mxl, %MIXER_GETLINEINFOF_COMPONENTTYPE) MxLCtl.cbStruct = SIZEOF(MxlCtl) MxLCtl.dwLineID = Mxl.dwLineID MxLCtl.dwControl = %MIXERCONTROL_CONTROLTYPE_VOLUME MxLCtl.cControls = 1 MxLCtl.cbMxctrl = SIZEOF(MxCtl) MxLCtl.paMxctrl = VARPTR(MxCtl) 'mxctl retval = MixerGetLineControls(hMix, MxLCtl, %MIXER_GETLINECONTROLSF_ONEBYTYPE) IF retval THEN FUNCTION = -1: EXIT FUNCTION cChannels = mxl.cChannels IF %MIXERCONTROL_CONTROLF_UNIFORM AND mxctl.fdwControl THEN cChannels = 1 DIM unsgn (1 TO cChannels) AS MIXERCONTROLDETAILS_UNSIGNED mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxCtd.cChannels = cChannels '1 mxCtd.item = 0 'cChannels mxctd.cbDetails = SIZEOF(unsgn(1)) mxctd.paDetails = VARPTR(unsgn(1)) retval = MixerGetControlDetails(hMix, mxctd, %MIXER_GETCONTROLDETAILSF_VALUE) IF retval THEN FUNCTION = -1: EXIT FUNCTION l = (unsgn(1).dwValue - mxctl.lMinimum) * 100 / (mxctl.lMaximum - mxctl.lMinimum) IF UBOUND(unsgn) > 1 THEN r = (unsgn(2).dwvalue - mxctl.lMinimum) * 100 /(mxctl.lMaximum - mxctl.lMinimum) ELSE r = l END IF FUNCTION = %false END FUNCTION FUNCTION WinMix_Rec_GetSelect(BYVAL hMix AS DWORD) EXPORT AS STRING 'returns selected line from rec mixer, can be: MIDI CD LINE MIC AUX DAT TELEPHONE (=MODEM) VIDEO MIX NONE UNDEFINED(on error) 'returns false on succes, otherwise winapi retval or %true for device not found LOCAL i AS LONG LOCAL retval AS DWORD LOCAL cChannels AS DWORD LOCAL cCtrl AS DWORD LOCAL MixLineSub AS MIXERLINE LOCAL MxCtl AS MIXERCONTROL LOCAL MxLCtl AS MIXERLINECONTROLS LOCAL mxctldetlisttext AS MIXERCONTROLDETAILS_LISTTEXT LOCAL mxctd AS MIXERCONTROLDETAILS LOCAL lineID AS LONG MixLineSub.cbStruct = SIZEOF(MixLineSub) MixLineSub.dwComponentType = %MIXERLINE_COMPONENTTYPE_DST_WAVEIN retval = mixerGetLineInfo(hMix, MixLineSub, %MIXER_GETLINEINFOF_COMPONENTTYPE) IF retval THEN FUNCTION = "UNDEFINED": EXIT FUNCTION cCtrl = MixLineSub.cControls MxLCtl.cbStruct = SIZEOF(MxlCtl) MxLCtl.dwLineID = MixLineSub.dwLineID MxLCtl.dwControl = %MIXERCONTROL_CONTROLTYPE_MUX MxLCtl.cControls = cCtrl '1 MxLCtl.cbMxctrl = SIZEOF(MxCtl) MxLCtl.paMxctrl = VARPTR(MxCtl) retval = MixerGetLineControls(hMix, MxLCtl, %MIXER_GETLINECONTROLSF_ONEBYTYPE) '_ALL cChannels = MxcTl.cMultipleItems 'note windoze's weird behaviour: the MixLineSub.cControls field is set to 0, although we didn't pass this type here... IF retval THEN FUNCTION = "UNDEFINED": EXIT FUNCTION IF %MIXERCONTROL_CONTROLF_uniform AND MxCtl.fdwControl THEN DIM mxctldetlist(1 TO cChannels) AS MIXERCONTROLDETAILS_LISTTEXT mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxCtd.cChannels = 1 mxCtd.item = cChannels mxctd.cbDetails = SIZEOF(mxctldetlist(1)) mxctd.paDetails = VARPTR(mxctldetlist(1)) retval = mixerGetControlDetails(hMix, MxCtd, %MIXER_GETCONTROLDETAILSF_LISTTEXT) IF retval THEN FUNCTION = "UNDEFINED" DIM mxctldetbool(1 TO cChannels) AS MIXERCONTROLDETAILS_BOOLEAN mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxctd.cChannels = 1 'cChannels mxCtd.item = cChannels '0 mxctd.cbDetails = SIZEOF(mxctldetbool(1)) mxctd.paDetails = VARPTR(mxctldetbool(1)) retval = MixerGetControlDetails(hMix, mxctd, %MIXER_GETCONTROLDETAILSF_VALUE) ' IF retval THEN FUNCTION = "UNDEFINED": EXIT FUNCTION FOR i = 1 TO cchannels IF mxctldetbool(i).fvalue = %true THEN 'now find out wich one is what > by label. stupid, but that's the way to go according to the msdn docu! mxctldetlist(i).szname = UCASE$(mxctldetlist(i).szname) IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "MIDI") = mxctldetlist(i).szname) THEN FUNCTION = "MIDI": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "SYNTH") = mxctldetlist(i).szname) THEN FUNCTION = "MIDI": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "CD") = mxctldetlist(i).szname) THEN FUNCTION = "CD": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "COMPACT") = mxctldetlist(i).szname) THEN FUNCTION = "CD": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "LINE") = mxctldetlist(i).szname) THEN FUNCTION = "LINE": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "MIC") = mxctldetlist(i).szname) THEN FUNCTION = "MIC": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "AUX") = mxctldetlist(i).szname) THEN FUNCTION = "AUX": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "DAT") = mxctldetlist(i).szname) THEN FUNCTION = "DAT": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "TEL") = mxctldetlist(i).szname) THEN FUNCTION = "TELEPHONE": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "PHONE") = mxctldetlist(i).szname) THEN FUNCTION = "TELEPHONE": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "MODEM") = mxctldetlist(i).szname) THEN FUNCTION = "TELEPHONE": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "VIDEO") = mxctldetlist(i).szname) THEN FUNCTION = "VIDEO": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "MIX") = mxctldetlist(i).szname) THEN FUNCTION = "MIX": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "WAVE") = mxctldetlist(i).szname) THEN FUNCTION = "MIX": EXIT FUNCTION IF ISFALSE (EXTRACT$(mxctldetlist(i).szName, "LOOP") = mxctldetlist(i).szname) THEN FUNCTION = "MIX": EXIT FUNCTION END IF NEXT FUNCTION = "NONE" END IF END FUNCTION FUNCTION WinMix_Rec_GetVolume(BYVAL hMix AS DWORD, BYVAL componenttype AS DWORD, BYREF l AS LONG, BYREF r AS LONG) EXPORT AS LONG 'get volume in recording mixer for componenttype (cfr. WinMix_Mute) 'fills in l/r with LEFT vol(percent), RIGHT vol(percent) 'returns %false on succes, otherwose win retval or -1 for nonexisting componenttype LOCAL i AS LONG LOCAL retval AS LONG LOCAL mxl AS MIXERLINE LOCAL mxctl AS MIXERCONTROL LOCAL mxlctl AS MIXERLINECONTROLS LOCAL unsgn AS MIXERCONTROLDETAILS_UNSIGNED LOCAL mxctd AS MIXERCONTROLDETAILS LOCAL cConnections AS DWORD LOCAL cChannels AS DWORD mxl.cbStruct = SIZEOF(mxl) mxl.dwComponentType = %MIXERLINE_COMPONENTTYPE_DST_WAVEIN retval = mixerGetLineInfo(hMix, mxl, %MIXER_GETLINEINFOF_COMPONENTTYPE) IF retval THEN FUNCTION = -1: EXIT FUNCTION cConnections = mxl.cConnections FOR i = 1 TO cConnections 'couldnt we use the code from select proc??? mxl.dwSource = i mixerGetLineInfo hMix, mxl, %MIXER_GETLINEINFOF_SOURCE IF mxl.dwComponentType = componenttype THEN EXIT FOR NEXT IF (i = cConnections) AND (mxl.dwComponentType = componenttype) THEN FUNCTION = %true: EXIT FUNCTION MxLCtl.cbStruct = SIZEOF(MxlCtl) MxLCtl.dwLineID = Mxl.dwLineID MxLCtl.dwControl = %MIXERCONTROL_CONTROLTYPE_VOLUME MxLCtl.cControls = 1 'cCtrl '1 MxLCtl.cbMxctrl = SIZEOF(MxCtl) MxLCtl.paMxctrl = VARPTR(MxCtl) retval = MixerGetLineControls (hmix, MxLCtl, %MIXER_GETLINECONTROLSF_ONEBYTYPE) IF retval THEN FUNCTION = retval: EXIT FUNCTION cChannels = mxl.cChannels IF %MIXERCONTROL_CONTROLF_UNIFORM AND mxctl.fdwControl THEN cChannels = 1 DIM unsgn (1 TO cChannels) AS MIXERCONTROLDETAILS_UNSIGNED mxctd.cbstruct = SIZEOF(mxctd) mxctd.dwControlID = MxCtl.dwControlID mxCtd.cChannels = cChannels '1 mxCtd.item = 0 'cChannels mxctd.cbDetails = SIZEOF(unsgn(1)) mxctd.paDetails = VARPTR(unsgn(1)) retval = MixerGetControlDetails(hMix, mxctd, %MIXER_SETCONTROLDETAILSF_VALUE) IF retval THEN FUNCTION = -1: EXIT FUNCTION l = (unsgn(1).dwValue - mxctl.lMinimum) * 100 / (mxctl.lMaximum - mxctl.lMinimum) IF UBOUND(unsgn) > 1 THEN r = (unsgn(2).dwvalue - mxctl.lMinimum) * 100 /(mxctl.lMaximum - mxctl.lMinimum) ELSE r = l END IF FUNCTION = %false END FUNCTION FUNCTION SaveMixerSettings(fn AS STRING) EXPORT AS LONG 'give fn as param, so we can store mixer settings for a piece in gmt.ini '& store settings before we cange them IN a temp file, so we can restore them afterwards 'if fn allready contains mixersettings the're overwritten. if not, the mixersettings are inserted just before "[EOF]" LOCAL f AS LONG LOCAL tmpf AS LONG LOCAL tmpfn AS STRING LOCAL dum$ LOCAL i AS LONG LOCAL l AS LONG, r AS LONG tmpfn = PARSE$(fn, ".",1)+".tmp" IF ISFALSE(existfile(fn)) THEN 'create empty file f = FREEFILE OPEN fn FOR APPEND LOCK SHARED AS f CLOSE f END IF f = FREEFILE OPEN fn FOR INPUT LOCK SHARED AS f tmpf = FREEFILE OPEN tmpfn FOR OUTPUT AS tmpf DO INPUT# f, dum$ IF TRIM$(UCASE$(dum$)) = "[MIXER]" THEN EXIT LOOP IF TRIM$(UCASE$(dum$)) = "[EOF]" THEN EXIT LOOP PRINT# tmpf, dum$ IF EOF(f) THEN EXIT LOOP END IF LOOP PRINT# tmpf, "[MIXER]" 'write mute status, left vol, right vol in playback mixer. for ALL POSSIBLE COMPONENTTYPES 'mute status -1 for nonexisting ones PRINT# tmpf, "[Playback]" FOR i = %MIXERLINE_COMPONENTTYPE_SRC_FIRST TO %MIXERLINE_COMPONENTTYPE_SRC_LAST WinMix_GetVolume @pgh.wMix, i, l, r PRINT# tmpf, WinMix_GetMute(@pgh.wMix, i), l, r NEXT FOR i = %MIXERLINE_COMPONENTTYPE_DST_FIRST TO %MIXERLINE_COMPONENTTYPE_DST_LAST WinMix_GetVolume @pgh.wMix, i, l, r PRINT# tmpf, WinMix_GetMute(@pgh.wMix, i), l, r NEXT 'write selected line in recording mixer PRINT# tmpf, "[Recording select]" PRINT# tmpf, WinMix_Rec_GetSelect(@pgh.wMix) 'write volumes for recording mixer PRINT# tmpf, "[Recording volumes]" FOR i = %MIXERLINE_COMPONENTTYPE_SRC_FIRST TO %MIXERLINE_COMPONENTTYPE_SRC_LAST WinMix_Rec_GetVolume @pgh.wMix, i, l, r PRINT# tmpf, l, r NEXT FOR i = %MIXERLINE_COMPONENTTYPE_DST_FIRST TO %MIXERLINE_COMPONENTTYPE_DST_LAST WinMix_Rec_GetVolume @pgh.wMix, i, l, r PRINT# tmpf, l, r NEXT PRINT# tmpf, "[MIXER_END]" DO INPUT# f, dum$ IF EOF(f) THEN EXIT LOOP LOOP UNTIL TRIM$(UCASE$(dum$)) = "[MIXER_END]" DO INPUT# f, dum$ PRINT# tmpf, dum$ LOOP UNTIL EOF(f) IF TRIM$(UCASE$(dum$)) <> "[EOF]" THEN PRINT# tmpf, "[EOF]" END IF CLOSE f CLOSE tmpf IF tmpfn <> fn THEN FILECOPY tmpfn, fn KILL tmpfn END IF FUNCTION = %true END FUNCTION FUNCTION LoadMixerSettings(fn AS STRING) EXPORT AS LONG 'read mixersettings from gmt midi & restore them 'formatting must be exactly as done by SaveMixerSettings!! LOCAL f AS LONG LOCAL dum$ LOCAL i AS LONG LOCAL chck AS LONG LOCAL r AS LONG, l AS LONG IF ISFALSE ExistFile (fn) THEN FUNCTION = %False : EXIT FUNCTION OPEN fn FOR INPUT LOCK SHARED AS f DO INPUT# f, dum$ IF UCASE$(TRIM$(dum$)) = "[MIXER]" THEN EXIT LOOP IF (UCASE$(TRIM$(dum$)) = "[EOF]") OR EOF(f) THEN FUNCTION = %false CLOSE f EXIT FUNCTION END IF LOOP DO UNTIL EOF(f) INPUT# f, dum$ IF UCASE$(TRIM$(dum$)) = "[MIXER_END]" THEN FUNCTION = %true CLOSE f EXIT FUNCTION END IF SELECT CASE UCASE$(TRIM$(dum$)) CASE "[PLAYBACK]" FOR i = %MIXERLINE_COMPONENTTYPE_SRC_FIRST TO %MIXERLINE_COMPONENTTYPE_SRC_LAST INPUT# f, chck IF chck >=0 THEN WinMix_Mute @pgh.wMix, i, chck INPUT# f, l INPUT# f, r WinMix_SetVolume @pgh.wMix, BYVAL i, BYVAL l, BYVAL r NEXT FOR i = %MIXERLINE_COMPONENTTYPE_DST_FIRST TO %MIXERLINE_COMPONENTTYPE_DST_LAST INPUT# f, chck IF chck >=0 THEN WinMix_Mute @pgh.wMix, i, chck INPUT# f, l INPUT# f, r WinMix_SetVolume @pgh.wMix, BYVAL i, BYVAL l, BYVAL r NEXT CASE "[RECORDING SELECT]" INPUT# f, dum$ WinMix_Rec_Select @pgh.wMix, dum$ CASE "[RECORDING VOLUMES]" FOR i = %MIXERLINE_COMPONENTTYPE_SRC_FIRST TO %MIXERLINE_COMPONENTTYPE_SRC_LAST INPUT# f, l INPUT# f, r WinMix_Rec_SetVolume @pgh.wMix, BYVAL i, BYVAL l, BYVAL r NEXT FOR i = %MIXERLINE_COMPONENTTYPE_DST_FIRST TO %MIXERLINE_COMPONENTTYPE_DST_LAST INPUT# f, l INPUT# f, r WinMix_Rec_SetVolume @pgh.wMix, BYVAL i, BYVAL l, BYVAL r NEXT END SELECT LOOP FUNCTION = %false EXIT FUNCTION END FUNCTION FUNCTION g_MixerSetControlDetails (BYVAL Device AS LONG) AS LONG LOCAL mxd AS MIXERCONTROLDETAILS LOCAL fdw AS DWORD SELECT CASE Device CASE hMidiO(0) fdw = %MIXER_OBJECTF_HMIDIOUT CASE hMidiI(0) fdw = %MIXER_OBJECTF_HMIDIIN CASE hWo(0) fdw = %MIXER_OBJECTF_HWAVEOUT CASE hWi(0) fdw = %MIXER_OBJECTF_HWAVEIN CASE @pAudioFader(0).id fdw = %MIXER_OBJECTF_AUX CASE @pgh.wMix fdw = %MIXER_OBJECTF_HMIXER ' CASE ELSE ' fdw = %MIXER_SETCONTROLSDETAILSF_VALUE ' or _GET cfr. notice in msdn END SELECT END FUNCTION FUNCTION g_MixerGetControlDetails (BYVAL Device AS LONG) AS LONG LOCAL retval AS LONG LOCAL mxd AS MIXERCONTROLDETAILS LOCAL fdw AS DWORD LOCAL ltxt() AS MIXERCONTROLDETAILS_LISTTEXT LOCAL mxct AS MIXERCONTROL mxd.cbStruct = SIZEOF(mxd) SELECT CASE Device CASE hMidiO(0) fdw = %MIXER_OBJECTF_HMIDIOUT CASE hMidiI(0) fdw = %MIXER_OBJECTF_HMIDIIN CASE hWo(0) fdw = %MIXER_OBJECTF_HWAVEOUT CASE hWi(0) fdw = %MIXER_OBJECTF_HWAVEIN CASE @pAudioFader(0).id fdw = %MIXER_OBJECTF_AUX CASE @pgh.wMix fdw = %MIXER_OBJECTF_HMIXER DIM ltxt(@pOutputmixer.controls(1)) AS LOCAL MIXERCONTROLDETAILS_LISTTEXT ' test control 1 mxd.paDetails = VARPTR(ltxt(0) ) mxd.dwControlID = @pOutputmixer.lineID(1) mxd.cChannels = @pOutputmixer.channels(1) mxd.item = 3 ' mxct.cMultipleItems - problematic. mxd.cbDetails = SIZEOF(ltxt(0)) * (UBOUND(ltxt)+1) ' CASE ELSE ' fdw = %MIXER_SETCONTROLSDETAILSF_VALUE ' or _GET cfr. notice in msdn END SELECT ' extra flags: %MIXER_GETCONTROLDETAILSF_LISTTEXT ---> mxd.cbDetails = SIZEOF(ltxt) ' %MIXER_GETCONTROLDETAILSF_VALUE ---> retval = mixerGetControlDetails(@pgh.wMix,mxd,%MIXER_GETCONTROLDETAILSF_LISTTEXT) ' should retrieve anu control specified in mxd IF retval <> %MMSYSERR_NOERROR THEN MSGBOX "error in g_MixerGetControlDetails" EXIT FUNCTION END IF ' note: 'TYPE MIXERCONTROLDETAILS ' cbStruct AS LONG 'size in Byte of MIXERCONTROLDETAILS ' dwControlID AS LONG 'control id to get/set details on ' cChannels AS LONG 'number of channels in paDetails array ' item AS LONG 'hwndOwner or cMultipleItems ' cbDetails AS LONG 'size of _one_ details_XX struct ' paDetails AS LONG 'pointer to array of details_XX structs 'END TYPE ' MIXER_GETCONTROLDETAILSF_LISTTEXT 'TYPE MIXERCONTROLDETAILS_LISTTEXT ' dwParam1 AS LONG ' dwParam2 AS LONG ' szName AS ASCIIZ * %MIXER_LONG_NAME_CHARS 'END TYPE ' MIXER_GETCONTROLDETAILSF_VALUE 'TYPE MIXERCONTROLDETAILS_BOOLEAN ' fValue AS LONG 'END TYPE 'TYPE MIXERCONTROLDETAILS_SIGNED ' lValue AS LONG 'END TYPE 'TYPE MIXERCONTROLDETAILS_UNSIGNED ' dwValue AS LONG 'END TYPE END FUNCTION FUNCTION MixAppGetControlTypeName (mxctrl AS MIXERCONTROL) EXPORT AS STRING ' translated from C code. - 14.05.2000 SELECT CASE mxctrl.dwControlType CASE %MIXERCONTROL_CONTROLTYPE_CUSTOM FUNCTION= "Custom!" CASE %MIXERCONTROL_CONTROLTYPE_BOOLEANMETER FUNCTION = "Boolean Meter" CASE %MIXERCONTROL_CONTROLTYPE_SIGNEDMETER FUNCTION = "Signed Meter" CASE %MIXERCONTROL_CONTROLTYPE_PEAKMETER FUNCTION = "Peak Meter" CASE %MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER FUNCTION = "Unsigned Meter" CASE %MIXERCONTROL_CONTROLTYPE_BOOLEAN FUNCTION = "Boolean Switch" CASE %MIXERCONTROL_CONTROLTYPE_ONOFF FUNCTION = "On/Off Switch" CASE %MIXERCONTROL_CONTROLTYPE_MUTE FUNCTION = "Mute Switch" CASE %MIXERCONTROL_CONTROLTYPE_MONO FUNCTION = "Mono Switch" CASE %MIXERCONTROL_CONTROLTYPE_LOUDNESS FUNCTION = "Loudness Switch" CASE %MIXERCONTROL_CONTROLTYPE_STEREOENH FUNCTION = "Stereo Enh Switch" CASE %MIXERCONTROL_CONTROLTYPE_BUTTON FUNCTION = "Button" CASE %MIXERCONTROL_CONTROLTYPE_DECIBELS FUNCTION = "Decibels Number" CASE %MIXERCONTROL_CONTROLTYPE_SIGNED FUNCTION = "Signed Number" CASE %MIXERCONTROL_CONTROLTYPE_PERCENT: FUNCTION = "Percent Number" CASE %MIXERCONTROL_CONTROLTYPE_UNSIGNED: FUNCTION = "Unsigned Number" CASE %MIXERCONTROL_CONTROLTYPE_SLIDER: FUNCTION = "Slider" CASE %MIXERCONTROL_CONTROLTYPE_PAN: FUNCTION = "Pan Slider" CASE %MIXERCONTROL_CONTROLTYPE_QSOUNDPAN: FUNCTION = "Q-Sound Pan Slider" CASE %MIXERCONTROL_CONTROLTYPE_FADER: FUNCTION = "Fader" CASE %MIXERCONTROL_CONTROLTYPE_VOLUME FUNCTION = "Volume Fader" CASE %MIXERCONTROL_CONTROLTYPE_BASS FUNCTION = "Bass Fader" CASE %MIXERCONTROL_CONTROLTYPE_TREBLE FUNCTION = "Treble Fader" CASE %MIXERCONTROL_CONTROLTYPE_EQUALIZER FUNCTION = "Equalizer Fader" CASE %MIXERCONTROL_CONTROLTYPE_SINGLESELECT FUNCTION = "Single-Sel List" CASE %MIXERCONTROL_CONTROLTYPE_MUX FUNCTION = "MUX List" CASE %MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT FUNCTION = "Multi-Sel List" CASE %MIXERCONTROL_CONTROLTYPE_MIXER FUNCTION = "Mixer List" CASE %MIXERCONTROL_CONTROLTYPE_MICROTIME FUNCTION = "Microsecond Time" CASE %MIXERCONTROL_CONTROLTYPE_MILLITIME FUNCTION = "Millisecond Time" CASE ELSE 'DEFAULT: ' DPF(0, "!MixAppGetControlTypeName: invalid control type %.08lXh!", pmxctrl->dwControlType); ' lstrcpy(szControlType, "** NOT VALID **"); FUNCTION = "NOT VALID" '%False 'RETURN (FALSE); END SELECT END FUNCTION FUNCTION ProcMixer (BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, BYVAL dwInstance AS DWORD,_ BYVAL wParam AS LONG, BYVAL lParam AS LONG) EXPORT AS LONG ' This is to become the mixer-callbackprocedure... ' It is called on reception of mixer events. Therefore it is not a regular task. 'dwInstance wordt doorgegeven zoals bepaald bij de opening van de Mixer callback 'In dit geval, 0 'wMsg bevat de message konstante 'wParam bevat ... mixer handle ? 'lParam bevat ... LOCAL mxlc AS MIXERLINECONTROLS LOCAL mxctrl AS mixercontrol LOCAL retval AS LONG mxlc.cbStruct = SIZEOF(mxlc) SELECT CASE wMsg ' to be done... 'CASE %WM_INITDIALOG ' mxlc.dwControl = lParam ' CASE %MM_MIXM_CONTROL_CHANGE ' MSGBOX "dwControlID=" & HEX$(lParam) ' CASE %MM_MIXM_LINE_CHANGE END SELECT FUNCTION = 0 ' acknowledge result of callback function END FUNCTION ' ******************************** ' * FADER MANIPULATION CODE * ' ******************************** SUB SetFaders (AudioFader() AS AudioFaderType, WaveFader() AS AudioFaderType) EXPORT LOCAL i AS DWORD REDIM pAudioFader(UBOUND(AudioFader)) AS GLOBAL AudioFaderType PTR REDIM pWaveFader(UBOUND(WaveFader)) AS GLOBAL AudioFaderType PTR FOR i = 0 TO UBOUND(AudioFader) pAudioFader(i) = VARPTR(AudioFader(i)) NEXT i FOR i = 0 TO UBOUND(WaveFader) pWaveFader(i) = VARPTR(WaveFader(i)) NEXT i END SUB SUB WaveOutFader () EXPORT ' default fader task for the WaveOut device LOCAL volume AS DWORD LOCAL intervalRight AS LONG LOCAL intervalLeft AS LONG LOCAL nv AS LONG ' must be 32 bit bipolar LOCAL pVol AS DWORD PTR STATIC init AS BYTE STATIC nrsteps AS LONG STATIC stapRight AS LONG STATIC stapLeft AS LONG IF ISFALSE init THEN 'IF @pWaveFader(0).tasknr < %False THEN EXIT SUB IF @pWaveFader(0).id = -1 THEN StopTask @pWaveFader(0).tasknr :EXIT SUB IF ISFALSE hWo(0) THEN StopTask @pWaveFader(0).tasknr : EXIT SUB init = %True END IF IF ISFALSE @pTask(@pWaveFader(0).tasknr).tog THEN pVol = VARPTR(volume) 'waveOutGetVolume Audio.hWo, byval pVol 'volume - by handle waveOutGetVolume @pWaveFader(0).id, BYVAL pVol ' by ID @pWavefader(0).rightvolume = HIWRD (volume) @pWavefader(0).leftvolume = LOWRD (volume) @pTask(@pWaveFader(0).tasknr).tog = %True stapRight = %False stapLeft = %False intervalRight = (@pWaveFader(0).rightendvolume - @pWaveFader(0).rightvolume) ' if positive, crescendo, else diminuendo. intervalLeft = @pWaveFader(0).leftendvolume - @pWaveFader(0).leftvolume ' if positive, crescendo, else diminuendo. ' bereken nu het aantal uit te voeren stapjes: nrsteps = (@pTask(@pWaveFader(0).Tasknr).duur * @pTask(@pWaveFader(0).TaskNr).freq ) / 1000! IF nrsteps <= 1 THEN @pTask(@pWaveFader(0).TaskNr).duur = %False @pTask(@pWaveFader(0).TaskNr).tog = %False volume = @pWaveFader(0).RightendVolume SHIFT LEFT volume, 16 volume = volume OR @pWaveFader(0).LeftendVolume WaveOutSetVolume @pWaveFader(0).id, volume @pWaveFader(0).rightvolume = @pWaveFader(0).rightendVolume @pWaveFader(0).leftVolume = @pWaveFader(0).leftendvolume StopTask @pWaveFader(0).TaskNr EXIT SUB END IF ' bereken de stapgrootte in volumeunits: stapRight = intervalRight / nrsteps stapLeft = intervalLeft / nrsteps END IF ' we should move the faders at a maximum frequency of 12 steps a second. ' now do it: 'IF stapRight <> %False THEN nv = (stapright + (@pWaveFader(0).RightVolume)) SELECT CASE nv CASE < %False @pWaveFader(0).RightVolume = %False CASE > &H0FFFF& @pWaveFader(0).RightVolume = &HFFFF CASE ELSE @pWaveFader(0).RightVolume = nv AND &HFFFF END SELECT 'END IF 'IF stapLeft <> %False THEN nv = (stapleft + (@pWaveFader(0).LeftVolume)) SELECT CASE nv CASE < %False @pWaveFader(0).LeftVolume = %False CASE > &H0FFFF& @pWaveFader(0).LeftVolume = &HFFFF CASE ELSE @pWaveFader(0).LeftVolume = nv AND &HFFFF END SELECT 'END IF 'SetDlgItemText hCockpit, %GMT_TEXT0_ID + 11, STR$(WaveFader(0).RightVolume) & " " & STR$(WaveFader(0).LeftVolume) volume = LOWRD(@pWaveFader(0).RightVolume) SHIFT LEFT volume, 16 volume = volume OR (LOWRD(@pWaveFader(0).LeftVolume)) WaveOutSetVolume @pWaveFader(0).id, volume DECR nrsteps IF nrsteps <= %False THEN @pTask(@pWaveFader(0).Tasknr).tog = %False @pTask(@pWaveFader(0).Tasknr).duur = %False @pWaveFader(0).rightendVolume = @pWaveFader(0).rightvolume @pWaveFader(0).leftendVolume = @pWaveFader(0).leftvolume StopTask @pWaveFader(0).TaskNr END IF END SUB SUB WaveInFader () EXPORT ' default fader task for the WaveIn device LOCAL volume AS DWORD LOCAL intervalRight AS LONG LOCAL intervalLeft AS LONG LOCAL nv AS LONG ' must be 32 bit bipolar LOCAL pVol AS DWORD PTR STATIC init AS BYTE STATIC nrsteps AS LONG STATIC stapRight AS LONG STATIC stapLeft AS LONG IF ISFALSE init THEN IF @pWaveFader(1).id = -1 THEN StopTask @pWaveFader(1).tasknr :EXIT SUB IF ISFALSE hWi(0) THEN StopTask @pWaveFader(1).tasknr : EXIT SUB init = %True END IF IF ISFALSE @pTask(@pWaveFader(1).tasknr).tog THEN pVol = VARPTR(volume) 'waveOutGetVolume Audio.hWo, byval pVol 'volume - by handle waveOutGetVolume @pWaveFader(1).id, BYVAL pVol ' by ID @pWavefader(1).rightvolume = HIWRD (volume) @pWavefader(1).leftvolume = LOWRD (volume) @pTask(@pWaveFader(1).tasknr).tog = %True stapRight = %False stapLeft = %False intervalRight = (@pWaveFader(1).rightendvolume - @pWaveFader(1).rightvolume) ' if positive, crescendo, else diminuendo. intervalLeft = @pWaveFader(1).leftendvolume - @pWaveFader(1).leftvolume ' if positive, crescendo, else diminuendo. ' bereken nu het aantal uit te voeren stapjes: nrsteps = (@pTask(@pWaveFader(1).Tasknr).duur * @pTask(@pWaveFader(1).TaskNr).freq ) / 1000! IF nrsteps <= 1 THEN @pTask(@pWaveFader(1).TaskNr).duur = %False @pTask(@pWaveFader(1).TaskNr).tog = %False volume = @pWaveFader(1).RightendVolume SHIFT LEFT volume, 16 volume = volume OR @pWaveFader(1).LeftendVolume WaveOutSetVolume @pWaveFader(1).id, volume @pWaveFader(1).rightvolume = @pWaveFader(1).rightendVolume @pWaveFader(1).leftVolume = @pWaveFader(1).leftendvolume StopTask @pWaveFader(1).TaskNr EXIT SUB END IF ' bereken de stapgrootte in volumeunits: stapRight = intervalRight / nrsteps stapLeft = intervalLeft / nrsteps END IF ' we should move the faders at a maximum frequency of 12 steps a second. ' now do it: 'IF stapRight <> %False THEN nv = (stapright + (@pWaveFader(1).RightVolume)) SELECT CASE nv CASE < %False @pWaveFader(1).RightVolume = %False CASE > &H0FFFF& @pWaveFader(1).RightVolume = &HFFFF CASE ELSE @pWaveFader(1).RightVolume = nv AND &HFFFF END SELECT 'END IF 'IF stapLeft <> %False THEN nv = (stapleft + (@pWaveFader(1).LeftVolume)) SELECT CASE nv CASE < %False @pWaveFader(1).LeftVolume = %False CASE > &H0FFFF& @pWaveFader(1).LeftVolume = &HFFFF CASE ELSE @pWaveFader(1).LeftVolume = nv AND &HFFFF END SELECT 'END IF 'SetDlgItemText hCockpit, %GMT_TEXT0_ID + 11, STR$(WaveFader(1).RightVolume) & " " & STR$(WaveFader(1).LeftVolume) volume = LOWRD(@pWaveFader(1).RightVolume) SHIFT LEFT volume, 16 volume = volume OR (LOWRD(@pWaveFader(1).LeftVolume)) WaveOutSetVolume @pWaveFader(1).id, volume DECR nrsteps IF nrsteps <= %False THEN @pTask(@pWaveFader(1).Tasknr).tog = %False @pTask(@pWaveFader(1).Tasknr).duur = %False @pWaveFader(1).rightendVolume = @pWaveFader(1).rightvolume @pWaveFader(1).leftendVolume = @pWaveFader(1).leftvolume StopTask @pWaveFader(1).TaskNr END IF END SUB SUB Fader0 () EXPORT ' should be used as a task. ' the default tasknumber is set in AudioFader(0).tasknr ' the duration of the fade should be passed in Task().duur, expressed in milliseconds ' To be changed to support many fader instances in a single fader task. ' we can use the Task().channel field to pass the fader index. LOCAL volume AS DWORD LOCAL intervalRight AS LONG LOCAL intervalLeft AS LONG LOCAL pVol AS DWORD PTR LOCAL nv AS LONG STATIC stapRight AS LONG STATIC stapLeft AS LONG STATIC nrsteps AS LONG IF @pAudioFader(0).tasknr < %False THEN EXIT SUB IF ISFALSE @pTask(@pAudioFader(0).tasknr).tog THEN IF @pAudioFader(0).id = -1 THEN EXIT SUB pVol = VARPTR(volume) auxGetVolume @pAudioFader(0).id, BYVAL(pVol) ' id does not have to be 0 here!!! ' @pAudioFader(0) is always the first device selected!!! @pAudioFader(0).rightvolume = HIWRD (volume) @pAudioFader(0).leftvolume = LOWRD (volume) @pTask(@pAudioFader(0).tasknr).tog = %True intervalRight = @pAudioFader(0).rightendvolume - @pAudioFader(0).rightvolume ' if positive, crescendo, else diminuendo. intervalLeft = @pAudioFader(0).leftendvolume - @pAudioFader(0).leftvolume ' bereken nu het aantal uit te voeren stapjes: nrsteps = (@pTask(@pAudioFader(0).Tasknr).duur * @pTask(@pAudioFader(0).TaskNr).freq ) / 1000 IF nrsteps <= %False THEN volume = @pAudioFader(0).RightendVolume SHIFT LEFT volume, 16 volume = volume OR @pAudioFader(0).LeftendVolume AuxSetVolume @pAudioFader(0).id, volume @pAudioFader(0).rightvolume = @pAudioFader(0).rightendVolume @pAudioFader(0).leftVolume = @pAudioFader(0).leftendvolume @pTask(@pAudioFader(0).TaskNr).duur = %False @pTask(@pAudioFader(0).TaskNr).tog = %False StopTask @pAudioFader(0).TaskNr EXIT SUB END IF ' bereken de stapgrootte in volumeunits: stapRight = intervalRight / nrsteps stapLeft = intervalLeft / nrsteps END IF ' we should move the faders at a maximum frequency of 12 steps a second. ' now do it: 'IF stapRight <> %False THEN nv = @pAudioFader(0).RightVolume + stapRight SELECT CASE nv CASE < %False @pAudioFader(0).RightVolume = %False CASE > &H0FFFF& @pAudioFader(0).RightVolume = &H0FFFF& CASE ELSE @pAudioFader(0).RightVolume = LOWRD(nv) END SELECT 'END IF 'IF stapLeft <> %False THEN nv = @pAudioFader(0).LeftVolume + stapLeft SELECT CASE nv CASE < %False @pAudioFader(0).LeftVolume = %False CASE > &H0FFFF& @pAudioFader(0).LeftVolume = &H0FFFF& CASE ELSE @pAudioFader(0).LeftVolume = LOWRD(nv) END SELECT 'END IF volume = @pAudioFader(0).RightVolume SHIFT LEFT volume, 16 volume = volume OR @pAudioFader(0).LeftVolume auxSetVolume @pAudioFader(0).id, volume DECR nrsteps IF nrsteps <= %False THEN @pAudioFader(0).rightendVolume = @pAudioFader(0).rightvolume @pAudioFader(0).leftendVolume = @pAudioFader(0).leftvolume @pTask(@pAudioFader(0).Tasknr).tog = %False @pTask(@pAudioFader(0).Tasknr).duur = %False StopTask @pAudioFader(0).TaskNr END IF END SUB SUB Fader1 () EXPORT ' should be used as a task. ' the duration of the fade should be passed in Task().duur, expressed in milliseconds LOCAL volume AS DWORD LOCAL intervalRight AS LONG LOCAL intervalLeft AS LONG LOCAL pVol AS DWORD PTR LOCAL nv AS LONG STATIC nrsteps AS LONG STATIC stapRight AS LONG STATIC stapLeft AS LONG IF @pAudioFader(1).tasknr <= %False THEN EXIT SUB IF ISFALSE @pTask(@pAudioFader(1).tasknr).tog THEN IF @pAudioFader(1).id = -1 THEN EXIT SUB pVol = VARPTR(volume) AuxGetVolume @pAudioFader(1).id, BYVAL(pVol) 'BYVAL(VARPTR(volume)) @pAudioFader(1).rightvolume = HIWRD (volume) @pAudioFader(1).leftvolume = LOWRD (volume) @pTask(@pAudioFader(1).tasknr).tog = %True intervalRight = @pAudioFader(1).rightendvolume - @pAudioFader(1).rightvolume ' if positive, crescendo, else diminuendo. intervalLeft = @pAudioFader(1).leftendvolume - @pAudioFader(1).leftvolume ' bereken nu het aantal uit te voeren stapjes: nrsteps = (@pTask(@pAudioFader(1).Tasknr).duur * @pTask(@pAudioFader(1).TaskNr).freq ) / 1000! IF nrsteps <= %False THEN volume = @pAudioFader(1).RightendVolume SHIFT LEFT volume, 16 volume = volume OR @pAudioFader(1).LeftendVolume AuxSetVolume @pAudioFader(1).id, volume @pAudioFader(1).rightvolume = @pAudioFader(1).rightendVolume @pAudioFader(1).leftVolume = @pAudioFader(1).leftendvolume @pTask(@pAudioFader(1).TaskNr).duur = %False @pTask(@pAudioFader(1).TaskNr).tog = %False StopTask @pAudioFader(1).TaskNr EXIT SUB END IF ' bereken de stapgrootte in volumeunits: stapRight = intervalRight / nrsteps stapLeft = intervalLeft / nrsteps END IF ' we should move the faders at a maximum frequency of 12 steps a second. IF stapRight <> %False THEN nv = @pAudioFader(1).RightVolume + stapRight SELECT CASE nv CASE < %False @pAudioFader(1).RightVolume = %False CASE > &H0FFFF& @pAudioFader(1).RightVolume = &H0FFFF& CASE ELSE @pAudioFader(1).RightVolume = LOWRD(nv) END SELECT END IF IF stapLeft <> %False THEN nv = @pAudioFader(1).LeftVolume + stapLeft SELECT CASE nv CASE < %False @pAudioFader(1).LeftVolume = %False CASE > &H0FFFF& @pAudioFader(1).LeftVolume = &H0FFFF& CASE ELSE @pAudioFader(1).LeftVolume = LOWRD(nv) END SELECT END IF volume = LOWRD(@pAudioFader(1).RightVolume) SHIFT LEFT volume, 16 volume = volume OR @pAudioFader(1).LeftVolume AuxSetVolume @pAudioFader(1).id, volume DECR nrsteps IF nrsteps <= %False THEN @pAudioFader(1).rightendVolume = @pAudioFader(1).rightvolume @pAudioFader(1).leftendVolume = @pAudioFader(1).leftvolume @pTask(@pAudioFader(1).Tasknr).tog = %False @pTask(@pAudioFader(1).Tasknr).duur = %False StopTask @pAudioFader(1).TaskNr END IF END SUB SUB Fader2 () EXPORT ' should be used as a task. ' the duration of the fade should be passed in Task().duur, expressed in milliseconds LOCAL volume AS DWORD LOCAL intervalRight AS LONG LOCAL intervalLeft AS LONG LOCAL pVol AS DWORD PTR LOCAL nv AS LONG STATIC nrsteps AS LONG STATIC stapRight AS LONG STATIC stapLeft AS LONG IF @pAudioFader(2).tasknr <= %False THEN EXIT SUB IF ISFALSE @pTask(@pAudioFader(2).tasknr).tog THEN IF @pAudioFader(2).id = -1 THEN EXIT SUB pVol = VARPTR(volume) AuxGetVolume @pAudioFader(2).id, BYVAL(pVol) 'BYVAL(VARPTR(volume)) @pAudioFader(2).rightvolume = HIWRD (volume) @pAudioFader(2).leftvolume = LOWRD (volume) @pTask(@pAudioFader(2).tasknr).tog = %True intervalRight = @pAudioFader(2).rightendvolume - @pAudioFader(2).rightvolume ' if positive, crescendo, else diminuendo. intervalLeft = @pAudioFader(2).leftendvolume - @pAudioFader(2).leftvolume ' bereken nu het aantal uit te voeren stapjes: nrsteps = (@pTask(@pAudioFader(2).Tasknr).duur * @pTask(@pAudioFader(2).TaskNr).freq ) / 1000! IF nrsteps <= %False THEN volume = @pAudioFader(2).RightendVolume SHIFT LEFT volume, 16 volume = volume OR @pAudioFader(2).LeftendVolume AuxSetVolume @pAudioFader(2).id, volume @pAudioFader(2).rightvolume = @pAudioFader(2).rightendVolume @pAudioFader(2).leftVolume = @pAudioFader(2).leftendvolume @pTask(@pAudioFader(2).TaskNr).duur = %False @pTask(@pAudioFader(2).TaskNr).tog = %False StopTask @pAudioFader(2).TaskNr EXIT SUB END IF ' bereken de stapgrootte in volumeunits: stapRight = intervalRight / nrsteps stapLeft = intervalLeft / nrsteps END IF ' we should move the faders at a maximum frequency of 12 steps a second. IF stapRight <> %False THEN nv = @pAudioFader(2).RightVolume + stapRight SELECT CASE nv CASE < %False @pAudioFader(2).RightVolume = %False CASE > &H0FFFF& @pAudioFader(2).RightVolume = &H0FFFF& CASE ELSE @pAudioFader(2).RightVolume = LOWRD(nv) END SELECT END IF IF stapLeft <> %False THEN nv = @pAudioFader(2).LeftVolume + stapLeft SELECT CASE nv CASE < %False @pAudioFader(2).LeftVolume = %False CASE > &H0FFFF& @pAudioFader(2).LeftVolume = &H0FFFF& CASE ELSE @pAudioFader(2).LeftVolume = LOWRD(nv) END SELECT END IF volume = LOWRD(@pAudioFader(2).RightVolume) SHIFT LEFT volume, 16 volume = volume OR @pAudioFader(2).LeftVolume AuxSetVolume @pAudioFader(2).id, volume DECR nrsteps IF nrsteps <= %False THEN @pAudioFader(2).rightendVolume = @pAudioFader(2).rightvolume @pAudioFader(2).leftendVolume = @pAudioFader(2).leftvolume @pTask(@pAudioFader(2).Tasknr).tog = %False @pTask(@pAudioFader(2).Tasknr).duur = %False StopTask @pAudioFader(2).TaskNr END IF END SUB SUB Fader3 () EXPORT ' should be used as a task. ' the duration of the fade should be passed in Task().duur, expressed in milliseconds LOCAL volume AS DWORD LOCAL intervalRight AS LONG LOCAL intervalLeft AS LONG LOCAL pVol AS DWORD PTR LOCAL nv AS LONG STATIC nrsteps AS LONG STATIC stapRight AS LONG STATIC stapLeft AS LONG IF @pAudioFader(3).tasknr <= %False THEN EXIT SUB IF ISFALSE @pTask(@pAudioFader(3).tasknr).tog THEN IF @pAudioFader(3).id = -1 THEN EXIT SUB pVol = VARPTR(volume) AuxGetVolume @pAudioFader(3).id, BYVAL(pVol) 'BYVAL(VARPTR(volume)) @pAudioFader(3).rightvolume = HIWRD (volume) @pAudioFader(3).leftvolume = LOWRD (volume) @pTask(@pAudioFader(3).tasknr).tog = %True intervalRight = @pAudioFader(3).rightendvolume - @pAudioFader(3).rightvolume ' if positive, crescendo, else diminuendo. intervalLeft = @pAudioFader(3).leftendvolume - @pAudioFader(3).leftvolume ' bereken nu het aantal uit te voeren stapjes: nrsteps = (@pTask(@pAudioFader(3).Tasknr).duur * @pTask(@pAudioFader(3).TaskNr).freq ) / 1000! IF nrsteps <= %False THEN volume = @pAudioFader(3).RightendVolume SHIFT LEFT volume, 16 volume = volume OR @pAudioFader(3).LeftendVolume AuxSetVolume @pAudioFader(3).id, volume @pAudioFader(3).rightvolume = @pAudioFader(3).rightendVolume @pAudioFader(3).leftVolume = @pAudioFader(3).leftendvolume @pTask(@pAudioFader(3).TaskNr).duur = %False @pTask(@pAudioFader(3).TaskNr).tog = %False StopTask @pAudioFader(3).TaskNr EXIT SUB END IF ' bereken de stapgrootte in volumeunits: stapRight = intervalRight / nrsteps stapLeft = intervalLeft / nrsteps END IF ' we should move the faders at a maximum frequency of 12 steps a second. IF stapRight <> %False THEN nv = @pAudioFader(3).RightVolume + stapRight SELECT CASE nv CASE < %False @pAudioFader(3).RightVolume = %False CASE > &H0FFFF& @pAudioFader(3).RightVolume = &H0FFFF& CASE ELSE @pAudioFader(3).RightVolume = LOWRD(nv) END SELECT END IF IF stapLeft <> %False THEN nv = @pAudioFader(3).LeftVolume + stapLeft SELECT CASE nv CASE < %False @pAudioFader(3).LeftVolume = %False CASE > &H0FFFF& @pAudioFader(3).LeftVolume = &H0FFFF& CASE ELSE @pAudioFader(3).LeftVolume = LOWRD(nv) END SELECT END IF volume = LOWRD(@pAudioFader(3).RightVolume) SHIFT LEFT volume, 16 volume = volume OR @pAudioFader(3).LeftVolume AuxSetVolume @pAudioFader(3).id, volume DECR nrsteps IF nrsteps <= %False THEN @pAudioFader(3).rightendVolume = @pAudioFader(3).rightvolume @pAudioFader(3).leftendVolume = @pAudioFader(3).leftvolume @pTask(@pAudioFader(3).Tasknr).tog = %False @pTask(@pAudioFader(3).Tasknr).duur = %False StopTask @pAudioFader(3).TaskNr END IF END SUB FUNCTION GetMixerLineIdForMidiSynth (BYVAL devnr AS LONG) EXPORT AS LONG ' this functions returns the id for the mixer line the midi-out device may be connected to in ' the windows mixer. ' Only if the internal midi synth is selected, the function will return the line. ' 0 = output mixer ' 1 = input mixer ' 2 = low priority mixer LOCAL MID AS DWORD 'LONG LOCAL retval AS LONG LOCAL st AS STRING FUNCTION = -1 IF hMidiO(devnr) THEN retval = mixerGetID (hMidiO(devnr), MID, %MIXER_OBJECTF_HMIDIOUT) SELECT CASE retval CASE %MMSYSERR_NOERROR FUNCTION = MID EXIT FUNCTION CASE %MMSYSERR_BADDEVICEID st = "[GetMixerLineIdForMidiSynth]Error - Baddevice ID" CASE %MMSYSERR_INVALHANDLE st = "[GetMixerLineIdForMidiSynth]Error - Invalid handle" CASE %MMSYSERR_INVALFLAG st = "[GetMixerLineIdForMidiSynth]Error - Invalid flag" CASE %MMSYSERR_NODRIVER IF MID = -1 THEN st = "[GetMixerLineIdForMidiSynth]Error - no mixer device for midi synth" ELSE st = "[GetMixerLineIdForMidiSynth]Error - No Driver" END IF END SELECT MSGBOX st & $CRLF ELSE EXIT FUNCTION END IF END FUNCTION FUNCTION GetMixerLineIdForMidiInput (BYVAL devnr AS LONG) EXPORT AS LONG ' this functions returns the id for the mixer line the midi-input device may be connected to in ' the windows mixer. ' 0 = output mixer ' 1 = input mixer ' 2 = low priority mixer LOCAL MID AS DWORD 'LONG LOCAL retval AS LONG LOCAL st AS STRING FUNCTION = -1 IF hMidiI(devnr) THEN retval = mixerGetID (hMidiI(devnr), MID, %MIXER_OBJECTF_HMIDIIN) SELECT CASE retval CASE %MMSYSERR_NOERROR FUNCTION = MID EXIT FUNCTION CASE %MMSYSERR_BADDEVICEID st = "[GetMixerLineIdForMidiInput]Error - Baddevice ID" CASE %MMSYSERR_INVALHANDLE st = "[GetMixerLineIdForMidiInput]Error - Invalid handle" CASE %MMSYSERR_INVALFLAG st = "[GetMixerLineIdForMidiInput]Error - Invalid flag" CASE %MMSYSERR_NODRIVER IF MID = -1 THEN st = "[GetMixerLineIdForMidiInput]Error - no mixer device for midi input" ELSE st = "[GetMixerLineIdForMidiInput]Error - No Driver" END IF END SELECT MSGBOX st & $CRLF ELSE EXIT FUNCTION END IF END FUNCTION FUNCTION GetMixerLineIdForWaveInput (BYVAL devnr AS LONG) EXPORT AS LONG ' this functions returns the id for the mixer line the wave-input device ' the windows mixer. ' 0 = output mixer ' 1 = input mixer ' 2 = low priority mixer LOCAL wid AS DWORD 'LONG LOCAL retval AS LONG LOCAL st AS STRING FUNCTION = -1 IF hWI(devnr) THEN retval = mixerGetID (hWI(devnr), wid, %MIXER_OBJECTF_HWAVEIN) SELECT CASE retval CASE %MMSYSERR_NOERROR FUNCTION = wid EXIT FUNCTION CASE %MMSYSERR_BADDEVICEID st = "[GetMixerLineIdForWaveInput]Error - Baddevice ID" CASE %MMSYSERR_INVALHANDLE st = "[GetMixerLineIdForWaveInput]Error - Invalid handle" CASE %MMSYSERR_INVALFLAG st = "[GetMixerLineIdForWaveInput]Error - Invalid flag" CASE %MMSYSERR_NODRIVER IF wid = -1 THEN st = "[GetMixerLineIdForWaveInput]Error - no mixer device for wave input" ELSE st = "[GetMixerLineIdForWaveInput]Error - No Driver" END IF END SELECT MSGBOX st & $CRLF ELSE EXIT FUNCTION END IF END FUNCTION FUNCTION GetMixerLineIdForWaveOutput (BYVAL devnr AS LONG) EXPORT AS LONG ' this functions returns the id for the mixer line the wave-input device ' the windows mixer. ' 0 = output mixer ' 1 = input mixer ' 2 = low priority mixer LOCAL wid AS DWORD 'LONG LOCAL retval AS LONG LOCAL st AS STRING FUNCTION = -1 IF hWO(devnr) THEN retval = mixerGetID (hWO(devnr), wid, %MIXER_OBJECTF_HWAVEOUT) SELECT CASE retval CASE %MMSYSERR_NOERROR FUNCTION = wid EXIT FUNCTION CASE %MMSYSERR_BADDEVICEID st = "[GetMixerLineIdForWaveOutput]Error - Baddevice ID" CASE %MMSYSERR_INVALHANDLE st = "[GetMixerLineIdForWaveOutput]Error - Invalid handle" CASE %MMSYSERR_INVALFLAG st = "[GetMixerLineIdForWaveOutput]Error - Invalid flag" CASE %MMSYSERR_NODRIVER IF wid = -1 THEN st = "[GetMixerLineIdForWaveOutput]Error - no mixer device for wave output" ELSE st = "[GetMixerLineIdForWaveOutput]Error - No Driver" END IF END SELECT MSGBOX st & $CRLF ELSE EXIT FUNCTION END IF END FUNCTION FUNCTION GetMixerLineIdForAux (BYVAL devnr AS LONG) EXPORT AS LONG ' this functions returns the id for the mixer line ' the windows mixer. ' 0 = output mixer ' 1 = input mixer ' 2 = low priority mixer LOCAL aid AS DWORD 'LONG LOCAL retval AS LONG LOCAL st AS STRING FUNCTION = -1 retval = mixerGetID (devnr, aid, %MIXER_OBJECTF_AUX) SELECT CASE retval CASE %MMSYSERR_NOERROR FUNCTION = aid EXIT FUNCTION CASE %MMSYSERR_BADDEVICEID st = "[GetMixerLineIdForAux]Error - Baddevice ID" CASE %MMSYSERR_INVALHANDLE st = "[GetMixerLineIdForAux]Error - Invalid handle" CASE %MMSYSERR_INVALFLAG st = "[GetMixerLineIdForAux]Error - Invalid flag" CASE %MMSYSERR_NODRIVER IF aid = -1 THEN st = "[GetMixerLineIdForAux]Error - no mixer device for aux device" ELSE st = "[GetMixerLineIdForAux]Error - No Driver" END IF END SELECT MSGBOX st & $CRLF END FUNCTION FUNCTION ReportMixerError (BYVAL msgval AS LONG) EXPORT AS DWORD ' 09.06.2002 LOCAL m AS ASCIIZ * 60 LOCAL szTitelbox AS ASCIIZ * 20 szTitelbox = "-Mixer error" FUNCTION = %True SELECT CASE msgval CASE %MMSYSERR_NOERROR m= "" FUNCTION = %False EXIT FUNCTION CASE %MMSYSERR_BADDEVICEID m= "Failed: Mixer opened with out of range device ID" + CHR$(13) CASE %MMSYSERR_INVALFLAG m= "Failed: Mixer opened with invalid flags..." + CHR$(13) CASE %MMSYSERR_INVALPARAM m= "Failed: Mixer opened with invalid pointer or structure" + CHR$(13) CASE %MMSYSERR_NOMEM m= "Unable to allocate memory for mixer" +CHR$(13) CASE %MMSYSERR_ALLOCATED m= "Failed: mixer resource already allocated" + CHR$(13) CASE %MMSYSERR_INVALHANDLE m= "Failed: mixer opened with invalid handle" + CHR$(13) CASE %MMSYSERR_NODRIVER m= "Failed: no driver available for mixer device" + CHR$(13) END SELECT IF m <> "" THEN MessageBox @pgh.InstDll,m, szTitelbox,%MB_OK OR %MB_ICONASTERISK OR %MB_TASKMODAL OR %MB_TOPMOST END IF END FUNCTION '[EOF]