[bb] Windows Audio Mixer Blitz Functions by Ziltch [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : Windows Audio Mixer Blitz Functions
Author : Ziltch
Posted : 1+ years ago

Description : examples

Include "audiomixer.bb"
; Watch the windows audio mixer while running this to see levels change.

; examples of setvolume function
; SetVolume(4,2000) this sets main volume to 2000 (0 to 65535 range)
; MixerName$ = SetVolume( MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,NewVolume)  This sets main volume
; MixerName$ = SetVolume( 262145,NewVolume,10000 ) This uses LineID to set LineIn/Mic record level.


While Not KeyHit(1)

  Cls
  Locate 1,10
  For controls% =  MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED To MIXERLINE_COMPONENTTYPE_SRC_LAST
  ; loop through all stanard window mixer lines.
  ; look in audiomixer include file for list of 'standard' types.
  ; your card will not have all types.

    If controls = MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED Then
      MixerControl =  MIXERLINE_COMPONENTTYPE_DST_SPEAKERS ; this is the main volume (NOTE: value is 4)
    Else
      MixerControl = controls
    EndIf

    OldVolume = GetVolume( MixerControl)
    ; Depending on sound card some special controls will fail
    ; if OldVolume = -1 it has failed.

    If OldVolume =>0 Then

      NewVolume = OldVolume + Rand(-1000,1000)
      MixerName$ = SetVolume( MixerControl, NewVolume)

      ; MixerName$ will contain name of Mixer control if volume was set OK.
      If MixerName$ <> "" Then
        Print MixerName$ + " number " + controls + " new value " +  NewVolume
      End If
    End If

  Next
  Delay 500
Wend
End


; This displays all your mixer line details.
; This info is very different for each sound card.

; It also creates a file containing the Name and lineID's of each mixer line.

graphics 800,600,16,2
include "audiomixer.bb"

setfont LoadFont("Arial",12,False,False,False)

local hMixer%
local uMixerCaps.MIXERCAPS = new MIXERCAPS
local uMixerDestinationLine.MIXERLINE = new MIXERLINE
local uMixerLineControls.MIXERLINECONTROLS = new MIXERLINECONTROLS
local uDetails.MIXERCONTROLDETAILS = new MIXERCONTROLDETAILS

local mxbank   = createbank(52)
local mxlbank  = createbank(168)
local mxlcbank = createbank(24)
local mxcbank = createbank(148)
local zerobank = createbank(4)


rc=mixerGetDevCaps(hmixer, mxbank, 52)
wMid%            = peekint(mxbank,0)
wPid%            = peekint(mxbank,4)
vDriverVersion%  = peekint(mxbank,8)
szPname$         = peekstr(mxbank,40,8)
fdwSupport       = peekint(mxbank,48)
cDestinations    = peekint(mxbank,44)

print
print "MIXER FOR " + szPname$
print
print "  DESTIMATIONS"
For iDestIndex = 0 To cDestinations - 1

  pokeint(mxlbank,0,banksize(mxlbank))   ;size of the struct
  pokeint(mxlbank,4,iDestIndex)          ;Destination index
  pokeint(mxlbank,8,0)                   ;This must be set to zero  when calling mixerGetLineInfo
                                         ;with the  MIXER_GETLINEINFOF_DESTINATION flag.


  rc=mixerGetLineInfo(hMixer, mxlbank, MIXER_GETLINEINFOF_DESTINATION)

  if rc = 0 then
    dwDestination%   = peekint(mxlbank,4);   zero based destination index
    dwSource%        = peekint(mxlbank,8);   zero based source index (if source)
    dwLineID%        = peekint(mxlbank,12);  unique line id for mixer device
    fdwLine%         = peekint(mxlbank,16);  state/information about line
    dwUser%          = peekint(mxlbank,20);  driver specific information
    cChannels%       = peekint(mxlbank,28);  number of channels line supports
    cConnections%    = peekint(mxlbank,32);  number of connections (possible)
    cControls%       = peekint(mxlbank,36);  number of controls at this line
    szShortName$     = peekstr(mxlbank,16,40)
    szName$          = peekstr(mxlbank,64,56)
    dwType%          = peekint(mxlbank, 120)
    dwDeviceID%      = peekint(mxlbank,124)
    wMid%            = peekint(mxlbank,128)
    wPid%            = peekint(mxlbank,130)
    vDriverVersion%  = peekint(mxlbank,132)
    szPname$         = peekstr(mxlbank,32,136)

    print
    print "    "+szName$ +"   Connections "+ cConnections% + "   Controls "+ cControls% +  "   Channels "+ cChannels% +    "   LineID "+ dwLineID%
  End if
Next

print
print "  LINE ID's"

out=writefile("lineIDs.txt")
For Index = -65536 To 655350
  pokeint(mxlbank,12,Index)          ;LineID index
  pokeint(mxlbank,8,0)                   ;This must be set to zero  when calling mixerGetLineInfo
  rc=mixerGetLineInfo(hMixer, mxlbank, MIXER_GETLINEINFOF_LINEID)

  if rc = 0 then
    dwDestination%   = peekint(mxlbank,4);   zero based destination index
    dwSource%        = peekint(mxlbank,8);   zero based source index (if source)
    dwLineID%        = peekint(mxlbank,12);  unique line id for mixer device
    fdwLine%         = peekint(mxlbank,16);  state/information about line
    dwUser%          = peekint(mxlbank,20);  driver specific information
    cChannels%       = peekint(mxlbank,28);  number of channels line supports
    cConnections%    = peekint(mxlbank,32);  number of connections (possible)
    cControls%       = peekint(mxlbank,36);  number of controls at this line
    szShortName$     = peekstr(mxlbank,16,40)
    szName$          = peekstr(mxlbank,64,56)
    dwType%          = peekint(mxlbank, 120)
    dwDeviceID%      = peekint(mxlbank,124)
    wMid%            = peekint(mxlbank,128)
    wPid%            = peekint(mxlbank,130)
    vDriverVersion%  = peekint(mxlbank,132)
    szPname$         = peekstr(mxlbank,32,136)

    print
    print "    "+szName$ +    "   LineID "+ dwLineID%     +    "    Type "+ dwType% + "    Connections "+ cConnections% + "  Controls "+ cControls%  +   "  Channels "+ cChannels%  +   " Source "+dwSource%
    writeline out,"data "+dwLineID% + ","+ chr(34) + szName$ + chr(34)

    if cControls > 0 then
      outsize = 148*cControls
      resizebank mxcbank,outsize
      pokeint(mxlcbank,0, banksize(mxlcbank))
      pokeint(mxlcbank,4,dwLineID)
      pokeint(mxlcbank,8,0)
      pokeint(mxlcbank,12,ccontrols)
      pokeint(mxlcbank,16,148)
      mem = GlobalAlloc($40, outsize)
      pokeint(mxlcbank,20,mem)

      pokeint(mxcbank,0, banksize(mxcbank))
      pokeint(mxcbank,4, 0)
      pokeint(mxcbank,8, 0)
      pokeint(mxcbank,12,0)


    ; Get the control
      rc = mixerGetLineControls(hmixer, mxlcbank, MIXER_GETLINECONTROLSF_ALL)
   ;    stop
 ;     printbank mxlcbank
      If (  MMSYSERR_NOERROR= rc) Then  ; 11

         ; Copy the control into the destination structure
         CopyStructFromPtr mxcbank, peekint(mxlcbank,20), outsize

         for numctrl = 0 to cControls-1
           cbStruct%      = peekint(mxcbank,numctrl*148+0)  ;  size in Byte of MIXERCONTROL
           dwControlID%   = peekint(mxcbank,numctrl*148+4)  ;  unique control id for mixer device
           dwControlType% = peekint(mxcbank,numctrl*148+8)  ;  MIXERCONTROL_CONTROLTYPE_xxx
           fdwControl%    = peekint(mxcbank,numctrl*148+12) ;  MIXERCONTROL_CONTROLF_xxx
           cMultipleItems%= peekint(mxcbank,numctrl*148+16) ;  if MIXERCONTROL_CONTROLF_MULTIPLE
           szShortName$   = peekstr(mxcbank,numctrl*148+16,20) ;  set short name of control
           szName$        = peekstr(mxcbank,numctrl*148+64,36) ;  long name of control
           lMinimum%      = peekint(mxcbank,numctrl*148+100);  Minimum value
           lMaximum%      = peekint(mxcbank,numctrl*148+104);  Maximum value
           print "          * "+szName$ + " ControlType "+GetControlName$(dwControlType%)
         next
        End If
      End If
      GlobalFree (mem)
    End If

if keyhit(1) end
next

closefile out
print
print "hit any key."
while not getkey()
wend


Code :
Code (blitzbasic) Select
; Windows Audio Mixer Blitz Functions
; audiomixer.bb
; v1  ADAmor ZILTCH 31 July 2003

;---------------------- USERLIBS DECLS NEEDED
;  .lib "Kernel32.dll"
;  CopyStructFromPtr(struct*,ptr%,cb%):"RtlMoveMemory"
;  CopyPtrFromStruct(ptr%, struct*, cb%):"RtlMoveMemory"
;  GlobalAlloc%(wFlags%, dwBytes%)
;  GlobalLock%(hmem%)
;  GlobalFree%(hmem%)

;----------------------
;  .lib "winmm.dll"
;  mixerOpen%(phmx%, uMxId%, dwCallback%, dwInstance%, fdwOpen%)
;  mixerClose%(hmx%)

;  mixerGetControlDetails%(hmxobj%, pmxcd*, fdwDetails%):"mixerGetControlDetailsA"
;  mixerGetDevCaps%(uMxId%, pmxcaps*, cbmxcaps%): "mixerGetDevCapsA"
;  mixerGetID%(hmxobj%, pumxID%, fdwId%)
;  mixerGetLineControls%(hmxobj%, pmxlc*, fdwControls%): "mixerGetLineControlsA"
;  mixerGetLineInfo%(hmxobj%, pmxl*, fdwInfo%):"mixerGetLineInfoA"
;  mixerGetNumDevs%()
;  mixerMessage%(hmx%, uMsg%, dwParam1%, dwParam2%)
;  mixerSetControlDetails%(hmxobj%, pmxcd*, fdwDetails%)
;----------------------
;  .lib "Kernel32.dll"
;  CopyStructFromPtr(struct*,ptr%,cb%):"RtlMoveMemory"
;  CopyPtrFromStruct(ptr%, struct*, cb%):"RtlMoveMemory"
;  GlobalAlloc%(wFlags%, dwBytes%)
;  GlobalLock%(hmem%)
;  GlobalFree%(hmem%)

;----------------------

Const MMSYSERR_NOERROR       = 0
Const MMSYSERR_ERROR         = 1  ; unspecified error
Const MMSYSERR_BADDEVICEID   = 2  ; device ID out of range
Const MMSYSERR_NOTENABLED    = 3  ; driver failed enable
Const MMSYSERR_ALLOCATED     = 4  ; device already allocated
Const MMSYSERR_INVALHANDLE   = 5  ; device handle is invalid
Const MMSYSERR_NODRIVER      = 6  ; no device driver present
Const MMSYSERR_NOMEM         = 7  ; memory allocation error
Const MMSYSERR_NOTSUPPORTED  = 8  ; function isn't supported
Const MMSYSERR_BADERRNUM     = 9  ; error value out of range
Const MMSYSERR_INVALFLAG     = 10 ; invalid flag passed
Const MMSYSERR_INVALPARAM    = 11 ; invalid parameter passed
Const MMSYSERR_HANDLEBUSY    = 12 ; handle being used

Const MAXPNAMELEN            = 32
Const MIXER_LONG_NAME_CHARS  = 64
Const MIXER_SHORT_NAME_CHARS = 16

Const MIXER_GETLINEINFOF_DESTINATION       = $00000000
Const MIXER_GETLINEINFOF_SOURCE            = $00000001
Const MIXER_GETLINEINFOF_LINEID            = $00000002
Const MIXER_GETLINEINFOF_COMPONENTTYPE     = $00000003
Const MIXER_GETLINEINFOF_TARGETTYPE        = $00000004

Const MIXER_GETCONTROLDETAILSF_VALUE       = $0

Const MIXER_GETLINECONTROLSF_ALL           = $0
Const MIXER_GETLINECONTROLSF_ONEBYID       = $1
Const MIXER_GETLINECONTROLSF_ONEBYTYPE     = $2

;--  MIXERCONTROL.fdwControl

Const MIXERCONTROL_CONTROLF_UNIFORM        = $00000001
Const MIXERCONTROL_CONTROLF_MULTIPLE       = $00000002
Const MIXERCONTROL_CONTROLF_DISABLED       = $80000000



;--  MIXERCONTROL_CONTROLTYPE_xxx building block defines


Const MIXERCONTROL_CT_CLASS_MASK           = $F0000000
Const MIXERCONTROL_CT_CLASS_CUSTOM         = $00000000
Const MIXERCONTROL_CT_CLASS_METER          = $10000000
Const MIXERCONTROL_CT_CLASS_SWITCH         = $20000000
Const MIXERCONTROL_CT_CLASS_NUMBER         = $30000000
Const MIXERCONTROL_CT_CLASS_SLIDER         = $40000000
Const MIXERCONTROL_CT_CLASS_FADER          = $50000000
Const MIXERCONTROL_CT_CLASS_TIME           = $60000000
Const MIXERCONTROL_CT_CLASS_LIST           = $70000000


Const MIXERCONTROL_CT_SUBCLASS_MASK        = $0F000000

Const MIXERCONTROL_CT_SC_SWITCH_BOOLEAN    = $00000000
Const MIXERCONTROL_CT_SC_SWITCH_BUTTON     = $01000000

Const MIXERCONTROL_CT_SC_METER_POLLED      = $00000000

Const MIXERCONTROL_CT_SC_TIME_MICROSECS    = $00000000
Const MIXERCONTROL_CT_SC_TIME_MILLISECS    = $01000000

Const MIXERCONTROL_CT_SC_LIST_SINGLE       = $00000000
Const MIXERCONTROL_CT_SC_LIST_MULTIPLE     = $01000000


Const MIXERCONTROL_CT_UNITS_MASK           = $00FF0000
Const MIXERCONTROL_CT_UNITS_CUSTOM         = $00000000
Const MIXERCONTROL_CT_UNITS_BOOLEAN        = $00010000
Const MIXERCONTROL_CT_UNITS_SIGNED         = $00020000
Const MIXERCONTROL_CT_UNITS_UNSIGNED       = $00030000
Const MIXERCONTROL_CT_UNITS_DECIBELS       = $00040000 ;in 10ths
Const MIXERCONTROL_CT_UNITS_PERCENT        = $00050000 ;in 10ths



;--  Commonly used control types for specifying MIXERCONTROL.dwControlType


Const MIXERCONTROL_CONTROLTYPE_CUSTOM        = (MIXERCONTROL_CT_CLASS_CUSTOM Or MIXERCONTROL_CT_UNITS_CUSTOM)
Const MIXERCONTROL_CONTROLTYPE_BOOLEANMETER  = (MIXERCONTROL_CT_CLASS_METER Or MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Const MIXERCONTROL_CONTROLTYPE_SIGNEDMETER   = (MIXERCONTROL_CT_CLASS_METER Or MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_SIGNED)
Const MIXERCONTROL_CONTROLTYPE_PEAKMETER     = (MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1)
Const MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER = (MIXERCONTROL_CT_CLASS_METER Or MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Const MIXERCONTROL_CONTROLTYPE_BOOLEAN       = (MIXERCONTROL_CT_CLASS_SWITCH Or MIXERCONTROL_CT_SC_SWITCH_BOOLEAN Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Const MIXERCONTROL_CONTROLTYPE_ONOFF         = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1)
Const MIXERCONTROL_CONTROLTYPE_MUTE          = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2)
Const MIXERCONTROL_CONTROLTYPE_MONO          = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3)
Const MIXERCONTROL_CONTROLTYPE_LOUDNESS      = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4)
Const MIXERCONTROL_CONTROLTYPE_STEREOENH     = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5)
Const MIXERCONTROL_CONTROLTYPE_BASS_BOOST    = (MIXERCONTROL_CONTROLTYPE_BOOLEAN + $00002277)
Const MIXERCONTROL_CONTROLTYPE_BUTTON        = (MIXERCONTROL_CT_CLASS_SWITCH Or MIXERCONTROL_CT_SC_SWITCH_BUTTON Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Const MIXERCONTROL_CONTROLTYPE_DECIBELS      = (MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_DECIBELS)
Const MIXERCONTROL_CONTROLTYPE_SIGNED        = (MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_SIGNED)
Const MIXERCONTROL_CONTROLTYPE_UNSIGNED      = (MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Const MIXERCONTROL_CONTROLTYPE_PERCENT       = (MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_PERCENT)
Const MIXERCONTROL_CONTROLTYPE_SLIDER        = (MIXERCONTROL_CT_CLASS_SLIDER Or MIXERCONTROL_CT_UNITS_SIGNED)
Const MIXERCONTROL_CONTROLTYPE_PAN           = (MIXERCONTROL_CONTROLTYPE_SLIDER + 1)
Const MIXERCONTROL_CONTROLTYPE_QSOUNDPAN     = (MIXERCONTROL_CONTROLTYPE_SLIDER + 2)
Const MIXERCONTROL_CONTROLTYPE_FADER         = (MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Const MIXERCONTROL_CONTROLTYPE_VOLUME        = (MIXERCONTROL_CONTROLTYPE_FADER + 1)
Const MIXERCONTROL_CONTROLTYPE_BASS          = (MIXERCONTROL_CONTROLTYPE_FADER + 2)
Const MIXERCONTROL_CONTROLTYPE_TREBLE        = (MIXERCONTROL_CONTROLTYPE_FADER + 3)
Const MIXERCONTROL_CONTROLTYPE_EQUALIZER     = (MIXERCONTROL_CONTROLTYPE_FADER + 4)
Const MIXERCONTROL_CONTROLTYPE_SINGLESELECT  = (MIXERCONTROL_CT_CLASS_LIST Or MIXERCONTROL_CT_SC_LIST_SINGLE Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Const MIXERCONTROL_CONTROLTYPE_MUX           = (MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1)
Const MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT= (MIXERCONTROL_CT_CLASS_LIST Or MIXERCONTROL_CT_SC_LIST_MULTIPLE Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Const MIXERCONTROL_CONTROLTYPE_MIXER         = (MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1)
Const MIXERCONTROL_CONTROLTYPE_MICROTIME     = (MIXERCONTROL_CT_CLASS_TIME Or MIXERCONTROL_CT_SC_TIME_MICROSECS Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Const MIXERCONTROL_CONTROLTYPE_MILLITIME     = (MIXERCONTROL_CT_CLASS_TIME Or MIXERCONTROL_CT_SC_TIME_MILLISECS Or MIXERCONTROL_CT_UNITS_UNSIGNED)

.CONTROLTYPES
Data "MIXERCONTROL_CONTROLTYPE_CUSTOM       ",(MIXERCONTROL_CT_CLASS_CUSTOM Or MIXERCONTROL_CT_UNITS_CUSTOM)
Data "MIXERCONTROL_CONTROLTYPE_BOOLEANMETER ",(MIXERCONTROL_CT_CLASS_METER Or MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Data "MIXERCONTROL_CONTROLTYPE_SIGNEDMETER  ",(MIXERCONTROL_CT_CLASS_METER Or MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_SIGNED)
Data "MIXERCONTROL_CONTROLTYPE_PEAKMETER    ",(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1)
Data "MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER",(MIXERCONTROL_CT_CLASS_METER Or MIXERCONTROL_CT_SC_METER_POLLED Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Data "MIXERCONTROL_CONTROLTYPE_BOOLEAN      ",(MIXERCONTROL_CT_CLASS_SWITCH Or MIXERCONTROL_CT_SC_SWITCH_BOOLEAN Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Data "MIXERCONTROL_CONTROLTYPE_ONOFF        ",(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1)
Data "MIXERCONTROL_CONTROLTYPE_MUTE         ",(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2)
Data "MIXERCONTROL_CONTROLTYPE_MONO         ",(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3)
Data "MIXERCONTROL_CONTROLTYPE_LOUDNESS     ",(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4)
Data "MIXERCONTROL_CONTROLTYPE_STEREOENH    ",(MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5)
Data "MIXERCONTROL_CONTROLTYPE_BASS_BOOST   ",(MIXERCONTROL_CONTROLTYPE_BOOLEAN + $00002277)
Data "MIXERCONTROL_CONTROLTYPE_BUTTON       ",(MIXERCONTROL_CT_CLASS_SWITCH Or MIXERCONTROL_CT_SC_SWITCH_BUTTON Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Data "MIXERCONTROL_CONTROLTYPE_DECIBELS     ",(MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_DECIBELS)
Data "MIXERCONTROL_CONTROLTYPE_SIGNED       ",(MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_SIGNED)
Data "MIXERCONTROL_CONTROLTYPE_UNSIGNED     ",(MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Data "MIXERCONTROL_CONTROLTYPE_PERCENT      ",(MIXERCONTROL_CT_CLASS_NUMBER Or MIXERCONTROL_CT_UNITS_PERCENT)
Data "MIXERCONTROL_CONTROLTYPE_SLIDER       ",(MIXERCONTROL_CT_CLASS_SLIDER Or MIXERCONTROL_CT_UNITS_SIGNED)
Data "MIXERCONTROL_CONTROLTYPE_PAN          ",(MIXERCONTROL_CONTROLTYPE_SLIDER + 1)
Data "MIXERCONTROL_CONTROLTYPE_QSOUNDPAN    ",(MIXERCONTROL_CONTROLTYPE_SLIDER + 2)
Data "MIXERCONTROL_CONTROLTYPE_FADER        ",(MIXERCONTROL_CT_CLASS_FADER Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Data "MIXERCONTROL_CONTROLTYPE_VOLUME       ",(MIXERCONTROL_CONTROLTYPE_FADER + 1)
Data "MIXERCONTROL_CONTROLTYPE_BASS         ",(MIXERCONTROL_CONTROLTYPE_FADER + 2)
Data "MIXERCONTROL_CONTROLTYPE_TREBLE       ",(MIXERCONTROL_CONTROLTYPE_FADER + 3)
Data "MIXERCONTROL_CONTROLTYPE_EQUALIZER    ",(MIXERCONTROL_CONTROLTYPE_FADER + 4)
Data "MIXERCONTROL_CONTROLTYPE_SINGLESELECT ",(MIXERCONTROL_CT_CLASS_LIST Or MIXERCONTROL_CT_SC_LIST_SINGLE Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Data "MIXERCONTROL_CONTROLTYPE_MUX          ",(MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1)
Data "MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT", (MIXERCONTROL_CT_CLASS_LIST Or MIXERCONTROL_CT_SC_LIST_MULTIPLE Or MIXERCONTROL_CT_UNITS_BOOLEAN)
Data "MIXERCONTROL_CONTROLTYPE_MIXER        ",(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1)
Data "MIXERCONTROL_CONTROLTYPE_MICROTIME    ",(MIXERCONTROL_CT_CLASS_TIME Or MIXERCONTROL_CT_SC_TIME_MICROSECS Or MIXERCONTROL_CT_UNITS_UNSIGNED)
Data "MIXERCONTROL_CONTROLTYPE_MILLITIME    ",(MIXERCONTROL_CT_CLASS_TIME Or MIXERCONTROL_CT_SC_TIME_MILLISECS Or MIXERCONTROL_CT_UNITS_UNSIGNED)

Restore CONTROLTYPES
Dim CONTROLTYPES_Name$(31)
Dim CONTROLTYPES_Val$(31)
For count = 1 To 31
  Read CONTROLTYPES_Name$(count),CONTROLTYPES_Val$(count)
Next

; -- Component types for mixer destinations and sources

Const MIXERLINE_COMPONENTTYPE_DST_FIRST = $0
Const MIXERLINE_COMPONENTTYPE_DST_UNDEFINED   = MIXERLINE_COMPONENTTYPE_DST_FIRST + 0
Const MIXERLINE_COMPONENTTYPE_DST_DIGITAL     = MIXERLINE_COMPONENTTYPE_DST_FIRST + 1
Const MIXERLINE_COMPONENTTYPE_DST_LINE        = MIXERLINE_COMPONENTTYPE_DST_FIRST + 2
Const MIXERLINE_COMPONENTTYPE_DST_MONITOR     = MIXERLINE_COMPONENTTYPE_DST_FIRST + 3
Const MIXERLINE_COMPONENTTYPE_DST_SPEAKERS    = MIXERLINE_COMPONENTTYPE_DST_FIRST + 4
Const MIXERLINE_COMPONENTTYPE_DST_HEADPHONES  = MIXERLINE_COMPONENTTYPE_DST_FIRST + 5
Const MIXERLINE_COMPONENTTYPE_DST_TELEPHONE   = MIXERLINE_COMPONENTTYPE_DST_FIRST + 6
Const MIXERLINE_COMPONENTTYPE_DST_WAVEIN      = MIXERLINE_COMPONENTTYPE_DST_FIRST + 7
Const MIXERLINE_COMPONENTTYPE_DST_VOICEIN     = MIXERLINE_COMPONENTTYPE_DST_FIRST + 8
Const MIXERLINE_COMPONENTTYPE_DST_LAST        = MIXERLINE_COMPONENTTYPE_DST_FIRST + 8

Const MIXERLINE_COMPONENTTYPE_SRC_FIRST = $1000
Const MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED   = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 0
Const MIXERLINE_COMPONENTTYPE_SRC_DIGITAL     = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 1
Const MIXERLINE_COMPONENTTYPE_SRC_LINE        = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2
Const MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE  = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3
Const MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 4
Const MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 5
Const MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE   = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 6
Const MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER   = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 7
Const MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT     = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 8
Const MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY   = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 9
Const MIXERLINE_COMPONENTTYPE_SRC_ANALOG      = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10
Const MIXERLINE_COMPONENTTYPE_SRC_LAST        = MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10


; --  MIXERLINE.Target.dwType

Const MIXERLINE_TARGETTYPE_UNDEFINED    = 0
Const MIXERLINE_TARGETTYPE_WAVEOUT      = 1
Const MIXERLINE_TARGETTYPE_WAVEIN       = 2
Const MIXERLINE_TARGETTYPE_MIDIOUT      = 3
Const MIXERLINE_TARGETTYPE_MIDIIN       = 4
Const MIXERLINE_TARGETTYPE_AUX          = 5

Type MIXERCAPS
  Field wMid%                             ;0   manufacturer id
  Field wPid%                             ;4   product id
  Field vDriverVersion%                   ;8   version of the driver
  Field szPname$                          ;12  product name
  Field fdwSupport%                       ;44  misc. support bits
  Field cDestinations%                    ;48  count of destinations
End Type                                  ;Size 52

Type MIXERCONTROL
  Field cbStruct%                  ;0    size in Byte of MIXERCONTROL
  Field dwControlID%               ;4    unique control id for mixer device
  Field dwControlType%             ;8    MIXERCONTROL_CONTROLTYPE_xxx
  Field fdwControl%                ;12   MIXERCONTROL_CONTROLF_xxx
  Field cMultipleItems%            ;16   if MIXERCONTROL_CONTROLF_MULTIPLE
  Field szShortName$               ;20   short name of control
  Field szName$                    ;36   long name of control
  Field lMinimum%                  ;100  Minimum value
  Field lMaximum%                  ;104  Maximum value
;  field reserved()%               ;108  reserved structure space
End Type                           ;size 148

Type MIXERCONTROLDETAILS
  Field cbStruct%              ;0   size in Byte of MIXERCONTROLDETAILS
  Field dwControlID%           ;4   control id to get/set details on
  Field cChannels%             ;8   number of channels in paDetails array
  Field item%                  ;12  hwndOwner or cMultipleItems
  Field cbDetails%             ;16  size of _one_ details_XX struct
  Field paDetails%             ;20  pointer to array of details_XX structs
End Type                       ;size 24

Type MIXERCONTROLDETAILS_UNSIGNED
  Field dwValue%               ;0  value of the control
End Type                       ;size 4

Type MIXERLINE
  Field cbStruct%                      ;0   size of MIXERLINE structure
  Field dwDestination%                 ;4   zero based destination index
  Field dwSource%                      ;8   zero based source index (if source)
  Field dwLineID%                      ;12  unique line id for mixer device
  Field fdwLine%                       ;16  state/information about line
  Field dwUser%                        ;20  driver specific information
  Field dwComponentType%               ;24  component type line connects to
  Field cChannels%                     ;28  number of channels line supports
  Field cConnections%                  ;32  number of connections (possible)
  Field cControls%                     ;36  number of controls at this line
  Field szShortName$                   ;40
  Field szName$                        ;56
  Field dwType%                        ;120
  Field dwDeviceID%                    ;124
  Field wMid%                          ;128
  Field wPid%                          ;130
  Field vDriverVersion%                ;132
  Field szPname$                       ;136
End Type                               ;size 168

Type MIXERLINECONTROLS
  Field cbStruct%              ;0   size in Byte of MIXERLINECONTROLS
  Field dwLineID%              ;4   line id (from MIXERLINE.dwLineID)
                               ;    MIXER_GETLINECONTROLSF_ONEBYID or
  Field dwControl%             ;8   MIXER_GETLINECONTROLSF_ONEBYTYPE
  Field cControls%             ;12  count of controls pmxctrl points to
  Field cbmxctrl%              ;16  size in Byte of _one_ MIXERCONTROL
  Field pamxctrl%              ;20  pointer to first MIXERCONTROL array
End Type                       ;size 24

Type MIXERCONTROLDETAILS_LISTTEXT
  Field  dwParam1             ;0
  Field  dwParam2             ;4
  Field  szname$              ;8
End Type                      ;len 72



Function GetControlName$(ControlNum)

  Local count

  For count = 1 To 31
     If controlnum = CONTROLTYPES_Val$(count) Then
      Return CONTROLTYPES_Name$(count)
    End If
  Next
  Return "Control type unkown " + Controlnum
End Function


Function GetMixerControl(hmixer%, componentType%, ctrlType%, mxc.MIXERCONTROL,mode=0)

; This function attempts to obtain a mixer control.
; Returns True if successful.
;mode 1 uses lineID instead of control type

   Local mxlc.MIXERLINECONTROLS = New MIXERLINECONTROLS
   Local mxl.MIXERLINE = New MIXERLINE
   Local hmem%
   Local rc%
   Local mxlcbank = CreateBank(24)
   Local mxlbank  = CreateBank(168)

   mxlcbStruct = BankSize(mxlbank)
   mxldwComponentType = componentType

   PokeInt(mxlbank,0,BankSize(mxlbank))

   Select mode
     Case 0; Obtain a line corresponding to the component type
       PokeInt(mxlbank,24,componentType)
       rc = mixerGetLineInfo(hmixer, mxlbank, MIXER_GETLINEINFOF_COMPONENTTYPE)
     Case 1; Obtain a line from its lineID
       PokeInt(mxlbank,8,0)
       PokeInt(mxlbank,12,componentType)
       rc=mixerGetLineInfo(hMixer, mxlbank, MIXER_GETLINEINFOF_LINEID)
   End Select

   If (MMSYSERR_NOERROR <> rc) Then
     DebugLog "error "+rc+" mixer get line info failed. For lineID/componentType of "+componentType
   Else
     mxldwDestination%   = PeekInt(mxlbank,4);   zero based destination index
     mxldwSource%        = PeekInt(mxlbank,8);   zero based source index (if source)
     mxldwLineID%        = PeekInt(mxlbank,12);  unique line id for mixer device
     mxlfdwLine%         = PeekInt(mxlbank,16);  state/information about line
     mxldwUser%          = PeekInt(mxlbank,20);  driver specific information
     mxlcChannels%       = PeekInt(mxlbank,28);  number of channels line supports
     mxlcConnections%    = PeekInt(mxlbank,32);  number of connections (possible)
     mxlcControls%       = PeekInt(mxlbank,36);  number of controls at this line
     mxlszShortName$     = peekstr(mxlbank,16,40)
     mxlszName$          = peekstr(mxlbank,64,56)
     mxldwType%          = PeekInt(mxlbank, 120)
     mxldwDeviceID%      = PeekInt(mxlbank,124)
     mxlwMid%            = PeekInt(mxlbank,128)
     mxlwPid%            = PeekInt(mxlbank,130)
     mxlvDriverVersion%  = PeekInt(mxlbank,132)
     mxlszPname$         = peekstr(mxlbank,32,136)

     mxlccbStruct = BankSize(mxlcbank);24
     mxlcdwLineID = mxldwLineID
     mxlcdwControl = ctrlType
     mxlccControls = 1
     PokeInt(mxlcbank,0, BankSize(mxlcbank));24
     PokeInt(mxlcbank,4,mxldwLineID)
     PokeInt(mxlcbank,8,ctrlType)
     PokeInt(mxlcbank,12,1)

     outsize=148
     ; Allocate a buffer for the control
     hmem = GlobalAlloc($40, outsize)  ;$40
     mxlcpamxctrl = GlobalLock(hmem)
     mxlccbmxctrl = outsize
     PokeInt(mxlcbank,16,outsize)
     PokeInt(mxlcbank,20,mxlcpamxctrl)

     mxccbStruct = outsize
     mxcbank = CreateBank(outsize)
     PokeInt(mxcbank,0,mxccbStruct)

     ; Get the control
     rc = mixerGetLineControls(hmixer, mxlcbank, MIXER_GETLINECONTROLSF_ONEBYTYPE)
;     debuglog componentType%+" " +mxlszShortName$
     GetMixerControl = False

     If (  MMSYSERR_NOERROR= rc) Then
         GetMixerControl = True
         ; Copy the control into the destination structure

         CopyStructFromPtr mxcbank, mxlcpamxctrl, outsize

         mxccbStruct%      = PeekInt(mxcbank,0)  ;  size in Byte of MIXERCONTROL
         mxcdwControlID%   = PeekInt(mxcbank,4)  ;  unique control id for mixer device
         mxcdwControlType% = PeekInt(mxcbank,8)  ;  MIXERCONTROL_CONTROLTYPE_xxx
         mxcfdwControl%    = PeekInt(mxcbank,12) ;  MIXERCONTROL_CONTROLF_xxx
         mxccMultipleItems%= PeekInt(mxcbank,16) ;  if MIXERCONTROL_CONTROLF_MULTIPLE
         mxcszShortName$   = peekstr(mxcbank,16,20) ;  set short name of control
         mxcszName$        = peekstr(mxcbank,64,36) ;  long name of control
         mxclMinimum%      = PeekInt(mxcbank,100);  Minimum value
         mxclMaximum%      = PeekInt(mxcbank,104);  Maximum value
     End If

     GlobalFree (hmem)
     FreeBank mxcbank

   End If

   FreeBank mxlcbank
   FreeBank mxcbank
   FreeBank mxlbank
   Return GetMixerControl
End Function

Function SetVolumeControl(hmixer% , mxc.MIXERCONTROL, volume% )
; This function sets the value for a volume control.
; Returns True if successful

   Local mxcd.MIXERCONTROLDETAILS = New MIXERCONTROLDETAILS
   Local vol.MIXERCONTROLDETAILS_UNSIGNED = New MIXERCONTROLDETAILS_UNSIGNED
   Local mxcdbank   = CreateBank(24)
   Local volbank    = CreateBank(4)
   Local mem,rc

   mxcdcbStruct    = BankSize(mxcdbank)
   mxcdcbDetails   = 4
   mxcditem        = 0
   mxcddwControlID = mxcdwControlID

   PokeInt(mxcdbank,0, BankSize(mxcdbank));24
   PokeInt(mxcdbank,4, mxcdwControlID)
   PokeInt(mxcdbank,8, 1)
   PokeInt(mxcdbank,12,0)
   PokeInt(mxcdbank,16,BankSize(volbank) )

   ; Allocate a buffer for the control value buffer
   mem = GlobalAlloc($40, 4)
   mxcdpaDetails = GlobalLock(mem)
   mxcdcChannels = 1

   PokeInt(mxcdbank,20,mxcdpaDetails )
;   debuglog "max "+mxclMaximum%
   If volume < mxclMinimum% Then volume = mxclMinimum%
   voldwValue%  = volume Mod mxclMaximum%
   PokeInt volbank,0,volume

   ; Copy the data into the control value buffer
   CopyPtrFromStruct mxcdpaDetails, vol, BankSize(volbank)

   ; Set the control value
   rc = mixerSetControlDetails(hmixer, mxcdbank, MIXER_SETCONTROLDETAILSF_VALUE)

   GlobalFree (mem)

   FreeBank mxcdbank
   FreeBank volbank
   If (MMSYSERR_NOERROR = rc) Then
       SetVolumeControl = True
   Else
       SetVolumeControl = False
   End If

   Return SetVolumeControl

End Function



Function GetVolumeControlLevel(hmixer% , mxc.MIXERCONTROL)
; This function sets the value for a volume control.
; Returns True if successful

   Local mxcd.MIXERCONTROLDETAILS = New MIXERCONTROLDETAILS
   Local vol.MIXERCONTROLDETAILS_UNSIGNED = New MIXERCONTROLDETAILS_UNSIGNED
   Local mxcdbank   = CreateBank(24)
   Local volbank    = CreateBank(4)
   Local mem,rc

   mxcdcbStruct    = BankSize(mxcdbank)
   mxcdcbDetails   = 4
   mxcditem        = mxccMultipleItems
   mxcddwControlID = mxcdwControlID

   PokeInt(mxcdbank,0, BankSize(mxcdbank));24
   PokeInt(mxcdbank,4, mxcdwControlID)
   PokeInt(mxcdbank,8, 1)
   PokeInt(mxcdbank,12,mxccMultipleItems)
   PokeInt(mxcdbank,16,BankSize(volbank) )

   ; Allocate a buffer for the control value buffer
   mem = GlobalAlloc($40, 4)
   mxcdpaDetails = GlobalLock(mem)
   mxcdcChannels = 1

   PokeInt(mxcdbank,20,mxcdpaDetails )

  ; Set the control value
   rc = mixerGetControlDetails(hmixer, mxcdbank, MIXER_GETCONTROLDETAILSF_VALUE)

   If rc <> 0 Then
     DebugLog "error "+rc+" can not get control"
   End If

   CopyStructFromPtr volbank, mxcdpaDetails, 4
   OUTvolume = PeekInt(volbank,0)
   If (OUTvolume < 0) Then OUTvolume = -OUTvolume

   GlobalFree (mem)

   FreeBank mxcdbank
   FreeBank volbank
   If (MMSYSERR_NOERROR = rc) Then
       SetVolumeControl = True
   Else
       SetVolumeControl = False
       OUTvolume = -1
   End If

   Return OUTVolume

End Function



Function SetVolume$(Control=4,NewVolume,mode=0)
;returns name of Control if OK

;mode 1 uses lineID instead of control type

  Local ok, hmixer = 0
  volCtrl.mixercontrol = New mixercontrol ;

  ok = GetMixerControl(hmixer, Control, MIXERCONTROL_CONTROLTYPE_VOLUME, volCtrl.mixercontrol,mode)

  If ok Then ok = SetVolumeControl(hmixer, volCtrl, NewVolume)
  If ok Then
    ShortName$ = volCtrlszShortName$
    Delete volctrl
    Return ShortName$
  End If
End Function



Function GetVolume$(Control=4)
;returns name of Control if OK

  Local ok, hmixer = 0
  volCtrl.mixercontrol = New mixercontrol

  ok = GetMixerControl(hmixer, Control,MIXERCONTROL_CONTROLTYPE_VOLUME , volCtrl.mixercontrol)

  If ok Then
    OUTVolume = GetVolumeControlLevel(hmixer, volCtrl)
  Else
    OUTVolume = - 1
  End If

  Delete volctrl
  Return OUTVolume

End Function


;-- bank funcions

Function PeekStr$(Tbank,Size=64,Offset=0)
;note offset is 3rd param not 2nd like peekint, etc.

  Local count,newchr
  Local NewStr$ = ""
  Local bsize = BankSize(tbank)
  Local lastbyte = (offset+size-1)

  If lastbyte > bsize Then lastbyte = bsize

  For count = offset To lastbyte
    newchr = PeekByte(Tbank,count)

    If (newchr = 0) Then  Exit

    newstr$ = newstr$ + Chr$(newchr)
  Next
  Return Newstr$

End Function


Comments : none...