Advertisement
Ham62

VolumeLockerGUI.bas

Dec 14th, 2017
788
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define fbc -s gui res\VolLocker.rc
  2. #include "windows.bi"
  3. #include "win\commctrl.bi"
  4. #include "win\mmsystem.bi"
  5. #include "crt.bi"
  6.  
  7. #define ShowDebug 0
  8. type SimpleDevIDs
  9.     szName as zString * MAXPNAMELEN
  10. end type
  11. Declare Sub WinMain(hInstance as HINSTANCE, hPrevInstance as HINSTANCE, szCmdLine as PSTR, iCmdShow as Integer)
  12.  
  13. enum WindowControls
  14.     wcMain
  15.    
  16.     wcInptGrpBox    ' Line Selector group box
  17.     wcInptSlctLbl   ' Line selector label
  18.     wcInptSlct      ' Line Selector to control
  19.    
  20.     wcLockEnable    ' Enable/disable universal lock switch
  21.    
  22.     wcVolumeLbl
  23.     wcVolLevelLbl   ' Show volume level
  24.     wcVolumeSlider  ' Volume slider
  25.    
  26.     wcMuteLockEnable 'Enable/disable mute lock switch
  27.    
  28.     wcMuteLockCtrl  ' Controls if mute is forced on/off
  29.    
  30.     wcVersionLbl    'Version label
  31.    
  32.     wcLast
  33. end enum
  34.  
  35. Const WINDOW_WIDTH = 400, WINDOW_HEIGHT = 265
  36. dim shared as hwnd CTL(wcLast)   'Control handles
  37. Dim Shared as HINSTANCE hInstance
  38. Dim Shared as HFONT hFont
  39. Dim Shared as HFONT hSmallFont
  40. Dim Shared as String szAppName
  41. Dim Shared as String szCaption
  42.  
  43. '**** mmsys stuff ****
  44. Declare Sub OpenMixer()
  45. Declare Sub CloseMixer()
  46. Declare Sub SetVolume(dwVolumeLevel as DWORD)
  47. Declare Sub SetMuteState(dwMuteState as DWORD)
  48. Declare Sub EnumInputDevices()
  49. Declare Sub EnableLock(iEnable as integer)
  50. Declare Sub EnableMuteLock(iEnable as integer)
  51. Dim shared as HWAVEIN   WaveInHandle 'Handle for wave in device
  52. Dim shared as HMIXER    MixerHandle  'Handle of mixer for wave in device
  53. Dim shared as MIXERLINE mixerLine    'Mixer line info
  54.  
  55. 'State if line has mute and volume control
  56. Dim shared as Integer HasMuteControl   = -1
  57. Dim shared as Integer HasVolumeControl = -1
  58. 'Lock states
  59. Dim Shared as Integer LockEnabled      = 1
  60. Dim Shared as Integer MuteLockEnabled  = 0
  61.  
  62. Dim shared as uInteger SelectedDevice  = 0 ' 0 is default device
  63. Dim Shared as Integer iVolume
  64.  
  65. 'Make a list of all avalible input devices
  66. Dim shared as uInteger TotalDevs
  67. TotalDevs = waveInGetNumDevs()       'Get number of input devices
  68. Dim shared as SimpleDevIDs DevIDs(TotalDevs-1) 'Create array to store device IDs
  69. EnumInputDevices() 'Store device names in array
  70.  
  71.  
  72. hInstance = GetModuleHandle(NULL)
  73. szAppName = "Volume Locker"
  74. szCaption = "Volume Locker Settings"
  75.  
  76. 'Launch into WinMain()
  77. WinMain(hInstance, NULL, Command, SW_NORMAL)
  78.  
  79. Function WndProc (hWnd as HWND, iMsg as uInteger, wParam as WPARAM, lParam as LPARAM) as LRESULT
  80.     Select Case iMsg
  81.     Case WM_CREATE
  82.        
  83.         '**** Center window on desktop ****'
  84.         Scope   'Calculate Client Area Size
  85.             Dim as rect RcWnd = any, RcCli = Any, RcDesk = any
  86.             GetClientRect(hWnd, @RcCli)
  87.             GetClientRect(GetDesktopWindow(), @RcDesk)
  88.             GetWindowRect(hWnd, @RcWnd)
  89.             'Window Rect is in SCREEN coordinate.... make right/bottom become WID/HEI
  90.             with RcWnd
  91.                 .right -= .left: .bottom -= .top
  92.                 .right += (.right-RcCli.right)  'Add difference cli/wnd
  93.                 .bottom += (.bottom-RcCli.bottom)   'add difference cli/wnd
  94.                 var CenterX = (RcDesk.right-.right)\2
  95.                 var CenterY = (RcDesk.bottom-.bottom)\2
  96.                 SetWindowPos(hwnd,null,CenterX,CenterY,.right,.bottom,SWP_NOZORDER)
  97.             end with
  98.         end Scope        
  99.  
  100.         '**** Create default font ****'
  101.         var hDC = GetDC(hWnd) 'can be used for other stuff that requires a temporary DC
  102.         var nHeight = -MulDiv(10, GetDeviceCaps(hDC, LOGPIXELSY), 72) 'calculate size matching DPI
  103.         var nSmallHeight = -MulDiv(8, GetDeviceCaps(hDC, LOGPIXELSY), 72) 'calculate size matching DPI
  104.        
  105.         hFont = CreateFont(nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, _
  106.                            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, _
  107.                            DEFAULT_PITCH, "Verdana")
  108.  
  109.         hSmallFont = CreateFont(nSmallHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, _
  110.                                 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, _
  111.                                 DEFAULT_PITCH, "Verdana")
  112.        
  113.         ' Macro for creating window controls
  114.         #define CreateControl(mID , mExStyle , mClass , mCaption , mStyle , mX , mY , mWid , mHei) CTL(mID) = CreateWindowEx(mExStyle,mClass,mCaption,mStyle,mX,mY,mWid,mHei,hwnd,cast(hmenu,mID),hInstance,null)
  115.         const cBase = WS_VISIBLE OR WS_CHILD
  116.         const cDropList = cBase OR CBS_DROPDOWNLIST OR CBS_HASSTRINGS OR CBS_NOINTEGRALHEIGHT OR WS_VSCROLL
  117.         const cGrpBox = cBase OR BS_GROUPBOX
  118.         const cLabelStyle = cBase
  119.         const cTrackBar = cBase OR TBS_TOP' OR TBS_AUTOTICKS OR TBS_ENABLESELRANGE
  120.         const cCheckBox = cBase OR BS_AUTOCHECKBOX OR BS_RIGHTBUTTON
  121.        
  122.         '**** Device Select Section ****'
  123.         CreateControl(wcInptGrpBox, WS_EX_TRANSPARENT, WC_BUTTON, "Selected Input Device", cGrpBox, 5, 5, WINDOW_WIDTH-10, WINDOW_HEIGHT-10)
  124.         CreateControl(wcInptSlctLbl, WS_EX_TRANSPARENT, WC_STATIC, "Device to lock:", cLabelStyle, 20, 29, 100, 20)
  125.         CreateControl(wcInptSlct, NULL, WC_COMBOBOX, "", cDropList, 130, 26, 245, 100)
  126.  
  127.         'Fill drop menu with list of input devices
  128.         For dev as integer = 0 to TotalDevs-1
  129.             SendMessage(ctl(wcInptSlct), CB_ADDSTRING, cast(WPARAM, 0), cast(LPARAM, @DevIDs(dev).szName))
  130.         Next dev
  131.        
  132.         'Select default device
  133.         SendMessage(ctl(wcInptSlct), CB_SETCURSEL, cast(WPARAM, SelectedDevice), cast(LPARAM, 0))
  134.    
  135.  
  136.         '**** Lock Enable/Disable ****'
  137.         CreateControl(wcLockEnable, WS_EX_TRANSPARENT, WC_BUTTON, "Enable Device Lock", cCheckBox, 19, 75, 160, 20)
  138.         SendMessage(CTL(wcLockEnable), BM_SETCHECK, TRUE, 0)
  139.  
  140.  
  141.         '**** Volume Slider Section ****'
  142.         CreateControl(wcVolumeLbl, WS_EX_TRANSPARENT, WC_STATIC, "Volume to lock device to:", cLabelStyle, 19, 110, 170, 20)
  143.         CreateControl(wcVolLevelLbl, WS_EX_TRANSPARENT, WC_STATIC, Str(iVolume), cLabelStyle, 195, 110, 30, 20)
  144.         CreateControl(wcVolumeSlider, NULL, TRACKBAR_CLASS, "", cTrackBar, 10, 130, 380, 30)
  145.  
  146.         SendMessage(ctl(wcVolumeSlider), TBM_SETRANGE, TRUE, MAKELONG(0, 100))  'Set slider range
  147.         SendMessage(ctl(wcVolumeSlider), TBM_SETPAGESIZE, 0, 4)                 'Set page size
  148.         SendMessage(ctl(wcVolumeSlider), TBM_SETSEL, FALSE, MAKELONG(0, 1))    'Set selection range
  149.         SendMessage(ctl(wcVolumeSlider), TBM_SETPOS, TRUE, iVolume)        'Set position
  150.  
  151.  
  152.         '**** Mute Lock Enable/Disable ****'
  153.         CreateControl(wcMuteLockEnable, WS_EX_TRANSPARENT, WC_BUTTON, "Enable Mute Lock", cCheckBox, 19, 180, 160, 20)
  154.         CreateControl(wcMuteLockCtrl, WS_EX_TRANSPARENT, WC_BUTTON, "Mute Device:", cCheckBox, 39, 200, 140, 20)
  155.         EnableWindow(CTL(wcMuteLockCtrl), FALSE)
  156.  
  157.  
  158.         '**** Version string ****'
  159.         CreateControl(wcVersionLbl, WS_EX_TRANSPARENT, WC_STATIC, !"Volume locker V1.0\nGraham Downey (C) 2017", cLabelStyle, 239, 225, 190, 30)
  160.  
  161.         'Set font for all controls
  162.         for CNT as integer = wcMain to wcLast-1
  163.             SendMessage(CTL(CNT), WM_SETFONT, cast(WPARAM, hFont), true)
  164.         next CNT
  165.        
  166.         'Small font for version label
  167.         SendMessage(CTL(wcVersionLbl), WM_SETFONT, cast(WPARAM, hSmallFont), true)
  168.        
  169.         ReleaseDC(hWnd, hDC)
  170.         return 0
  171.        
  172.        
  173.     Case WM_COMMAND
  174.         Select Case lParam 'hwndCtl
  175.         Case CTL(wcInptSlct)
  176.             Select Case HIWORD(wParam) 'wNotifyCode
  177.             Case CBN_SELCHANGE
  178.                 var iCurDevice = SendMessage(CTL(wcInptSlct), CB_GETCURSEL, 0, 0)
  179.                 if (iCurDevice <> CB_ERR) then
  180.                     print "device changed ";iCurDevice
  181.                     SelectedDevice = iCurDevice ' Set new device to lock
  182.  
  183.                     CloseMixer()                'Close the old mixer device
  184.                    
  185.                     if LockEnabled then
  186.                         OpenMixer()                 'Open new selected one
  187.                     else
  188.                         EnableLock(TRUE): EnableLock(FALSE)
  189.                     end if
  190.            
  191.                     SendMessage(CTL(wcVolumeSlider), TBM_SETPOS, TRUE, iVolume)
  192.                 end if
  193.             End Select
  194.            
  195.         Case CTL(wcLockEnable)
  196.             Select Case HIWORD(wParam)
  197.             Case BN_CLICKED
  198.                 'Get checkbox state
  199.                 var iLockState = SendMessage(CTL(wcLockEnable), BM_GETCHECK, 0, 0)
  200.                 if iLockState = BST_CHECKED then
  201.                     EnableLock(TRUE)
  202.                 else
  203.                     EnableLock(FALSE)
  204.                 end if
  205.             End Select
  206.            
  207.         Case CTL(wcMuteLockEnable)
  208.             Select Case HIWORD(wParam)
  209.             Case BN_CLICKED
  210.                 var iLockState = SendMessage(CTL(wcMuteLockEnable), BM_GETCHECK, 0, 0)
  211.                 if iLockState = BST_CHECKED then
  212.                     EnableMuteLock(TRUE)
  213.                 else
  214.                     EnableMuteLock(FALSE)
  215.                 end if
  216.             End Select                
  217.            
  218.         End Select
  219.            
  220.    
  221.     Case WM_DESTROY
  222.         EnableLock(FALSE) ' disable lock and close mixer
  223.         DeleteObject(hFont)
  224.         DeleteObject(hSmallFont)
  225.         PostQuitMessage(0)
  226.         return 0
  227.     End Select
  228.    
  229.     return DefWindowProc(hWnd, iMsg, wParam, lParam)
  230. End Function
  231.    
  232.  
  233. Sub WinMain(hInstance as HINSTANCE, hPrevInstance as HINSTANCE, _
  234.             szCmdLine as PSTR, iCmdShow as Integer)
  235.            
  236.     Dim as HWND       hWnd
  237.     Dim as MSG        msg
  238.     Dim as WNDCLASSEX wcls
  239.  
  240.     #if ShowDebug
  241.         AllocConsole() 'Show console
  242.     #endif
  243.    
  244.     OpenMixer() 'Open mixer
  245.  
  246.     wcls.cbSize        = sizeof(WNDCLASSEX)
  247.     wcls.style         = CS_HREDRAW OR CS_VREDRAW
  248.     wcls.lpfnWndProc   = @WndProc
  249.     wcls.cbClsExtra    = 0
  250.     wcls.cbWndExtra    = 0
  251.     wcls.hInstance     = hInstance
  252.     wcls.hIcon         = LoadIcon(hInstance, "FB_PROGRAM_ICON")
  253.     wcls.hCursor       = LoadCursor(NULL, IDC_ARROW)
  254.     wcls.hbrBackground = cast(HBRUSH, COLOR_BTNFACE + 1)
  255.     wcls.lpszMenuName  = NULL
  256.     wcls.lpszClassName = strptr(szAppName)
  257.     wcls.hIconSm       = LoadIcon(hInstance, "FB_PROGRAM_ICON")
  258.    
  259.     if (RegisterClassEx(@wcls) = FALSE) then
  260.         Print "Error! Failed to register window class ", Hex(GetLastError())
  261.         sleep: system
  262.     end if
  263.    
  264.     const WINDOW_STYLE = WS_OVERLAPPEDWINDOW XOR WS_THICKFRAME XOR WS_MAXIMIZEBOX
  265.    
  266.     hWnd = CreateWindow(szAppName, _            ' window class name
  267.                         szCaption, _            ' Window caption
  268.                         WINDOW_STYLE, _         ' Window style
  269.                         CW_USEDEFAULT, _        ' Initial X position
  270.                         CW_USEDEFAULT, _        ' Initial Y Posotion
  271.                         WINDOW_WIDTH, _         ' Window width
  272.                         WINDOW_HEIGHT, _        ' Window height
  273.                         NULL, _                 ' Parent window handle
  274.                         NULL, _                 ' Window menu handle
  275.                         hInstance, _            ' Program instance handle
  276.                         NULL)                   ' Creation parameters
  277.                        
  278.     if hWnd = NULL then system
  279.            
  280.     ShowWindow(hWnd, iCmdShow)
  281.     UpdateWindow(hWnd)
  282.    
  283.     'while (GetMessage(@msg, NULL, 0, 0))
  284.     while (msg.message <> WM_QUIT)
  285.         while (PeekMessage(@msg, NULL, 0, 0, PM_REMOVE))
  286.             TranslateMessage(@msg)
  287.             DispatchMessage(@msg)
  288.         wend
  289.        
  290.         if LockEnabled then
  291.             'Get volume slider position
  292.             var iNewVolume = SendMessage(ctl(wcVolumeSlider), TBM_GETPOS, 0, 0)
  293.             if iNewVolume <> iVolume then
  294.                 iVolume = iNewVolume            'Set master volume to new slider value
  295.                 var sVolString = Str(iVolume)   'Convert to string
  296.                 SetWindowText(ctl(wcVolLevelLbl), StrPtr(sVolString)) 'Display on label
  297.             end if
  298.  
  299.             'SetVolume((iVolume * &HFFFF + 50) \ 100)
  300.             'Set volume
  301.             if iVolume = 100 then
  302.                 SetVolume(&HFFFF)
  303.             else
  304.                 SetVolume(655 * (iVolume + 1))
  305.                 'print 655 * (iVolume + 1)
  306.             end if
  307.             if MuteLockEnabled  then
  308.                 var iLockState = SendMessage(CTL(wcMuteLockCtrl), BM_GETCHECK, 0, 0)
  309.                 if iLockState = BST_CHECKED then
  310.                     SetMuteState(1)
  311.                 else
  312.                     SetMuteState(0)
  313.                 end if
  314.             end if
  315.         end if
  316.        
  317.         sleep 1,1
  318.     wend
  319.    
  320.     system msg.wParam
  321.     'return msg.wParam
  322. End Sub
  323.  
  324. Sub EnableLock(iEnable as integer)
  325.     'Enable/Disable all devices
  326.     EnableWindow(CTL(wcVolumeSlider), iEnable)
  327.     EnableWindow(CTL(wcVolLevelLbl), iEnable)
  328.     EnableWindow(CTL(wcVolumeLbl), iEnable)
  329.     EnableWindow(CTL(wcMuteLockEnable), iEnable)
  330.  
  331.     if iEnable then
  332.         OpenMixer()     'Open mixer
  333.         LockEnabled = 1 'Enable lock
  334.        
  335.         'Update volume display
  336.         var sVolString = Str(iVolume)
  337.         SetWindowText(ctl(wcVolLevelLbl), StrPtr(sVolString))
  338.         SendMessage(CTL(wcVolumeSlider), TBM_SETPOS, TRUE, iVolume)
  339.  
  340.         if MuteLockEnabled then EnableWindow(CTL(wcMuteLockCtrl), TRUE)
  341.     else
  342.         CloseMixer()    'Close mixer
  343.         LockEnabled = 0 'Disable lock
  344.         EnableWindow(CTL(wcMuteLockCtrl), FALSE)
  345.     end if
  346. End Sub
  347.  
  348. Sub EnableMuteLock(iEnable as integer)
  349.     'Enable/Disable mute control
  350.     EnableWindow(CTL(wcMuteLockCtrl), iEnable)
  351.     if iEnable then
  352.         MuteLockEnabled = 1 'Enable mute lock
  353.     else
  354.         MuteLockEnabled = 0 'Disable lock
  355.     end if
  356. End Sub
  357.  
  358. Sub EnumInputDevices()
  359.     Dim as WAVEINCAPS caps
  360.    
  361.     if TotalDevs = 0 then
  362.         MessageBox(NULL, "Error! No wave input devices found!", "Volume Locker - Error!", MB_ICONERROR)
  363.         system
  364.     end if
  365.    
  366.     for dev as uInteger = 0 to TotalDevs-1
  367.         Dim as MMRESULT result = waveInGetDevCaps(dev, @caps, sizeof(caps))
  368.        
  369.         if (result <> MMSYSERR_NOERROR) then
  370.             print "waveInGetDevCaps failed: returned 0x"+hex(result)
  371.             'sleep: system
  372.         end if
  373.        
  374.         'Store device names in array
  375.         strcpy(DevIDs(dev).szName, caps.szPname) 'Store name
  376.     next dev
  377. End Sub
  378.  
  379. Sub SetVolume(dwVolumeLevel as DWORD)
  380.     Dim as MIXERCONTROL                 mixerControl
  381.     Dim as MIXERLINECONTROLS            mixerLineControls
  382.     Dim as MIXERCONTROLDETAILS          mixerControlDetails
  383.     Dim as MIXERCONTROLDETAILS_UNSIGNED value(1)
  384.     Dim as MMRESULT                     result
  385.    
  386.     'Don't try setting volume if we know it has none! lol
  387.     if (HasVolumeControl = 0) then
  388.         return
  389.     end if
  390.    
  391.     mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS)
  392.     mixerLineControls.dwLineID = mixerLine.dwLineID
  393.    
  394.     mixerLineControls.cControls = 1 'Only get info for one control
  395.    
  396.     'Check for mute switch
  397.     mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME
  398.     mixerLineControls.pamxctrl = @mixerControl
  399.    
  400.     mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL)
  401.    
  402.     result = mixerGetLineControls(cast(HMIXEROBJ, MixerHandle), @mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE)
  403.     if (result <> MMSYSERR_NOERROR) then
  404.         var sErrMsg = "Warning! "+mixerLine.szName+" has no volume control!"
  405.         MessageBox(NULL, StrPtr(sErrMsg), "Volume Locker - Error!", MB_ICONWARNING)
  406.         HasVolumeControl = 0: EnableWindow(CTL(wcVolumeSlider), FALSE) 'disable volume slider
  407.         print mixerLine.szName; " has no volume control!"
  408.     else
  409.         mixerControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS)
  410.    
  411.         mixerControlDetails.dwControlID = mixerControl.dwControlID
  412.        
  413.         mixerControlDetails.cChannels = mixerLine.cChannels
  414.         if (mixerControlDetails.cChannels > 2) then mixerControlDetails.cChannels = 2
  415.         if (mixerControl.fdwControl AND MIXERCONTROL_CONTROLF_UNIFORM) then mixerControlDetails.cChannels = 1
  416.        
  417.         mixerControlDetails.cMultipleItems = 0
  418.         mixerControlDetails.paDetails = @value(0)
  419.         mixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED)
  420.        
  421.         'Store mute state for both channels
  422.         value(0).dwValue = dwVolumeLevel
  423.         value(1).dwValue = dwVolumeLevel
  424.        
  425.         result = mixerSetControlDetails(cast(HMIXEROBJ, MixerHandle), @mixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE)
  426.         if (result <> MMSYSERR_NOERROR) then
  427.             print "Error #"; result; " setting volume for "; mixerLine.szName
  428.         end if
  429.     end if
  430. End Sub
  431.  
  432. Sub SetMuteState(dwMuteState as DWORD)
  433.     Dim as MIXERCONTROL                 mixerControl
  434.     Dim as MIXERLINECONTROLS            mixerLineControls
  435.     Dim as MIXERCONTROLDETAILS          mixerControlDetails
  436.     Dim as MIXERCONTROLDETAILS_UNSIGNED value(1)
  437.     Dim as MMRESULT                     result
  438.    
  439.     'Don't try setting the mute state if we know it has none!
  440.     if (HasMuteControl = 0) then
  441.         return
  442.     end if
  443.    
  444.     mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS)
  445.     mixerLineControls.dwLineID = mixerLine.dwLineID
  446.    
  447.     mixerLineControls.cControls = 1 'Only get info for one control
  448.    
  449.     'Check for mute switch
  450.     mixerLineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE
  451.     mixerLineControls.pamxctrl = @mixerControl
  452.    
  453.     mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL)
  454.    
  455.     result = mixerGetLineControls(cast(HMIXEROBJ, MixerHandle), @mixerLineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE)
  456.     if (result <> MMSYSERR_NOERROR) then
  457.         var sErrMsg = "Warning! "+mixerLine.szName+" has no mute control!"
  458.         MessageBox(NULL, StrPtr(sErrMsg), "Volume Locker - Error!", MB_ICONWARNING)
  459.         HasMuteControl = 0
  460.         print mixerLine.szName; " has no mute control!"
  461.     else
  462.         mixerControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS)
  463.    
  464.         mixerControlDetails.dwControlID = mixerControl.dwControlID
  465.        
  466.         mixerControlDetails.cChannels = mixerLine.cChannels
  467.         if (mixerControlDetails.cChannels > 2) then mixerControlDetails.cChannels = 2
  468.         if (mixerControl.fdwControl AND MIXERCONTROL_CONTROLF_UNIFORM) then mixerControlDetails.cChannels = 1
  469.        
  470.         mixerControlDetails.cMultipleItems = 0
  471.         mixerControlDetails.paDetails = @value(0)
  472.         mixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED)
  473.        
  474.         'Store mute state for both channels
  475.         value(0).dwValue = dwMuteState
  476.         value(1).dwValue = dwMuteState
  477.        
  478.         result = mixerSetControlDetails(cast(HMIXEROBJ, MixerHandle), @mixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE)
  479.         if (result <> MMSYSERR_NOERROR) then
  480.             print "Error #"; result; " setting mute for "; mixerLine.szName
  481.         end if
  482.     end if
  483.    
  484. End Sub
  485.  
  486. Sub OpenMixer()
  487.     Dim as integer result
  488.     'Open default input device
  489.     dim as WAVEFORMATEX pwfx
  490.     pwfx.wFormatTag = WAVE_FORMAT_PCM
  491.     pwfx.nChannels = 1
  492.     pwfx.nSamplesPerSec = 8000
  493.     pwfx.wBitsPerSample = 8
  494.     pwfx.nBlockAlign = (pwfx.nChannels * pwfx.wBitsPerSample) \ 8
  495.     pwfx.nAvgBytesPerSec = pwfx.nBlockAlign * pwfx.nSamplesPerSec
  496.     pwfx.cbSize = 0
  497.    
  498.     'Open wave input device
  499.     result = waveInOpen(cast(LPHWAVEIN, @WaveInHandle), SelectedDevice, @pwfx, NULL, NULL, CALLBACK_NULL)
  500.     if (result <> MMSYSERR_NOERROR) then
  501.         print "Error #"; result; " opening wave input device!"
  502.         EnableLock(FALSE) 'Disable lock because we couldn't open device to lock it
  503.         'sleep: system
  504.     end if
  505.    
  506.     'Open mixer for selected input
  507.     result = mixerOpen(@MixerHandle, cast(DWORD, WaveInHandle), 0, 0, MIXER_OBJECTF_HWAVEIN)
  508.     if (result <> MMSYSERR_NOERROR) then
  509.         print "Error #"; result; " opening input mixer!"
  510.         EnableLock(FALSE)
  511.         'sleep: system
  512.     end if
  513.    
  514.     'Get line info for selected mixer
  515.     mixerLine.cbStruct = sizeof(MIXERLINE)
  516.     mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN
  517.     result = mixerGetLineInfo(cast(HMIXEROBJ, MixerHandle), @mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE)
  518.     if (result <> MMSYSERR_NOERROR) then
  519.         print "Error #"; result; " reading line recording control!"
  520.         EnableLock(FALSE)
  521.         'sleep: system
  522.     end if
  523.  
  524.     'Get mixer line controls
  525.     Dim as MIXERCONTROL mxc
  526.     Dim as MIXERLINECONTROLS mxlc
  527.     mxlc.cbStruct = SizeOf(mxlc)
  528.     mxlc.dwLineID = mixerLine.dwLineID
  529.     mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME
  530.     mxlc.cControls = 1
  531.     mxlc.cbmxctrl = SizeOf(mxc)
  532.     mxc.cbStruct = SizeOf(mxc)
  533.     mxlc.pamxctrl = @mxc
  534.    
  535.     result = mixerGetLineControls(cast(HMIXEROBJ, MixerHandle), @mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)
  536.     if (result <> MMSYSERR_NOERROR) then
  537.         print "Error #"; result; " getting line controls!"
  538.         EnableLock(FALSE)
  539.     end if
  540.  
  541.     'Get line's current volume
  542.     Dim as MIXERCONTROLDETAILS mxcd
  543.     Dim as MIXERCONTROLDETAILS_SIGNED VolStruct
  544.     mxcd.cbStruct = SizeOf(mxcd)
  545.     mxcd.dwControlID = mxc.dwControlID
  546.     mxcd.cbDetails = SizeOf(VolStruct)
  547.     mxcd.paDetails = @VolStruct
  548.     mxcd.cChannels = 1
  549.    
  550.     result = mixerGetControlDetails(cast(HMIXEROBJ, MixerHandle), @mxcd, MIXER_GETCONTROLDETAILSF_VALUE)
  551.     if (result <> MMSYSERR_NOERROR) then
  552.         print "Error #"; result; " getting current line volume!"
  553.         iVolume = 0 'can't read volume, set it to 0
  554.     else
  555.         iVolume = VolStruct.lValue 'Otherwise, store volume
  556.         if iVolume < 0 then iVolume = -iVolume
  557.     end if
  558.    
  559.     iVolume = (iVolume * 100 + 50) \ 65535 'Convert from actual value to percent
  560.     var sVolString = Str(iVolume)   'Convert to string
  561.     SetWindowText(ctl(wcVolLevelLbl), StrPtr(sVolString)) 'Display on label
  562. End Sub
  563.  
  564. Sub CloseMixer()
  565.     Dim result as integer
  566.     result = mixerClose(MixerHandle)
  567.     if (result <> MMSYSERR_NOERROR) then
  568.         print "Error #"; result; " closing mixer!"
  569.         'sleep: system
  570.     end if
  571.  
  572.     result = waveInClose(WaveInHandle)
  573.     if (result <> MMSYSERR_NOERROR) then
  574.         print "Error #"; result; " Closing wave in device!"
  575.         'sleep: system
  576.     end if
  577.    
  578.     HasVolumeControl = -1
  579.     HasMuteControl = -1
  580. End Sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement