Oops, the Jarvis Command and Control Grammar was not applied because this line was REMED.
'gsBannerDictation = "*"
Also the Jarvis Command & Control Grammar does not work because of this line:
<RULEREF NAME="voiceCmd"/>
Which calls a name that does not exist.
Sorry about that.
Here is the update.
VistaPlusAudio.zip
X
-
Version 3 with Jarvis C&CG speech recognition enabled.
Code:'Volume and mute control for Vista, Seven, Eight, and Ten. 'Callback functions will syncronize speaker volume and mute 'microphone volume and mute and microphone boost with other mixer controls. 'Based on work done by Pierre Bellisle. 'Works with PBWIN10.4 and J.Roca includes WINAPI_III_107. 'Released to the public on 2020 MAY 12. 'Version 3 'Speech Recognition implemented 'Note: 'Once the microphone is muted there is no recognition. #COMPILE EXE "VolumeWithCallbackVistaPlus.exe" #DIM ALL #REGISTER NONE $CandCGrammar = "JARVIS.xml" 'unused functions '-------------------------------------------------------------------------------- ' ** Globals ** '-------------------------------------------------------------------------------- GLOBAL g_guid_1_Context AS GUID 'speakers volume/mute-unmute context GLOBAL g_guid_2_Context AS GUID 'microphone volume/mute-unmute context GLOBAL g_guid_3_Context AS GUID 'microphone boost volume context (currently not used) 'SAPI GLOBAL InProcEvents AS ISpeechRecoContextEventsImplemented 'SAPI interface GLOBAL giRunningRecogProcess AS LONG 'SAPI GLOBAL RecognitionStatus AS LONG 'SAPI GLOBAL giStartStopRecognition AS LONG 'SAPI GLOBAL oRecoContext AS ISpeechRecoContext 'SAPI GLOBAL oRecognizer AS ISpeechRecognizer 'SAPI GLOBAL oMyGrammar AS ISpeechRecoGrammar 'SAPI GLOBAL oCategory AS ISpeechObjectTokenCategory 'SAPI GLOBAL oToken AS ISpeechObjectToken 'SAPI GLOBAL giCCGrammarLoaded AS LONG 'SAPI GLOBAL gsBannerDictation AS STRING 'SAPI GLOBAL gsBannerListen AS STRING 'SAPI GLOBAL giProcessingRecog AS LONG 'SAPI GLOBAL giRecogNotUnderstood AS LONG 'SAPI GLOBAL MyDataX AS STRING 'SAPI contains the recognized phrase 'END SAPI GLOBAL hDlg AS DWORD GLOBAL giProgStat AS LONG GLOBAL VistaPlus AS LONG 'Vista to 10 GLOBAL sBuffer AS STRING GLOBAL gsMasterVolumeIsChangeable AS STRING '"YES" OR "NO" GLOBAL gpIMMDeviceEnumSpeakers AS IMMDeviceEnumerator GLOBAL gpIMMDeviceSpeakers AS IMMDevice GLOBAL gpIAudioEndpointVolumeSpeakers AS IAudioEndpointVolume GLOBAL giSpeakers AS LONG ' default stereo speaker availablility yes = 1, no = 0 GLOBAL giSpeakersHr AS LONG GLOBAL giMasterSpeakersLevel AS LONG GLOBAL gsTheSpeakersName AS STRING GLOBAL giMasterSpeakersMuteLevel AS LONG GLOBAL gpIMMDeviceEnumMicrophone AS IMMDeviceEnumerator GLOBAL gpIMMDeviceMicrophone AS IMMDevice GLOBAL gpIAudioEndpointVolumeMicrophone AS IAudioEndpointVolume GLOBAL giMicrophone AS LONG ' default microphone availablility yes = 1, no = 0 GLOBAL giMicrophoneHr AS LONG GLOBAL giMasterMicrophoneLevel AS LONG GLOBAL gsTheMicrophoneName AS STRING GLOBAL giMasterMicrophoneMuteLevel AS LONG GLOBAL giMasterMicroBoostLevel AS LONG 'value 0, 10, 20, 30 GLOBAL gpIMMNotificationClientMicrophone AS IMMNotificationClient GLOBAL pDeviceTopology AS IDeviceTopology GLOBAL pConnFrom AS IConnector GLOBAL pConnTo AS IConnector GLOBAL pPartPrev AS IPart GLOBAL pPartNext AS IPart GLOBAL ppParts AS IPartsList GLOBAL pIaudioVolumeLevel AS IAudioVolumeLevel GLOBAL pSelector AS IAudioInputSelector GLOBAL ppNotify_1 AS IAudioEndpointVolumeCallback 'speakers GLOBAL ppNotify_2 AS IAudioEndpointVolumeCallback 'microphone GLOBAL ppNotify_3 AS IControlChangeNotify 'microphone boost GLOBAL PEAK AS SINGLE 'for peak meter GLOBAL gpMeterInfo AS IAudioMeterInformation GLOBAL pDevId AS WSTRINGZ PTR GLOBAL devName AS WSTRING GLOBAL pName AS WSTRINGZ PTR 'LPWSTR pName GLOBAL giMicroMute AS LONG 'Tracks Microphone Mute status GLOBAL pflow AS LONG 'DataFlow pflow GLOBAL pPartType AS LONG 'PartType GLOBAL bConnected AS LONG 'BOOL bConnected GLOBAL connType AS LONG 'ConnectorType GLOBAL ComponentName AS WSTRINGZ * 255 GLOBAL XFill AS STRING 'used to post text to clipboard GLOBAL giPRTDMessage AS LONG GLOBAL giPumpingMessages AS LONG GLOBAL CLSID_MMDeviceEnumerator AS GUID GLOBAL IID_IMMDeviceEnumerator AS GUID GLOBAL IID_IPart AS GUID GLOBAL IID_IAudioVolumeLevel AS GUID GLOBAL IID_IConnector AS GUID GLOBAL IID_IAudioInputSelector AS GUID GLOBAL IID_IAudioEndpointVolume AS GUID GLOBAL IID_IDeviceTopology AS GUID GLOBAL IID_IAudioMeterInformation AS GUID GLOBAL IID_IAudioEndpointVolumeCallback AS GUID GLOBAL IID_IControlChangeNotify AS GUID GLOBAL LastValue AS SINGLE $AppName = "Audio with Callback" '-------------------------------------------------------------------------------- ' ** Constants ** '-------------------------------------------------------------------------------- ENUM Equates SINGULAR ID_RefreshBanner = %WM_USER + 5001 'SAPI LabelMinSpeakers 'MIN LabelMaxSpeakers 'MAX LabelVolSpeakers LabelInfoSpeakers LabelOnOffSpeakers TrackbarVolSpeakers CheckboxVolOnOffSpeakers ButtonSndVolExeSpeakers LabelMinMicro 'MIN LabelMaxMicro 'MAX LabelVolMicro LabelInfoMicro LabelOnOffMicro TrackbarVolMicro CheckboxVolOnOffMicro ButtonSndVolExeMicro LabelMinMicroBoost LabelMaxMicroBoost LabelVolMicroBoost LabelInfoMicroBoost 'LabelOnOffMicroBoost 'not used TrackbarVolMicroBoost 'CheckboxVolOnOffMicroBoost 'not used 'ButtonSndVolExeMicroBoost 'not used ID_VOLUME IDC_PEAK_METER SpeakersUp SpeakersDn MicrophoneUp MicrophoneDn MicrophoneBoostUp MicrophoneBoostDn SpeakersMuteUnmute MicrophoneMuteUnmute END ENUM %TrackbarMax = 100 'for speaker and microphone trackbar %TrackbarMaxBoost = 3 'for microphone boost trackbar '-------------------------------------------------------------------------------- ' ** Includes ** '-------------------------------------------------------------------------------- '#INCLUDE ONCE "MB_API_A.inc" 'WHEN USED {6,996 total lines} COMPILE TIME 0.1 seconds 'OR THESE #INCLUDE ONCE "Win32Api.inc" 'WHEN USED {289,783 total lines} COMPILE TIME 1.9 seconds #INCLUDE ONCE "CommCtrl.inc" 'Needed if manifest and WinXP #INCLUDE ONCE "mmdeviceapi.inc" 'used for WASAPI #INCLUDE ONCE "devpkey.inc" 'used for WASAPI #INCLUDE ONCE "propvarutil.inc" 'used for WASAPI #INCLUDE ONCE "endpointvolume.inc" 'used for WASAPI #INCLUDE ONCE "propsys.inc" 'used for WASAPI #INCLUDE ONCE "sapi.inc" 'used for SAPI #INCLUDE ONCE "WinNls.inc" 'User language ' ######################################################################################## ' Class CISpeechRecoContextEvents SAPI ' Interface name = _ISpeechRecoContextEvents ' IID = {7B8FCB42-0E9D-4F00-A048-7B04D6179D3D} ' Attributes = 4096 [&H1000] [Dispatchable] ' ######################################################################################## CLASS CISpeechRecoContextEventsImplemented GUID$("{5B344ADB-C0C7-4B5F-8046-7D2DB91A1D75}") AS EVENT INTERFACE ISpeechRecoContextEventsImplemented GUID$("{7B8FCB42-0E9D-4F00-A048-7B04D6179D3D}") AS EVENT INHERIT IDISPATCH ' ===================================================================================== METHOD Recognition <7> ( _ BYVAL StreamNumber AS LONG _ ' __in long StreamNumber , BYVAL StreamPosition AS VARIANT _ ' __in VARIANT StreamPosition , BYVAL RecognitionType AS LONG _ ' __in SpeechRecognitionType RecognitionType , BYVAL Result AS ISpeechRecoResult _ ' __in ISpeechRecoResult *Result ) ' void LOCAL pDisp AS IDISPATCH LOCAL bstrText AS WSTRING IF ISNOTHING(Result) THEN EXIT METHOD pDisp = Result OBJECT CALL pDisp.PhraseInfo.GetText TO bstrText IF OBJRESULT THEN ? "GetText error: " & OBJRESULT$ ELSE giRecogNotUnderstood = 0 MyDataX = TRIM$(bstrText) '? "]" & MyDataX & "[" END IF END METHOD ' ===================================================================================== ' ===================================================================================== METHOD FalseRecognition <11> ( _ BYVAL StreamNumber AS LONG _ ' __in long StreamNumber , BYVAL StreamPosition AS VARIANT _ ' __in VARIANT StreamPosition , BYVAL Result AS ISpeechRecoResult _ ' __in ISpeechRecoResult *Result ) ' void LOCAL pDisp AS IDISPATCH LOCAL bstrText AS WSTRING IF ISNOTHING(Result) THEN EXIT METHOD END IF pDisp = Result OBJECT CALL pDisp.PhraseInfo.GetText TO bstrText IF OBJRESULT THEN ? "GetText error: " & OBJRESULT$ ELSE giRecogNotUnderstood = 1 MyDataX = "What was that?" '? "]" & MyDataX & "[" END IF END METHOD END INTERFACE END CLASS ' ######################################################################################## ' Class CIAudioEndpointVolumeCallback ' Interface name = _IAudioEndpointVolumeCallback ' IID = {657804FA-D6AD-4496-8A60-352752AF4F89} ' Inherited interface = IUnknown ' ######################################################################################## CLASS CIAudioEndpointVolumeCallback_1 AS COM INTERFACE IAudioEndpointVolumeCallback $IID_IAudioEndpointVolumeCallback INHERIT IUNKNOWN ' ===================================================================================== METHOD OnNotify ( _ ' VTable offset = 12 BYREF pNotify_1 AS AUDIO_VOLUME_NOTIFICATION_DATA _ ' __in PAUDIO_VOLUME_NOTIFICATION_DATA pNotify ) AS LONG ' HRESULT 'Method-Callback that receives a pointer to the sample buffer. 'Callback method for endpoint-volume-change notifications. IF VARPTR(pNotify_1) = %NULL THEN METHOD = %E_INVALIDARG ELSE IF (hDlg <> %NULL) THEN IF (pNotify_1.guidEventContext <> g_guid_1_Context) THEN 'Post notification to main dialog SendMessageA (hDlg, %WM_APP, %CheckboxVolOnOffSpeakers, pNotify_1.bMuted) SendMessageA (hDlg, %WM_APP, %TrackbarVolSpeakers, pNotify_1.fMasterVolume * %TrackbarMax) END IF END IF METHOD = %S_OK END IF END METHOD ' ===================================================================================== END INTERFACE END CLASS ' ######################################################################################## ' Class CIAudioEndpointVolumeCallback ' Interface name = _IAudioEndpointVolumeCallback ' IID = {657804FA-D6AD-4496-8A60-352752AF4F89} ' Inherited interface = IUnknown ' ######################################################################################## CLASS CIAudioEndpointVolumeCallback_2 AS COM INTERFACE IAudioEndpointVolumeCallback $IID_IAudioEndpointVolumeCallback INHERIT IUNKNOWN ' ===================================================================================== METHOD OnNotify ( _ ' VTable offset = 12 BYREF pNotify_2 AS AUDIO_VOLUME_NOTIFICATION_DATA _ ' __in PAUDIO_VOLUME_NOTIFICATION_DATA pNotify ) AS LONG ' HRESULT 'Method-Callback that receives a pointer to the sample buffer. 'Callback method for endpoint-volume-change notifications. IF VARPTR(pNotify_2) = %NULL THEN METHOD = %E_INVALIDARG ELSE IF (hDlg <> %NULL) THEN IF (pNotify_2.guidEventContext <> g_guid_2_Context) THEN 'Post notification to main dialog SendMessageA (hDlg, %WM_APP, %CheckboxVolOnOffMicro, pNotify_2.bMuted) SendMessageA (hDlg, %WM_APP, %TrackbarVolMicro, pNotify_2.fMasterVolume * %TrackbarMax) END IF END IF METHOD = %S_OK END IF END METHOD ' ===================================================================================== END INTERFACE END CLASS ' ######################################################################################## ' Class CIControlChangeNotify ' Interface name = IControlChangeNotify ' IID = A09513ED-C709-4D21-BD7B-5F34C47F3947 ' Inherited interface = IUnknown ' ######################################################################################## CLASS CIControlChangeNotify AS COM INTERFACE IControlChangeNotify $IID_IControlChangeNotify INHERIT IUNKNOWN ' ===================================================================================== METHOD OnNotify ( _ ' VTable offset = 12 BYVAL dwSenderProcessId AS DWORD _ ' __in DWORD dwSenderProcessId , BYREF pguidEventContext AS GUID _ ' __in LPCGUID pguidEventContext ) AS LONG ' HRESULT ' ===================================================================================== IF (hDlg <> %NULL) THEN IF (pguidEventContext <> g_guid_3_Context) THEN 'Get the microphone boost values CALL GetVolumeMicrophoneBoost END IF END IF METHOD = %S_OK END METHOD END INTERFACE END CLASS '_____________________________________________________________________________ ' SUB IconSet_1(iconOn AS LONG) DIM hIcon(0 TO 3) AS STATIC DWORD LOCAL Looper AS LONG SELECT CASE iconOn CASE 0, 1 'Set "disable icon" or "enable icon" on dialog ans static SetClassLongA (hDlg, %GCL_HICONSM, hIcon(iconOn)) SendMessageA (hDlg, %WM_SETICON, %ICON_SMALL, hIcon(iconOn)) SendDlgItemMessageA (hDlg, %LabelOnOffSpeakers, %STM_SETIMAGE, %IMAGE_ICON, hIcon(iconOn + 02)) CASE -2 'Get "disable icon" and "enable icon" from appropriate files IF VistaPlus THEN 'Vista to 10 ExtractIconExA ("SndVol.exe", 1, BYVAL VARPTR(hIcon(3)), BYVAL VARPTR(hIcon(1)), 1) 'Vista to 10, Enable-Big-Small ExtractIconExA ("SndVol.exe", 2, BYVAL VARPTR(hIcon(2)), BYVAL VARPTR(hIcon(0)), 1) 'Vista to 10, Disable-Big-Small ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF CASE -1 'Release memory clean-up FOR Looper = 0 TO 3 DestroyIcon (hIcon(Looper)) NEXT END SELECT END SUB ' ======================================================================================== ' Helper function to retrieve the friendly name of the audio device. ' ======================================================================================== FUNCTION AfxGetDeviceName (BYVAL pDev AS IMMDevice) AS WSTRING LOCAL hr AS LONG LOCAL pPropStore AS IPropertyStore hr = pDev.OpenPropertyStore(%STGM_READ, pPropStore) IF FAILED(hr) THEN EXIT FUNCTION LOCAL friendlyName AS PROPVARIANT PropVariantInit(friendlyName) hr = pPropStore.getValue(DEVPKEY_Device_FriendlyName, friendlyName) IF FAILED(hr) THEN EXIT FUNCTION LOCAL wszDevName AS WSTRINGZ * 128 PropVariantToString(friendlyName, wszDevName, 128) FUNCTION = wszDevName PropVariantClear(friendlyName) END FUNCTION '_________________________________________________________________ ' ' SUB UnRegisterSpeakerCallback '_________________________________________________________________ SUB UnRegisterSpeakerCallback LOCAL xhr AS LONG xhr = gpIAudioEndpointVolumeSpeakers.UnRegisterControlChangeNotify( _ BYVAL ppNotify_1) 'IAudioEndpointVolumeCallback END SUB '_________________________________________________________________ ' ' SUB UnRegisterMicrophoneCallback '_________________________________________________________________ SUB UnRegisterMicrophoneCallback LOCAL xhr AS LONG xhr = gpIAudioEndpointVolumeMicrophone.UnRegisterControlChangeNotify( _ BYVAL ppNotify_2) 'IAudioEndpointVolumeCallback END SUB '_________________________________________________________________ ' ' SUB UnRegisterMicrophoneBoostCallback '_________________________________________________________________ SUB UnRegisterMicrophoneBoostCallback LOCAL xhr AS LONG xhr = pPartNext.UnRegisterControlChangeCallback( _ BYVAL ppNotify_3) 'IControlChangeNotify END SUB '_________________________________________________________________ ' ' FUNCTION SetSpeakersCallback '_________________________________________________________________ FUNCTION SetSpeakersCallback AS LONG 'Pointer to the IAudioEndpointVolumeCallback interface that the client 'is registering for notification callbacks. If the 'RegisterControlChangeNotify method succeeds, it calls the AddRef 'method on the client's IAudioEndpointVolumeCallback interface. LOCAL xhr AS LONG IF ISOBJECT(gpIAudioEndpointVolumeSpeakers) THEN xhr = CoCreateGuid (g_guid_1_Context) LET ppNotify_1 = CLASS "CIAudioEndpointVolumeCallback_1" xhr = gpIAudioEndpointVolumeSpeakers.RegisterControlChangeNotify(BYVAL ppNotify_1) 'IAudioEndpointVolumeCallback IF FAILED(xhr) THEN ? "Unable to set stereo speaker callback." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default stereo speaker callback." END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION SetMicrophoneCallback '_________________________________________________________________ FUNCTION SetMicrophoneCallback AS LONG 'Pointer to the IAudioEndpointVolumeCallback interface that the client 'is registering for notification callbacks. If the 'RegisterControlChangeNotify method succeeds, it calls the AddRef 'method on the client's IAudioEndpointVolumeCallback interface. LOCAL xhr AS LONG IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = CoCreateGuid (g_guid_2_Context) LET ppNotify_2 = CLASS "CIAudioEndpointVolumeCallback_2" xhr = gpIAudioEndpointVolumeMicrophone.RegisterControlChangeNotify(BYVAL ppNotify_2) 'IAudioEndpointVolumeCallback IF FAILED(xhr) THEN ? "Unable to set microphone callback." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default microphone callback." END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION SetMicrophoneBoostCallback '_________________________________________________________________ FUNCTION SetMicrophoneBoostCallback AS LONG LOCAL xhr AS LONG IF ISOBJECT(pPartNext) THEN xhr = CoCreateGuid (g_guid_3_Context) LET ppNotify_3 = CLASS "CIControlChangeNotify" xhr = pPartNext.RegisterControlChangeCallback( _ IID_IAudioVolumeLevel, _ BYVAL ppNotify_3) IF FAILED(xhr) THEN ? "Unable to set microphone boost callback." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default microphone boost callback." END IF END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION GetMuteSpeakers AS LONG LOCAL xhr AS LONG LOCAL fMute AS LONG IF ISOBJECT(gpIAudioEndpointVolumeSpeakers) THEN xhr = gpIAudioEndpointVolumeSpeakers.GetMute(fMute) IF FAILED(xhr) THEN ? "Unable to get stereo speakers mute level." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default stereo speakers mute level is " + STR$(fMute) END IF END IF giMasterSpeakersMuteLevel = fMute SELECT CASE fMute CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_CHECKED, 0) IconSet_1(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_UNCHECKED, 0) IconSet_1(1) END SELECT FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION MuteSpeakers AS LONG LOCAL xhr AS LONG IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeSpeakers) THEN xhr = gpIAudioEndpointVolumeSpeakers.SetMute(1, g_guid_1_Context) 'BYVAL %NULL) '%TRUE BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to mute default stereo speakers." ELSE '? "Default Speakers muted successfully!" END IF END IF giMasterSpeakersMuteLevel = 1 SELECT CASE giMasterSpeakersMuteLevel CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_CHECKED, 0) IconSet_1(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_UNCHECKED, 0) IconSet_1(1) END SELECT END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION UnMuteSpeakers AS LONG LOCAL xhr AS LONG IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeSpeakers) THEN xhr = gpIAudioEndpointVolumeSpeakers.SetMute(0, g_guid_1_Context) 'BYVAL %NULL) '%FALSE BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to unmute default stereo speakers." ELSE '? "Default Speakers unmuted successfully!" END IF END IF giMasterSpeakersMuteLevel = 0 SELECT CASE giMasterSpeakersMuteLevel CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_CHECKED, 0) IconSet_1(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_UNCHECKED, 0) IconSet_1(1) END SELECT END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== ' ======================================================================================== '_________________________________________________________________ ' ' FUNCTION SpeakersCheck '_________________________________________________________________ FUNCTION SpeakersCheck AS LONG LOCAL xhr AS LONG LOCAL pDevId AS WSTRINGZ PTR LOCAL devName AS WSTRING gpIMMDeviceEnumSpeakers = NEWCOM CLSID CLSID_MMDeviceEnumerator IF ISNOTHING(gpIMMDeviceEnumSpeakers) THEN EXIT FUNCTION ' // Enumerate the audio endpoints of interest (in this case audio capture endpoints) ' // The flags that can be used are %EDataFlow_eRender (for audio output endpoints), ' // %EDataFlow_eCapture (for audio capture endpoints) or %EDataFlow_eAll (for all audio endpoints) ' // %EDataFlow_eCapture (for audio capture endpoints), ' // %EDataFlow_eAll (for all audio endpoints) ' // %ERole_eConsole = Games, system notification sounds, and voice commands. ' // %ERole_eMultimedia = Music, movies, narration, and live music recording. ' // %ERole_eCommunications = Voice communications (talking to another person). giSpeakersHr = gpIMMDeviceEnumSpeakers.GetDefaultAudioEndpoint( _ %EDataFlow_eRender, _ %ERole_eMultimedia, _ gpIMMDeviceSpeakers) 'IMMDevice IF FAILED(giSpeakersHr) THEN 'CALL SHOW_NOTES("Unable to find default speakers.") ? "Unable to find the default Stereo Speakers" FUNCTION = 0 EXIT FUNCTION END IF xhr = gpIMMDeviceSpeakers.Activate( _ IID_IAudioEndpointVolume, _ %CLSCTX_INPROC_SERVER, _ BYVAL %NULL, _ gpIAudioEndpointVolumeSpeakers) 'IAudioEndpointVolume IF FAILED(xhr) THEN 'CALL SHOW_NOTES("Unable to activate default speakers.") ? "Unable to activate default Stereo Speakers" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default Stereo Speakers activated successfully!" ' // Get the device identifier xhr = gpIMMDeviceSpeakers.GetId(pDevId) IF pDevId THEN ' "Device id = " & @pDevId CoTaskMemFree(pDevId) END IF ' // Get the device name gsTheSpeakersName = AfxGetDeviceName (gpIMMDeviceSpeakers) 'IMMDevice END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION MicrophoneCheck new 2020 MAY 06 new '_________________________________________________________________ FUNCTION MicrophoneCheck AS LONG LOCAL xhr AS LONG LOCAL fMinDb AS SINGLE 'float fMinDb LOCAL fMaxDb AS SINGLE 'float fMaxDb LOCAL fStepDb AS SINGLE 'float fStepDb LOCAL pfCurrentDb AS SINGLE 'float pfCurrentDb ' Get enumerator for audio endpoint devices. gpIMMDeviceEnumMicrophone = NEWCOM CLSID CLSID_MMDeviceEnumerator IF ISNOTHING(gpIMMDeviceEnumMicrophone) THEN ? "Unable to create audio device enumerator." FUNCTION = 0 EXIT FUNCTION END IF ' // Enumerate the audio endpoints of interest (in this case audio capture endpoints) ' // The flags that can be used are: ' // %EDataFlow_eRender (for audio output endpoints), ' // %EDataFlow_eCapture (for audio capture endpoints), ' // %EDataFlow_eAll (for all audio endpoints) ' // %ERole_eConsole = Games, system notification sounds, and voice commands. ' // %ERole_eMultimedia = Music, movies, narration, and live music recording. ' // %ERole_eCommunications = Voice communications (talking to another person). '%DEVICE_STATE_ACTIVE giMicrophoneHr = gpIMMDeviceEnumMicrophone.GetDefaultAudioEndpoint(%EDataFlow_eCapture, %ERole_eConsole, gpIMMDeviceMicrophone) IF FAILED(giMicrophoneHr) THEN ? "Unable to find default microphone device." FUNCTION = 0 EXIT FUNCTION END IF xhr = gpIMMDeviceMicrophone.Activate( _ IID_IAudioEndpointVolume, _ %CLSCTX_INPROC_SERVER, _ BYVAL %NULL, _ gpIAudioEndpointVolumeMicrophone) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to activate a microphone.") ? "Unable to activate default microphone" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone activated successfully!" ' // Get the device identifier xhr = gpIMMDeviceMicrophone.GetId(pDevId) IF pDevId THEN XFill = "Device id = " & @pDevId 'Device id = {0.0.1.00000000}.{be4cea6b-aba4-4420-8e08-dbfb7a6be10c} 'call COPY_TO_CLIPBOARD CoTaskMemFree(pDevId) END IF ' // Get the device name gsTheMicrophoneName = AfxGetDeviceName(gpIMMDeviceMicrophone) '? gsTheMicrophoneName 'Get the endpoint device's IDeviceTopology interface. xhr = gpIMMDeviceMicrophone.Activate( _ IID_IDeviceTopology, _ %CLSCTX_ALL, _ BYVAL %NULL, _ pDeviceTopology) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get microphone topology.") ? "Unable to get microphone topology." FUNCTION = 0 EXIT FUNCTION END IF 'The device topology for an endpoint device always 'contains just one connector (connector number 0). xhr = pDeviceTopology.GetConnector(0, pConnFrom) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get the connector info.") ? "Unable to get the connector info." FUNCTION = 0 EXIT FUNCTION END IF pDeviceTopology = NOTHING 'Make sure that this is a capture device. xhr = pConnFrom.GetDataFlow(pflow) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get connector flow data.") ? "Unable to get connector flow data." FUNCTION = 0 EXIT FUNCTION ELSE 'For example, a typical rendering device on an adapter has a connector 'with data-flow direction "In" through which the Windows audio engine 'streams PCM data into the device. The same device has a connector with 'data-flow direction "Out" through which the device transmits an audio 'signal to speakers or headphones. '%DataFlow_In = 0 Input stream. The audio stream flows into the device through the connector. '%DataFlow_Out = 1 Output stream. The audio stream flows out of the device through the connector. SELECT CASE pFlow CASE 0 'In 'Error -- this is a rendering device. 'EXIT_ON_ERROR(xhr = %AUDCLNT_E_WRONG_ENDPOINT_TYPE) 'CALL SHOW_NOTES_NO_WAIT("Error! The connector flow data was wrong.") ? "Error! The connector flow data was wrong." FUNCTION = 0 EXIT FUNCTION CASE 1 'Out '? "DataFlow is out stream." END SELECT END IF '-------------------------------------- 'Computer\HKEY_CURRENT_USER\Control Panel\International\User Profile\en-US (if exists)0x00000001 (1) 'Name 0409:00000409 'Type: REG_DWORD 'Data: 0x00000001 (1) LOCAL dwReserved AS DWORD LOCAL MyVal AS DWORD LOCAL zLocale AS ASCIIZ * %MAX_PATH IF EnumUILanguagesA (CODEPTR(EnumUILanguagesCB()), dwReserved, MyVal) THEN 'If the function succeeds, the return value is TRUE. 'let pass ELSE ? "Error determining language to support" END IF REPLACE "English 0409" WITH "en-US" IN sBuffer 'windows 10 REPLACE "English 0009" WITH "en" IN sBuffer 'windows 7 REPLACE "French 040C" WITH "fr-FR" IN sBuffer 'windows 10 REPLACE "French 000C" WITH "fr" IN sBuffer 'windows 7 IF INSTR(sBuffer, "fr") THEN ComponentName = "Ampli Microphone" 'french ELSE ComponentName = "Microphone Boost" 'english END IF '-------------------------------------- CALL SelectCaptureDevice pConnFrom = NOTHING '\\\\\\\\\\\\\\\ 'Get the endpoint device's IAudioMeterInformation interface. xhr = gpIMMDeviceMicrophone.Activate( _ IID_IAudioMeterInformation, _ %CLSCTX_ALL, _ BYVAL %NULL, _ gpMeterInfo) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get peak meter info.") ? "Unable to get peak meter info." FUNCTION = 0 EXIT FUNCTION END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION GetMuteMicrophone '_________________________________________________________________ FUNCTION GetMuteMicrophone AS LONG LOCAL xhr AS LONG LOCAL fMute AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.GetMute(fMute) IF FAILED(xhr) THEN ? "Unable to get microphone mute level." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default microphone mute level is " + STR$(fMute) END IF giMasterMicrophoneMuteLevel = fMute SELECT CASE fMute CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_CHECKED, 0) 'IconSet_2(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_UNCHECKED, 0) 'IconSet_2(1) END SELECT END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION MuteMicrophone '_________________________________________________________________ FUNCTION MuteMicrophone AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.SetMute(1, g_guid_2_Context) '%TRUE, BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to mute default microphone." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default microphone muted successfully!" END IF giMasterMicrophoneMuteLevel = 1 SELECT CASE giMasterMicrophoneMuteLevel CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_CHECKED, 0) 'IconSet_2(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_UNCHECKED, 0) 'IconSet_2(1) END SELECT END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION UnMuteMicrophone '_________________________________________________________________ FUNCTION UnMuteMicrophone AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.SetMute(0, g_guid_2_Context) '%FALSE, BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to unmute default microphone." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default microphone unmuted successfully!" END IF giMasterMicrophoneMuteLevel = 0 SELECT CASE giMasterMicrophoneMuteLevel CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_CHECKED, 0) 'IconSet_2(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_UNCHECKED, 0) 'IconSet_2(1) END SELECT END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION GlobalVariableTest86 VER4 '_________________________________________________________________ FUNCTION GlobalVariableTest86() AS LONG IF giProgStat = 0 THEN FUNCTION = 1 END IF END FUNCTION '_________________________________________________________________ ' ' FUNCTION GlobalVariableTestOn VER4 '_________________________________________________________________ FUNCTION GlobalVariableTestOn() AS LONG IF giProgStat = 1 THEN FUNCTION = 1 END IF END FUNCTION '_________________________________________________________________ ' ' Processes pending Windows messages. VER4 ' Call this procedure if you are performing a tight ' FOR/NEXT or DO/LOOP and need to allow ' your application to be responsive to user input. ' Modified version of AfxPumpMessages '_________________________________________________________________ SUB MyPumpMessages(BYVAL xTimes AS LONG) EXPORT '///////////////////////////////////////////////////////////// 'Do not want to remove the WM_QUIT message from message que. IF GlobalVariableTest86 = 1 THEN EXIT SUB '///////////////////////////////////////////////////////////// LOCAL Ix AS LONG IF giPumpingMessages = 1 THEN EXIT SUB giPumpingMessages = 1 IF GlobalVariableTestOn THEN IF xTimes <= 0 THEN xTimes = 1 FOR Ix = 1 TO xTimes CALL PeekRemoveTranslateDispatchMessage IF GlobalVariableTest86 = 1 THEN GOTO NoMoreNeeded NEXT Ix END IF NoMoreNeeded: giPumpingMessages = 0 END SUB '_________________________________________________________________ ' ' GetEvents dialog procedure (replacement for Sleep 0) ' Sleep 0 releases time slices back to the OS but does ' not necessarily give your program the slices back. ' ' SUB GetEvents '_________________________________________________________________ SUB GetEvents(SleepTime AS LONG) EXPORT IF SleepTime <= 0 THEN SleepTime = 1 CALL PeekRemoveTranslateDispatchMessage SLEEP SleepTime/4 CALL PeekRemoveTranslateDispatchMessage SLEEP SleepTime/4 CALL PeekRemoveTranslateDispatchMessage SLEEP SleepTime/4 CALL PeekRemoveTranslateDispatchMessage SLEEP SleepTime/4 END SUB '_________________________________________________________________ ' ' SUB PeekRemoveTranslateDispatchMessage VER4 '_________________________________________________________________ SUB PeekRemoveTranslateDispatchMessage '///////////////////////////////////////////////////////////// 'Do not want to remove the WM_QUIT message from message que. IF GlobalVariableTest86 = 1 THEN EXIT SUB '///////////////////////////////////////////////////////////// 'Could use this to signal main message loop to close 'PostThreadMessageA (GetCurrentThreadID, %WM_QUIT, 0, 0) ' Signal Quit to Msg Loop IF giPRTDMessage = 1 THEN EXIT SUB giPRTDMessage = 1 STATIC Msg AS tagMsg IF PeekMessageA(Msg, %NULL, %NULL, %NULL, %PM_REMOVE) THEN TranslateMessage Msg DispatchMessageA Msg END IF giPRTDMessage = 0 END SUB '//----------------------------------------------------------- '// This function traverses the data path that extends from the '// endpoint device to the system bus (for example, PCI) '// or external bus (USB). If the function discovers a MUX '// (input selector) in the path, it selects the MUX input '// that connects to the stream from the endpoint device. '// In this case we are looking for the Microphone Boost '// parts. '//----------------------------------------------------------- 'Limits of Device Topology 'Where (con) is a connector 'microphone -> endpoint device B (con) physical external ' '-> Input Multiplexer Device (Topology Filter) ' (con) physical external IPart & IConnector ' subunit Mute -> IPart & ISubUnit ' subunit Vol -> IPart & ISubUnit ' subunit MUX -> IPart & ISubUnit ' (Con) Software Fixed IPart & IConnector ' '-> Wave Capture Device (Wave Filter) ' (Con) Software Fixed IPart & IConnector ' subunit ADC IPart & ISubUnit ' (Con) Software IO IPart & IConnector ' '-> System Bus Wave-in Stream (DMA) FUNCTION SelectCaptureDevice() AS LONG LOCAL hr AS LONG LOCAL ppwstrGlobalId AS WSTRINGZ PTR LOCAL ppBoostTopology AS IDeviceTopology hr = %S_OK pIaudioVolumeLevel = NOTHING IF ISOBJECT(pConnFrom) THEN 'continue ELSE GOTO ExitHere END IF '// Outer loop: Each iteration traverses the data path '// through a device topology starting at the input '// connector and ending at the output connector. WHILE %TRUE IF giProgStat = 0 THEN GOTO ExitHere hr = pConnFrom.IsConnected(bConnected) IF FAILED(hr) THEN GOTO ExitHere '// Does this connector connect to another device? IF bConnected = %FALSE THEN '// This is the end of the data path that '// stretches from the endpoint device to the '// system bus or external bus. Verify that '// the connection type is Software_IO. hr = pConnFrom.GetType(connType) IF FAILED(hr) THEN GOTO ExitHere IF connType = %ConnectorType_Software_IO THEN '? "Finished looking for connections." EXIT LOOP '// finished END IF IF FAILED(hr = %E_FAIL) THEN GOTO ExitHere END IF '// Get the connector in the next device topology, '// which lies on the other side of the connection. hr = pConnFrom.GetConnectedTo(pConnTo) IF FAILED(hr) THEN GOTO ExitHere '// Get the connector's IPart interface. hr = pConnTo.QueryInterface( _ IID_IPart, _ BYVAL VARPTR(pPartPrev)) IF FAILED(hr) THEN GOTO ExitHere pConnTo = NOTHING '// Inner loop: Each iteration traverses one link in a '// device topology and looks for input multiplexers. WHILE %TRUE IF giProgStat = 0 THEN GOTO ExitHere MyPumpMessages(2000) '// Follow downstream link to next part. hr = pPartPrev.EnumPartsOutgoing(ppParts) IF FAILED(hr) THEN GOTO ExitHere hr = ppParts.GetPart(0, pPartNext) ppParts = NOTHING IF FAILED(hr) THEN GOTO ExitHere hr = pPartNext.GetPartType(pPartType) IF FAILED(hr) THEN GOTO ExitHere IF SUCCEEDED(pPartNext.GetName(pName)) THEN '? @pName 'Microphone Boost 'Failure of the following call means only that 'the part is not a boost (microphone boost). IF UCASE$(ComponentName) <> UCASE$(@pName) THEN '? "Not a match." ELSE '? "The part name matched." 'get IAudioVolumeLevel to control volume hr = pPartNext.Activate( _ %CLSCTX_ALL, _ IID_IAudioVolumeLevel, _ pIaudioVolumeLevel) CALL SetMicrophoneBoostCallback GOTO ExitHere END IF CoTaskMemFree(pName) END IF '? "Try again..." SELECT CASE pPartType CASE %PartType_Connector '=0 '? "Connector found." '// We've reached the output connector that '// lies at the end of this device topology. hr = pPartNext.QueryInterface( _ IID_IConnector, _ BYVAL VARPTR(pConnFrom)) IF FAILED(hr) THEN GOTO ExitHere pPartPrev = NOTHING pPartNext = NOTHING EXIT LOOP CASE %PartType_Subunit '=1 '? "Subunit found." END SELECT '// Failure of the following call means only that '// the part is not a MUX (input selector). hr = pPartNext.Activate( _ %CLSCTX_ALL, _ IID_IAudioInputSelector, _ pSelector) IF hr = %S_OK THEN ? "The MUX was found." '// We found a MUX (input selector), so select '// the input from our endpoint device. LOCAL localId AS DWORD hr = pPartPrev.GetLocalId(localId) IF FAILED(hr) THEN GOTO ExitHere hr = pSelector.SetSelection(localId, BYVAL %NULL) IF FAILED(hr) THEN GOTO ExitHere pSelector = NOTHING END IF pPartPrev = NOTHING pPartPrev = pPartNext pPartNext = NOTHING WEND WEND ExitHere: CoTaskMemFree(pName) ppParts = NOTHING pConnTo = NOTHING pPartPrev = NOTHING pSelector = NOTHING FUNCTION = hr END FUNCTION '_____________________________________________________________________________ CALLBACK FUNCTION DlgProc LOCAL pNMHDR AS NMHDR POINTER LOCAL rcThumb_1 AS RECT LOCAL rcThumb_2 AS RECT LOCAL rcThumb_3 AS RECT LOCAL xhr AS LONG STATIC Mute AS LONG STATIC TrackBarPos_1 AS LONG STATIC TrackBarPos_2 AS LONG STATIC TrackBarPos_3 AS LONG LOCAL pid AS DWORD SELECT CASE CBMSG CASE %WM_INITDIALOG giProgStat = 1 gsMasterVolumeIsChangeable = "YES" giStartStopRecognition = 1 'start recognition IF VistaPlus THEN 'Vista to 10 giSpeakers = SpeakersCheck CALL GetMuteSpeakers CALL GetVolumeSpeakers CALL SetSpeakersCallback gpMeterInfo = NOTHING giMicrophone = MicrophoneCheck CALL GetMuteMicrophone CALL GetVolumeMicrophone CALL SetMicrophoneCallback CALL GetVolumeMicrophoneBoost CALL CREATE_THREAD_SERVICES ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF CASE %WM_APP SELECT CASE CB.WPARAM CASE %CheckboxVolOnOffSpeakers 'NOTIFY MASTER MUTE SELECT CASE CB.LPARAM CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_CHECKED, 0) IconSet_1(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_UNCHECKED, 0) IconSet_1(1) END SELECT CASE %CheckboxVolOnOffMicro 'NOTIFY MICROPHONE MUTE SELECT CASE CB.LPARAM CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_CHECKED, 0) 'IconSet_2(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_UNCHECKED, 0) 'IconSet_2(1) END SELECT CASE %TrackbarVolSpeakers 'NOTIFY MASTER VOLUME PostMessageA (GetDlgItem(hDlg, %TrackbarVolSpeakers), %TBM_SETPOS, %TRUE, %TrackbarMax - CB.LPARAM) SetDlgItemTextA (hDlg, %LabelVolSpeakers, FORMAT$(CB.LPARAM, "##0")) CASE %TrackbarVolMicro 'NOTIFY MICROPHONE VOLUME PostMessageA (GetDlgItem(hDlg, %TrackbarVolMicro), %TBM_SETPOS, %TRUE, %TrackbarMax - CB.LPARAM) SetDlgItemTextA (hDlg, %LabelVolMicro, FORMAT$(CB.LPARAM, "##0")) CASE %TrackbarVolMicroBoost 'NOTIFY MICROPHONE BOOST SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, %TrackbarMaxBoost - CB.LPARAM/10) SetDlgItemTextA (hDlg, %LabelVolMicroBoost, FORMAT$(CB.LPARAM, "##0") & " dB") END SELECT CASE %WM_COMMAND SELECT CASE CB.CTL CASE %SpeakersUp CALL SPEAKERS_UP CASE %SpeakersDn CALL SPEAKERS_DN CASE %MicrophoneUp CALL MICROPHONE_UP CASE %MicrophoneDn CALL MICROPHONE_DN CASE %MicrophoneBoostUp CALL MICROPHONE_BOOST_UP CASE %MicrophoneBoostDn CALL MICROPHONE_BOOST_DN CASE %SpeakersMuteUnmute CALL SpeakersMuteSelect CASE %MicrophoneMuteUnmute CALL MicrophoneMuteSelect 'SPEAKERS CASE %LabelOnOffSpeakers 'IF (CBCTLMSG = %STN_CLICKED) OR (CBCTLMSG = 1) THEN IF IsDlgButtonChecked (hDlg, %CheckboxVolOnOffSpeakers) THEN PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_UNCHECKED, 0) ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers), %BM_SETCHECK, %BST_CHECKED, 0) END IF PostMessageA (hDlg, %WM_COMMAND, MAKDWD(%CheckboxVolOnOffSpeakers, %BN_CLICKED), GetDlgItem(hDlg, %CheckboxVolOnOffSpeakers)) 'END IF CASE %CheckboxVolOnOffSpeakers 'IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN IF IsDlgButtonChecked(hDlg, %CheckboxVolOnOffSpeakers) THEN Mute = %TRUE IconSet_1(0) ELSE Mute = %FALSE 'Mute XOR %TRUE IconSet_1(1) END IF IF VistaPlus THEN 'Vista to 10 !!!!!! mute change SELECT CASE Mute CASE %TRUE CALL MuteSpeakers CASE %FALSE CALL UnMuteSpeakers END SELECT ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF 'END IF CASE %ButtonSndVolExeSpeakers 'IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN IF VistaPlus THEN 'Vista to 10 'SndVol.exe, use the -f flag to show the master volume slider only: SndVol.exe -f 'SndVol.exe allows you to specify window location by adding coordinates after -f switch: pid = SHELL("SndVol.exe") '"C:\Windows\System32\SndVol.exe" ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF 'END IF CASE %ButtonSndVolExeMicro 'IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN IF VistaPlus THEN 'Vista to 10 pid = SHELL("rundll32.exe shell32.dll,Control_RunDLL mmsys.cpl,,1") ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF 'END IF 'MICROPHONE CASE %LabelOnOffMicro 'IF (CBCTLMSG = %STN_CLICKED) OR (CBCTLMSG = 1) THEN IF IsDlgButtonChecked (hDlg, %CheckboxVolOnOffMicro) THEN PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_UNCHECKED, 0) ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_CHECKED, 0) END IF PostMessageA (hDlg, %WM_COMMAND, MAKDWD(%CheckboxVolOnOffMicro, %BN_CLICKED), GetDlgItem(hDlg, %CheckboxVolOnOffMicro)) 'END IF CASE %CheckboxVolOnOffMicro 'IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN IF IsDlgButtonChecked(hDlg, %CheckboxVolOnOffMicro) THEN Mute = %TRUE 'IconSet_2(0) ELSE Mute = %FALSE 'Mute XOR %TRUE 'IconSet_2(1) END IF IF VistaPlus THEN 'Vista to 10 !!!!!! mute change SELECT CASE Mute CASE %TRUE CALL MuteMicrophone CASE %FALSE CALL UnMuteMicrophone END SELECT ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF 'END IF END SELECT CASE %WM_NOTIFY pNMHDR = CBLPARAM 'SPEAKERS IF @pNMHDR.hwndFrom = GetDlgItem(hDlg, %TrackbarVolSpeakers) THEN IF @pNMHDR.code = %NM_RELEASEDCAPTURE THEN BEEP END IF SendMessageA (@pNMHDR.hwndFrom, %TBM_GETTHUMBRECT, 0, VARPTR(rcThumb_1)) MapWindowPoints (@pNMHDR.hwndFrom, hDlg, BYVAL VARPTR(rcThumb_1), 2) SetWindowPos (GetDlgItem(hDlg, %LabelVolSpeakers), 0, rcThumb_1.nRight + 5, _ rcThumb_1.nTop - 2, 0, 0, %SWP_NOZORDER OR %SWP_NOSIZE) END IF 'MICROPHONE IF @pNMHDR.hwndFrom = GetDlgItem(hDlg, %TrackbarVolMicro) THEN IF @pNMHDR.code = %NM_RELEASEDCAPTURE THEN 'BEEP END IF SendMessageA (@pNMHDR.hwndFrom, %TBM_GETTHUMBRECT, 0, VARPTR(rcThumb_2)) MapWindowPoints (@pNMHDR.hwndFrom, hDlg, BYVAL VARPTR(rcThumb_2), 2) SetWindowPos (GetDlgItem(hDlg, %LabelVolMicro), 0, rcThumb_2.nRight + 5, _ rcThumb_2.nTop - 2, 0, 0, %SWP_NOZORDER OR %SWP_NOSIZE) END IF 'MICROPHONE BOOST IF @pNMHDR.hwndFrom = GetDlgItem(hDlg, %TrackbarVolMicroBoost) THEN IF @pNMHDR.code = %NM_RELEASEDCAPTURE THEN 'BEEP END IF 'SendMessageA (@pNMHDR.hwndFrom, %TBM_GETTHUMBRECT, 0, VARPTR(rcThumb_3)) 'MapWindowPoints (@pNMHDR.hwndFrom, hDlg, BYVAL VARPTR(rcThumb_3), 2) 'SetWindowPos (GetDlgItem(hDlg, %LabelVolMicro), 0, rcThumb_3.nRight + 5, _ ' rcThumb_3.nTop - 2, 0, 0, %SWP_NOZORDER OR %SWP_NOSIZE) END IF CASE %WM_VSCROLL 'SPEAKERS IF CBLPARAM = GetDlgItem(hDlg, %TrackbarVolSpeakers) THEN SELECT CASE LOWRD(CBWPARAM) CASE %TB_LINEDOWN, %TB_LINEUP, %TB_THUMBPOSITION, %TB_THUMBTRACK, _ %TB_PAGEDOWN, %TB_PAGEUP, %TB_TOP, %TB_BOTTOM', %TB_ENDSCROLL TrackBarPos_1 = %TrackbarMax - SendMessageA (CBLPARAM, %TBM_GETPOS, 0, 0) SetDlgItemTextA (hDlg, %LabelVolSpeakers, FORMAT$(TrackBarPos_1, "##0")) 'Set speaker volume IF VistaPlus THEN 'Vista to 10 !!!!! volume change CALL SetVolumeSpeakers(TrackBarPos_1 / 100) 'range 0 to 100 ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END SELECT END IF 'MICROPHONE IF CBLPARAM = GetDlgItem(hDlg, %TrackbarVolMicro) THEN SELECT CASE LOWRD(CBWPARAM) CASE %TB_LINEDOWN, %TB_LINEUP, %TB_THUMBPOSITION, %TB_THUMBTRACK, _ %TB_PAGEDOWN, %TB_PAGEUP, %TB_TOP, %TB_BOTTOM', %TB_ENDSCROLL TrackBarPos_2 = %TrackbarMax - SendMessageA (CBLPARAM, %TBM_GETPOS, 0, 0) SetDlgItemTextA (hDlg, %LabelVolMicro, FORMAT$(TrackBarPos_2, "##0")) 'Set microphone volume IF VistaPlus THEN 'Vista to 10 !!!!! volume change CALL SetVolumeMicrophone(TrackBarPos_2 / 100) 'range 0 to 100 ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END SELECT END IF 'MICROPHONE BOOST IF CBLPARAM = GetDlgItem(hDlg, %TrackbarVolMicroBoost) THEN SELECT CASE LOWRD(CBWPARAM) CASE %TB_LINEDOWN, %TB_LINEUP, %TB_THUMBPOSITION, %TB_THUMBTRACK, _ %TB_PAGEDOWN, %TB_PAGEUP, %TB_TOP, %TB_BOTTOM', %TB_ENDSCROLL TrackBarPos_3 = %TrackbarMaxBoost - SendMessageA (CBLPARAM, %TBM_GETPOS, 0, 0) SetDlgItemTextA (hDlg, %LabelVolMicroBoost, FORMAT$(TrackBarPos_3 * 10, "##0") & " dB") 'Set microphone volume IF VistaPlus THEN 'Vista to 10 !!!!! volume change CALL SetVolumeMicrophoneBoost(TrackBarPos_3 * 10) 'range 0 to 3 ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END SELECT END IF CASE %WM_CLOSE CALL SetVolumeMicrophoneBoost(1 * 10) 'setting to 1 on close (range 0 to 3) giStartStopRecognition = 2 giProgStat = 0 'DestroyWindow hWnd CASE %WM_DESTROY 'window is being destroyed 'after windows is removed from screen (children still exist) CALL UnRegisterSpeakerCallback CALL UnRegisterMicrophoneCallback CALL UnRegisterMicrophoneBoostCallback pSelector = NOTHING gpIMMDeviceEnumMicrophone = NOTHING gpIMMDeviceMicrophone = NOTHING gpIAudioEndpointVolumeMicrophone = NOTHING gpMeterInfo = NOTHING pDeviceTopology = NOTHING pConnFrom = NOTHING pConnTo = NOTHING pPartPrev = NOTHING pPartNext = NOTHING ppParts = NOTHING pIaudioVolumeLevel = NOTHING 'PostQuitMessage 0 'only needed if dialog is modeless 'If an application processes this message, it should return zero. FUNCTION = 0 EXIT FUNCTION END SELECT END FUNCTION '______________________________________________________________________________ FUNCTION PBMAIN() LOCAL OS AS OSVERSIONINFOEXA OS.dwOSVersionInfoSize = SIZEOF(OSVERSIONINFOEXA) GetVersionExA (BYVAL VARPTR(OS)) IF (OS.dwPlatformId = %VER_PLATFORM_WIN32_NT) AND (OS.dwMajorVersion >= 6) THEN VistaPlus = %TRUE 'Vista to 10 END IF CLSID_MMDeviceEnumerator = GUID$("{BCDE0395-E52F-467C-8E3D-C4579291692E}") IID_IMMDeviceEnumerator = GUID$("{A95664D2-9614-4F35-A746-DE8DB63617E6}") IID_IAudioMeterInformation = GUID$("{C02216F6-8C67-4B5B-9D00-D008E73E0064}") IID_IDeviceTopology = GUID$("{2A07407E-6497-4A18-9787-32F79BD0D98F}") IID_IAudioEndpointVolume = GUID$("{5CDF2C82-841E-4546-9722-0CF74078229A}") IID_IPart = GUID$("{AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9}") IID_IAudioVolumeLevel = GUID$("{7FB7B48F-531D-44A2-BCB3-5AD5A134B3DC}") IID_IConnector = GUID$("{9C2C4058-23F5-41DE-877A-DF3AF236A09E}") IID_IAudioInputSelector = GUID$("{4F03DC02-5E6E-4653-8F72-A030C123D598}") IID_IAudioEndpointVolumeCallback = GUID$("{657804FA-D6AD-4496-8A60-352752AF4F89}") IID_IControlChangeNotify = GUID$("{A09513ED-C709-4D21-BD7B-5F34C47F3947}") DIALOG FONT "Segoe UI", 9 DIALOG NEW PIXELS, %HWND_DESKTOP, $AppNAme, , , 280, 400, _ %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg 'SPEAKERS IconSet_1(-2) 'Init IconSet_1(1) 'Set to icon on CONTROL ADD LABEL, hDlg, %LabelInfoSpeakers, "Speakers:", _ 15, 10, 80, 20, %WS_CHILD OR %WS_VISIBLE OR %SS_NOPREFIX OR %SS_CENTER, %WS_EX_CLIENTEDGE CONTROL ADD LABEL, hDlg, %LabelInfoMicro, "Microphone:", _ 100, 10, 80, 20, %WS_CHILD OR %WS_VISIBLE OR %SS_NOPREFIX OR %SS_CENTER, %WS_EX_CLIENTEDGE CONTROL ADD LABEL, hDlg, %LabelInfoMicroBoost, "Boost:", _ 185, 10, 80, 20, %WS_CHILD OR %WS_VISIBLE OR %SS_NOPREFIX OR %SS_CENTER, %WS_EX_CLIENTEDGE CONTROL ADD LABEL, hDlg, %LabelMaxSpeakers, "Max", 35, 40, 30, 12 CONTROL ADD LABEL, hDlg, %LabelMinSpeakers, "Min", 35, 195, 30, 12 CONTROL ADD LABEL, hDlg, %LabelVolSpeakers, "---", 60, 120, 30, 12 CONTROL ADD "MsCtls_TrackBar32", hDlg, %TrackbarVolSpeakers, "msctls_trackbar321", 30, 55, 25, 140, _ %WS_VISIBLE OR %WS_CHILD OR %TBS_BOTH OR %TBS_NOTICKS OR %WS_TABSTOP OR %TBS_VERT OR %TBS_REVERSED SendDlgItemMessageA (hDlg, %TrackbarVolSpeakers, %TBM_SETPOS, %TRUE, 50) SendDlgItemMessageA (hDlg, %TrackbarVolSpeakers, %TBM_SETPAGESIZE,0, 10) SendDlgItemMessageA (hDlg, %TrackbarVolSpeakers, %TBM_SETRANGEMAX, %TRUE, %TrackbarMax) SendDlgItemMessageA (hDlg, %TrackbarVolSpeakers, %TBM_SETRANGEMIN, %TRUE, 0) CONTROL ADD LABEL, hDlg, %LabelMaxMicro, "Max", 125, 40, 30, 12 CONTROL ADD LABEL, hDlg, %LabelMinMicro, "Min", 125, 195, 30, 12 CONTROL ADD LABEL, hDlg, %LabelVolMicro, "---", 150, 120, 30, 12 CONTROL ADD "MsCtls_TrackBar32", hDlg, %TrackbarVolMicro, "msctls_trackbar321", 120, 55, 25, 140, _ %WS_VISIBLE OR %WS_CHILD OR %TBS_BOTH OR %TBS_NOTICKS OR %WS_TABSTOP OR %TBS_VERT OR %TBS_REVERSED SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETPOS, %TRUE, 50) SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETPAGESIZE,0, 10) SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETRANGEMAX, %TRUE, %TrackbarMax) SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETRANGEMIN, %TRUE, 0) CONTROL ADD LABEL, hDlg, %LabelMaxMicroBoost, "Max", 90 + 125, 40, 30, 12 CONTROL ADD LABEL, hDlg, %LabelMinMicroBoost, "Min", 90 + 125, 195, 30, 12 CONTROL ADD LABEL, hDlg, %LabelVolMicroBoost, "---", 90 + 150, 120, 30, 12 CONTROL ADD "MsCtls_TrackBar32", hDlg, %TrackbarVolMicroBoost, "msctls_trackbar321", 90 + 120, 55, 25, 140, _ %WS_VISIBLE OR %WS_CHILD OR %TBS_BOTH OR %TBS_NOTICKS OR %WS_TABSTOP OR %TBS_VERT OR %TBS_REVERSED 'SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, 1) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPAGESIZE,0, 1) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETRANGEMAX, %TRUE, 3) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETRANGEMIN, %TRUE, 0) CONTROL ADD CHECKBOX, hDlg, %CheckboxVolOnOffMicro, "Microphone Mute", 50, 20 + 210, 140, 12, _ %BS_AUTOCHECKBOX OR %WS_TABSTOP CONTROL ADD CHECKBOX, hDlg, %CheckboxVolOnOffSpeakers, "Speakers Mute", 50, 20 + 230, 140, 12, _ %BS_AUTOCHECKBOX OR %WS_TABSTOP CONTROL ADD LABEL, hDlg, %LabelOnOffSpeakers, "", 190, 240, _ GetSystemMetrics (%SM_CXICON), GetSystemMetrics(%SM_CYICON), %SS_ICON OR %SS_NOTIFY IconSet_1(1) CONTROL ADD BUTTON, hDlg, %ButtonSndVolExeSpeakers, "Volume Mixer", 50, 280, 180, 22 CONTROL ADD BUTTON, hDlg, %ButtonSndVolExeMicro, "Recording Mixer", 50, 312, 180, 22 CONTROL ADD PROGRESSBAR, hDlg, %ID_VOLUME, "", 15, 352, 250, 20 CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETRANGE, 0, MAKLNG(0, 100) CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETSTEP, -1, 0 CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETBKCOLOR, 0, RGB(50,50,50) CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETBARCOLOR, 0, RGB(55,224,230) CONTROL ADD LABEL, hDlg, %IDC_PEAK_METER, "", 15, 377, 250, 20 DIALOG SHOW MODAL hDlg CALL DlgProc IconSet_1(-1) 'Release END FUNCTION '______________________________________________________________________________ '_________________________________________________________________ ' ' SUB CREATE_THREAD_SERVICES ' full time '_________________________________________________________________ SUB CREATE_THREAD_SERVICES CALL CreateRecognitionProcess LOCAL idThreadPeakMeter AS LONG THREAD CREATE PeakMeterThread(1) TO idThreadPeakMeter THREAD CLOSE idThreadPeakMeter TO idThreadPeakMeter END SUB '_________________________________________________________________ ' ' THREAD FUNCTION PeakMeterThread NEW 2020 MAY 18 NEW ' full time '_________________________________________________________________ THREAD FUNCTION PeakMeterThread(BYVAL yyy AS LONG) AS LONG DO WHILE GlobalVariableTestOn '// Update the peak meter in the dialog box. IF ISOBJECT(gpMeterInfo) THEN gpMeterInfo.GetPeakValue(PEAK) IF giMasterMicrophoneMuteLevel = 0 THEN CONTROL SET TEXT hDlg, %IDC_PEAK_METER, USING$("##.#", PEAK * 100) CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETPOS, (PEAK * 100), 0 ELSE PEAK = 0 'Need to do this to make sure the progress bar and 'peak indicator show 0.0 during computer speech. CONTROL SET TEXT hDlg, %IDC_PEAK_METER, USING$("##.#", PEAK * 100) CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETPOS, (PEAK * 100), 0 END IF END IF SLEEP 10 IF GlobalVariableTest86 = 1 THEN GOTO LoopEnd SLEEP 20 LOOP LoopEnd: END FUNCTION '_________________________________________________________________ ' ' SUB CreateRecognitionProcess Jarvis '_________________________________________________________________ SUB CreateRecognitionProcess LOCAL idThreadRecognition AS LONG THREAD CREATE RecogProcessThread(1) TO idThreadRecognition THREAD CLOSE idThreadRecognition TO idThreadRecognition END SUB '_________________________________________________________________ ' ' THREAD FUNCTION RecogProcessThread Jarvis ' full time ' ' new 2020 MAY 18 new ' ' Includes workaround for recognition volume AGC forcing volume to 91 ' The solution was to capture the volume level before using %SGDSActive ' and then reapplying the value after %SGDSActive was executed. ' For some unknown reason the callback didn't get a new level so the ' trackbar had to be refreshed as well. ' ' NOTE: oMyGrammar.DictationSetState(%SGDSActive) 'Turn Dictation on. ' This causes the microphone volume to drop to 91 the second time it is enabled ' instead of leaving the volume where it was originally set. ' Microsoft's way of making speech recognition idiot proof. '_________________________________________________________________ THREAD FUNCTION RecogProcessThread(BYVAL yyy AS LONG) AS LONG LOCAL MyPhraseData AS STRING SLEEP 1000 'small delay giRunningRecogProcess = 1 DO WHILE GlobalVariableTestOn = 1 MyPhraseData = TRIM$(MyDataX) IF MyPhraseData <> "" THEN MyDataX = "" CALL PutColonOnMarque CALL PROCESS_RECOGNITION(MyPhraseData) CALL ResetRecognition END IF SLEEP 20 CALL MyPumpMessages(100) IF GlobalVariableTest86 = 1 THEN EXIT LOOP END IF SELECT CASE RecognitionStatus CASE 0 IF giStartStopRecognition = 1 THEN giStartStopRecognition = 0 'reset signal IF ISFALSE ISOBJECT(oRecoContext) THEN CALL CREATE_RECOGNITION_CONTEXT '1st time %SGDSActive is called END IF IF ISTRUE ISOBJECT(oRecoContext) THEN CALL GetVolumeMicrophone 'workaround LastValue = giMasterMicrophoneLevel/100 'workaround CALL RECOGNITION_ENABLE '2nd time %SGDSActive is called RecognitionStatus = 1 CALL PutQuestionMarkOnMarque 'Emmulate recognition to test the interface. oRecoContext.Recognizer.EmulateRecognition("recognition has started") CALL SetVolumeMicrophone(LastValue) 'workaround CALL RefreshVolumeMicrophoneTrackbarPos(LastValue) 'workaround ELSE ? "The recognizer is not available." END IF ELSE END IF CASE 1 IF giStartStopRecognition = 2 THEN giStartStopRecognition = 0 'reset signal CALL RECOGNITION_OFF END IF END SELECT SLEEP 20 CALL MyPumpMessages(100) IF GlobalVariableTest86 = 1 THEN EXIT LOOP END IF LOOP giRunningRecogProcess = 0 END FUNCTION '_________________________________________________________________ ' ' SUB CREATE_RECOGNITION_CONTEXT Jarvis '_________________________________________________________________ SUB CREATE_RECOGNITION_CONTEXT LOCAL vInput AS STRING SLEEP 10 'Create an instance of the ISpeechRecoContext Interface oRecoContext = NEWCOM "SAPI.SpInProcRecoContext" '** VB WithEvents work around. ** 'Link the events of oRecoContext to InProcEvents to 'process a recognition event. InProcEvents = CLASS "CISpeechRecoContextEventsImplemented" EVENTS FROM oRecoContext CALL InProcEvents 'Create the InProc Speech Recognizer. oRecognizer = oRecoContext.Recognizer 'Create the InProc Speech Grammar. oMyGrammar = oRecoContext.CreateGrammar(1) 'Disable Grammar while loading it. oMyGrammar.State = %SGSDisabled 'Load the default Dictation Grammar. vInput = "" oMyGrammar.DictationLoad(vInput, %SLOstatic) oMyGrammar.DictationSetState(%SGDSInactive) 'Load the command and control grammar IF FileExists(EXE.PATH$ + $CandCGrammar) THEN '"jarvis.xml" oMyGrammar.CmdLoadFromFile(EXE.PATH$ + $CandCGrammar, %SLODynamic) 'SLOStatic) 'dim gData As Variant 'gData = gsSOLXML 'oMyGrammar.CmdLoadFromMemory gData, %SLODynamic 'Load from memory oMyGrammar.CmdSetRuleIdState(0, %SGDSInactive) giCCGrammarLoaded = 1 '? "Command and Control Grammar loaded" 'gsBannerDictation = "*" ELSE 'CALL FLASH_NOTE_FOR_SECONDS("Unable to load C&C grammar.", 1.5) '? "Unable to load C&C grammar." giCCGrammarLoaded = 0 'gsBannerDictation = ">" END IF CALL RECOGNITION_ENABLE 'Enable Grammar after loading it. oMyGrammar.State = %SGSEnabled CALL RECOGNITION_DISABLE 'Create the Audio Token Category. oCategory = NEWCOM "SAPI.SpObjectTokenCategory" 'Set the Audio Token category ID. oCategory.SetId("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\AudioInput") 'Create the Audio Token. oToken = NEWCOM "SAPI.SpObjectToken" 'Set the Token Category ID. oToken.SetId(oCategory.Default()) 'Give the Recognizer the Token. oRecognizer.PutRef_AudioInput() = oToken END SUB '_________________________________________________________________ ' ' SUB RECOGNITION_ENABLE '_________________________________________________________________ SUB RECOGNITION_ENABLE 'Start the recognition by activating one of the grammars IF ISTRUE ISOBJECT(oRecoContext) THEN IF giCCGrammarLoaded = 1 THEN IF gsBannerDictation = "*" THEN oMyGrammar.DictationSetState(%SGDSInactive) 'Turn Dictation off. oMyGrammar.CmdSetRuleIdState(0, %SGDSActive) 'turn command / contol on ELSE oMyGrammar.CmdSetRuleIdState(0, %SGDSInactive) 'turn command / contol off oMyGrammar.DictationSetState(%SGDSActive) 'Turn Dictation on. END IF ELSE oMyGrammar.DictationSetState(%SGDSActive) 'Turn Dictation on. END IF ELSE CALL PutEqualSignOnMarque END IF END SUB '_________________________________________________________________ ' ' SUB RECOGNITION_DISABLE '_________________________________________________________________ SUB RECOGNITION_DISABLE 'Stop the recognition by deactivating both of the grammars IF ISTRUE ISOBJECT(oRecoContext) THEN CALL PutTildeOnMarque oMyGrammar.DictationSetState(%SGDSInactive) 'Turn Dictation off. IF giCCGrammarLoaded = 1 THEN oMyGrammar.CmdSetRuleIdState(0, %SGDSInactive) 'turn command / contol off END IF ELSE CALL PutEqualSignOnMarque END IF END SUB '_________________________________________________________________ ' ' SUB RECOGNITION_OFF VISTA PLUS '_________________________________________________________________ SUB RECOGNITION_OFF CALL RECOGNITION_DISABLE RecognitionStatus = 0 END SUB '_________________________________________________________________ ' ' SUB PROCESS_RECOGNITION NEW 2020 MAY 18 NEW '_________________________________________________________________ SUB PROCESS_RECOGNITION(TheWordPhrase AS STRING) LOCAL lsMyData AS STRING LOCAL lsMessage AS STRING IF giProcessingRecog = 1 THEN CALL ResetRecognition: EXIT SUB giProcessingRecog = 1 lsMyData = LCASE$(TRIM$(TheWordPhrase)) REPLACE $CRLF WITH "" IN lsMyData REPLACE $CR WITH "" IN lsMyData REPLACE $TAB WITH "" IN lsMyData REPLACE "_" WITH "" IN lsMyData TheWordPhrase = "" CALL ResetRecognition CALL GetEvents(100) '? lsMyData SELECT CASE lsMyData CASE "recognition has started" 'update banner CASE "what was that?" CASE "speakers up", _ "speakes plus", _ "speakers increase", _ "haut-parleurs" PostMessageA hDlg, %WM_COMMAND, %SpeakersUp, 0 CASE "speakers down", _ "speakers minus", _ "speakers decrease", _ "haut-parleurs vers le bas" PostMessageA hDlg, %WM_COMMAND, %SpeakersDn, 0 CASE "microphone up", _ "microphone plus", _ "microphone increase", _ "microphone haut" PostMessageA hDlg, %WM_COMMAND, %MicrophoneUp, 0 CASE "microphone down", _ "microphone minus", _ "microphone decrease", _ "microphone vers le bas" PostMessageA hDlg, %WM_COMMAND, %MicrophoneDn, 0 CASE "boost up", _ "boost plus", _ "boost increase", _ "augmentation du microphone" PostMessageA hDlg, %WM_COMMAND, %MicrophoneBoostUp, 0 CASE "boost down", _ "boost minus", _ "boost decrease", _ "augmentation du microphone" PostMessageA hDlg, %WM_COMMAND, %MicrophoneBoostDn, 0 CASE "microphone mute", _ "microphone you", _ "microphone huge", _ "couper le microphone" PostMessageA hDlg, %WM_COMMAND, %MicrophoneMuteUnmute, 0 CASE "speakers mute", _ "speakers you", _ "haut-parleurs muets" PostMessageA hDlg, %WM_COMMAND, %SpeakersMuteUnmute, 0 CASE "boost mute" 'not used CASE "vol mixer", _ "volume mixer", _ "mélangeur de volume" PostMessageA hDlg, %WM_COMMAND, %ButtonSndVolExeSpeakers, 0 CASE "recording mixer", _ "table de mixage d'enregistrement" PostMessageA hDlg, %WM_COMMAND, %ButtonSndVolExeMicro, 0 END SELECT giProcessingRecog = 0 END SUB '_________________________________________________________________ ' ' SUB ResetRecognition Jarvis '_________________________________________________________________ SUB ResetRecognition GetEvents(80) IF RecognitionStatus = 1 THEN 'Pause Recognition oRecoContext.Pause() GetEvents(8) 'Resume Recognition oRecoContext.Resume() END IF END SUB SUB F698 'REFRESH_MARQUEE_BANNER PostMessageA hDlg, %WM_COMMAND, %ID_RefreshBanner, 0 END SUB '_________________________________________________________________ ' ' SUB PutTildeOnMarque the recognition context is available but not activated '_________________________________________________________________ SUB PutTildeOnMarque gsBannerListen = "~" CALL F698 END SUB '_________________________________________________________________ ' ' SUB PutColonOnMarque means a recognition has happened and is being processed are you ok '_________________________________________________________________ SUB PutColonOnMarque IF RecognitionStatus = 1 THEN IF giMicroMute = 0 THEN gsBannerListen = ":" CALL F698 END IF END IF END SUB '_________________________________________________________________ ' ' SUB PutQuestionMarkOnMarque the recognition context is available and active '_________________________________________________________________ SUB PutQuestionMarkOnMarque 'currently unused IF RecognitionStatus = 1 THEN IF giMicroMute = 0 THEN 'microphone is not muted gsBannerListen = "?" CALL F698 END IF END IF END SUB '_________________________________________________________________ ' ' SUB PutEqualSignOnMarque no recognition context available '_________________________________________________________________ SUB PutEqualSignOnMarque IF RecognitionStatus = 0 THEN gsBannerListen = "=" CALL F698 END IF END SUB '_________________________________________________________________ ' ' FileExists - make sure a file or folder exists '_________________________________________________________________ FUNCTION FileExists(sFileName AS ASCIIZ) AS LONG LOCAL sFN AS STRING sFN = REMOVE$(sFileName, $CRLF) FUNCTION = PathFileExistsA(BYVAL STRPTR(sFN)) 'Return non-zero if file or folder exist. END FUNCTION '_________________________________________________________________ ' ' SUB EnumUILanguagesCB '_________________________________________________________________ FUNCTION EnumUILanguagesCB(lpUILanguageString AS ASCIIZ, lParam AS LONG) AS LONG LOCAL zLocale AS ASCIIZ * %MAX_PATH GetLocaleInfoA (VAL("&h" & lpUILanguageString), %LOCALE_SENGLANGUAGE, zLocale, %MAX_PATH) sBuffer = zLocale & $SPC & lpUILanguageString & $CRLF FUNCTION = %TRUE 'To continue enumeration, the callback function should return TRUE. END FUNCTION '_________________________________________________________________ ' ' FUNCTION SpeakersMuteSelect '_________________________________________________________________ FUNCTION SpeakersMuteSelect AS LONG IF giSpeakers = 1 THEN IF giMasterSpeakersMuteLevel = 0 THEN MuteSpeakers ELSE UnMuteSpeakers END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION MicrophoneMuteSelect '_________________________________________________________________ FUNCTION MicrophoneMuteSelect AS LONG IF giMicrophone = 1 THEN IF giMasterMicrophoneMuteLevel = 0 THEN MuteMicrophone ELSE UnMuteMicrophone END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION GetVolumeSpeakers '_________________________________________________________________ FUNCTION GetVolumeSpeakers AS LONG LOCAL xhr AS LONG LOCAL fVolume AS SINGLE IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeSpeakers) THEN xhr = gpIAudioEndpointVolumeSpeakers.GetMasterVolumeLevelScalar(fVolume) IF FAILED(xhr) THEN ? "Unable to get scalar on default stereo speakers." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default Stereo Speakers volume scalar is " + STR$(fVolume) END IF giMasterSpeakersLevel = fVolume * 100 SendDlgItemMessageA (hDlg, %TrackbarVolSpeakers, %TBM_SETPOS, %TRUE, %TrackbarMax - fVolume * 100) SetDlgItemTextA (hDlg, %LabelVolSpeakers, FORMAT$(fVolume * 100, "##0")) END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION GetVolumeMicrophone '_________________________________________________________________ FUNCTION GetVolumeMicrophone() AS LONG LOCAL xhr AS LONG LOCAL fVolume AS SINGLE IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.GetMasterVolumeLevelScalar(fVolume) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on default microphone.") ? "Unable to get volume state on default microphone" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone volume get successfully!" END IF giMasterMicrophoneLevel = fVolume * 100 SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETPOS, %TRUE, %TrackbarMax - fVolume * 100) SetDlgItemTextA (hDlg, %LabelVolMicro, FORMAT$(fVolume * 100, "##0")) END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION GetVolumeMicrophoneBoost '_________________________________________________________________ FUNCTION GetVolumeMicrophoneBoost() AS LONG LOCAL xhr AS LONG LOCAL fVolume AS SINGLE IF giMicrophone = 1 THEN IF ISOBJECT(pIaudioVolumeLevel) THEN xhr = pIaudioVolumeLevel.GetLevel(0, fVolume) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on microphone boost.") ? "Unable to get volume state on microphone boost" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone boost volume get successful!" END IF giMasterMicroBoostLevel = fVolume SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, %TrackbarMaxBoost - fVolume/10) SetDlgItemTextA (hDlg, %LabelVolMicroBoost, FORMAT$(fVolume, "##0") & " dB") END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION SetVolumeSpeakers '_________________________________________________________________ FUNCTION SetVolumeSpeakers(BYVAL SpeakerScalar AS SINGLE) AS LONG LOCAL xhr AS LONG IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeSpeakers) THEN xhr = gpIAudioEndpointVolumeSpeakers.SetMasterVolumeLevelScalar(SpeakerScalar, g_guid_1_Context) 'BYVAL %NULL) 'BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to set scalar on default stereo speakers." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default Stereo Speakers volume set successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION SetVolumeMicrophone '_________________________________________________________________ FUNCTION SetVolumeMicrophone(BYVAL MicroScalar AS SINGLE) AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.SetMasterVolumeLevelScalar(MicroScalar, g_guid_2_Context) 'BYVAL %NULL) 'BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on default microphone.") ? "Unable to set volume state on default microphone" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone volume set successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION SetVolumeMicrophoneBoost '_________________________________________________________________ FUNCTION SetVolumeMicrophoneBoost(BYVAL MicroScalar AS SINGLE) AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(pIaudioVolumeLevel) THEN xhr = pIaudioVolumeLevel.SetLevel(0, MicroScalar, g_guid_3_Context) 'BYVAL %NULL) 'BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on microphone boost.") ? "Unable to set volume state on microphone boost" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone boost volume set successful!" END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' SUB SPEAKERS_UP '_________________________________________________________________ SUB SPEAKERS_UP CALL GetVolumeSpeakers IF giMasterSpeakersLevel < 100 THEN giMasterSpeakersLevel = giMasterSpeakersLevel + 1 CALL SetVolumeSpeakers(giMasterSpeakersLevel/ 100) CALL RefreshVolumeSpeakersTrackbarPos(giMasterSpeakersLevel/ 100) END IF END SUB '_________________________________________________________________ ' ' SUB SPEAKERS_DN '_________________________________________________________________ SUB SPEAKERS_DN CALL GetVolumeSpeakers IF giMasterSpeakersLevel > 0 THEN giMasterSpeakersLevel = giMasterSpeakersLevel - 1 CALL SetVolumeSpeakers(giMasterSpeakersLevel/ 100) CALL RefreshVolumeSpeakersTrackbarPos(giMasterSpeakersLevel/ 100) END IF END SUB '_________________________________________________________________ ' ' SUB MICROPHONE_UP '_________________________________________________________________ SUB MICROPHONE_UP CALL GetVolumeMicrophone IF giMasterMicrophoneLevel < 100 THEN giMasterMicrophoneLevel = giMasterMicrophoneLevel + 1 CALL SetVolumeMicrophone(giMasterMicrophoneLevel/ 100) CALL RefreshVolumeMicrophoneTrackbarPos(giMasterMicrophoneLevel/ 100) END IF END SUB '_________________________________________________________________ ' ' SUB MICROPHONE_DN '_________________________________________________________________ SUB MICROPHONE_DN CALL GetVolumeMicrophone IF giMasterMicrophoneLevel > 0 THEN giMasterMicrophoneLevel = giMasterMicrophoneLevel - 1 CALL SetVolumeMicrophone(giMasterMicrophoneLevel/ 100) CALL RefreshVolumeMicrophoneTrackbarPos(giMasterMicrophoneLevel/ 100) END IF END SUB '_________________________________________________________________ ' ' SUB MICROPHONE_BOOST_UP '_________________________________________________________________ SUB MICROPHONE_BOOST_UP CALL GetVolumeMicrophoneBoost IF giMasterMicroBoostLevel < 30 THEN giMasterMicroBoostLevel = giMasterMicroBoostLevel + 10 CALL SetVolumeMicrophoneBoost(giMasterMicroBoostLevel) CALL RefreshVolumeMicrophoneBoostTrackbarPos(giMasterMicroBoostLevel) 'workaround END IF END SUB '_________________________________________________________________ ' ' SUB MICROPHONE_BOOST_DN '_________________________________________________________________ SUB MICROPHONE_BOOST_DN CALL GetVolumeMicrophoneBoost IF giMasterMicroBoostLevel > 0 THEN giMasterMicroBoostLevel = giMasterMicroBoostLevel - 10 CALL SetVolumeMicrophoneBoost(giMasterMicroBoostLevel) CALL RefreshVolumeMicrophoneBoostTrackbarPos(giMasterMicroBoostLevel) 'workaround END IF END SUB '_________________________________________________________________ ' ' FUNCTION RefreshVolumeSpeakersTrackbarPos '_________________________________________________________________ FUNCTION RefreshVolumeSpeakersTrackbarPos(BYVAL MicroScalar1 AS SINGLE) AS LONG SendMessageA (hDlg, %WM_APP, %TrackbarVolSpeakers, MicroScalar1 * %TrackbarMax) END FUNCTION '_________________________________________________________________ ' ' FUNCTION RefreshVolumeMicrophoneTrackbarPos '_________________________________________________________________ FUNCTION RefreshVolumeMicrophoneTrackbarPos(BYVAL MicroScalar2 AS SINGLE) AS LONG SendMessageA (hDlg, %WM_APP, %TrackbarVolMicro, MicroScalar2 * %TrackbarMax) END FUNCTION '_________________________________________________________________ ' ' FUNCTION RefreshVolumeMicrophoneBoostTrackbarPos '_________________________________________________________________ FUNCTION RefreshVolumeMicrophoneBoostTrackbarPos(BYVAL MicroScalar3 AS SINGLE) AS LONG SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, %TrackbarMaxBoost - MicroScalar3/10) SetDlgItemTextA (hDlg, %LabelVolMicroBoost, FORMAT$(MicroScalar3, "##0") & " dB") END FUNCTION
Code:<GRAMMAR LANGID="409"> <!-- Created by James R Fritts on 2018-10-13 Extracted from xBot version 7 Last updated on: 2020-05-19 --> <RULE NAME="recStart" TOPLEVEL="ACTIVE"> <P>Recognition has started</P> </RULE> <RULE NAME="recStop" TOPLEVEL="ACTIVE"> <P>stop recognition</P> </RULE> <RULE NAME="mixCmd"> TOPLEVEL="ACTIVE"> <L> <!-- Mixer Command Functions --> <P>volume mixer</P> <P>recording mixer</P> </L> </RULE> <RULE NAME="spkrCmd" TOPLEVEL="ACTIVE"> <P>speakers</P> <RULEREF NAME="dirCmd"/> </RULE> <RULE NAME="microCmd" TOPLEVEL="ACTIVE"> <P>microphone</P> <RULEREF NAME="dirCmd"/> </RULE> <RULE NAME="boostCmd" TOPLEVEL="ACTIVE"> <P>boost</P> <RULEREF NAME="dirCmd"/> </RULE> <RULE NAME="cmdCtrl" TOPLEVEL="ACTIVE"> <P>jarvis</P> <O>please</O> <RULEREF NAME="endCmd"/> </RULE> <RULE NAME="pressCmd" TOPLEVEL="ACTIVE"> <O>press</O> <L> <RULEREF NAME="voiceCmd"/> </L> </RULE> <RULE NAME="endCmd"> <L> <P>get the time</P> <P>turn all lights on</P> <P>turn all lights off</P> </L> </RULE> <RULE NAME="dirCmd"> <L> <P>mute</P> <P>up</P> <P>plus</P> <P>increase</P> <P>down</P> <P>minus</P> <P>decrease</P> </L> </RULE> </GRAMMAR>
Last edited by Jim Fritts; 19 May 2020, 03:15 PM.
Leave a comment:
-
Another update...
PeakMeterThread new version
Now the timer can be deleted.
Code:'_________________________________________________________________ ' ' THREAD FUNCTION PeakMeterThread ' full time '_________________________________________________________________ THREAD FUNCTION PeakMeterThread(BYVAL yyy AS LONG) AS LONG DO WHILE GlobalVariableTestOn '// Update the peak meter in the dialog box. IF ISOBJECT(gpMeterInfo) THEN gpMeterInfo.GetPeakValue(PEAK) CONTROL SET TEXT hDlg, %IDC_PEAK_METER, USING$("##.#", PEAK * 100) CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETPOS, (PEAK * 100), 0 END IF SLEEP 10 IF GlobalVariableTest86 = 1 THEN GOTO LoopEnd SLEEP 20 LOOP LoopEnd: END FUNCTION
Leave a comment:
-
ExitHere: should me modified to this...
Code:ExitHere: CoTaskMemFree(pName) ppParts = NOTHING pConnTo = NOTHING pPartPrev = NOTHING pSelector = NOTHING FUNCTION = hr
Another issue:
The higher the microphone boost is set the more likely the program will not close correctly. This is because the speech recognition routine goes into saturation thinking the amplified background noise is something it should recognize so it expends more and more system resources to do just that.
The work around for this problem is this...
Drop the microphone boost level to 10 dB and
Stop the recognition.
Code:CASE %WM_CLOSE CALL SetVolumeMicrophoneBoost(1 * 10) '10 dB giStartStopRecognition = 2 giProgStat = 0
Last edited by Jim Fritts; 16 May 2020, 05:20 PM.
Leave a comment:
-
Changes:
Code:'SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, 10) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPAGESIZE,0, 10)
Code:'SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, 1) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPAGESIZE,0, 1)
Also added cleanup for callback methods which should be used during app shutdown
so that the OS mixer control doesn't experience a memory leak:
Code:'_________________________________________________________________ ' ' SUB UnRegisterSpeakerCallback '_________________________________________________________________ SUB UnRegisterSpeakerCallback LOCAL xhr AS LONG xhr = gpIAudioEndpointVolumeStereoSpeakers.UnRegisterControlChangeNotify( _ BYVAL ppNotify_1) 'IAudioEndpointVolumeCallback END SUB '_________________________________________________________________ ' ' SUB UnRegisterMicrophoneCallback '_________________________________________________________________ SUB UnRegisterMicrophoneCallback LOCAL xhr AS LONG xhr = gpIAudioEndpointVolumeMicrophone.UnRegisterControlChangeNotify( _ BYVAL ppNotify_2) 'IAudioEndpointVolumeCallback END SUB '_________________________________________________________________ ' ' SUB UnRegisterMicrophoneBoostCallback '_________________________________________________________________ SUB UnRegisterMicrophoneBoostCallback LOCAL xhr AS LONG xhr = pPartNext.UnRegisterControlChangeCallback( _ BYVAL ppNotify_3) 'IControlChangeNotify END SUB
Code:CASE %WM_DESTROY 'window is being destroyed 'after windows is removed from screen (children still exist) KillTimer (hDlg, %IDC_Timer0) CALL UnRegisterSpeakerCallback CALL UnRegisterMicrophoneCallback CALL UnRegisterMicrophoneBoostCallback pSelector = NOTHING gpIMMDeviceEnumMicrophone = NOTHING gpIMMDeviceMicrophone = NOTHING gpIAudioEndpointVolumeMicrophone = NOTHING gpMeterInfo = NOTHING pDeviceTopology = NOTHING pConnFrom = NOTHING pConnTo = NOTHING pPartPrev = NOTHING pPartNext = NOTHING ppParts = NOTHING pIaudioVolumeLevel = NOTHING PostQuitMessage 0 'If an application processes this message, it should return zero. FUNCTION = 0 EXIT FUNCTION
Leave a comment:
-
-
Version 2
Code:'Volume and mute control for Vista, Seven, Eight, and Ten. 'Callback functions will syncronize speaker volume and mute 'microphone volume and mute and microphone boost with other mixer controls. 'Based on work done by Pierre Bellisle. 'Works with PBWIN10.4 and J.Roca includes WINAPI_III_107. 'Released to the public on 2020 MAY 12. #COMPILE EXE "VolumeWithCallbackVistaPlus.exe" #DIM ALL #REGISTER NONE $CandCGrammar = "JARVIS.xml" 'unused functions 'STEREOSPEAKERSMUTESELECT 'MICROPHONEMUTESELECT 'PUTQUESTIONMARKONMARQUE GLOBAL g_guid_1_Context AS GUID 'speakers volume/mute-unmute context GLOBAL g_guid_2_Context AS GUID 'microphone volume/mute-unmute context GLOBAL g_guid_3_Context AS GUID 'microphone boost volume context (currently not used) 'SAPI GLOBAL InProcEvents AS ISpeechRecoContextEventsImplemented 'SAPI interface GLOBAL giRunningRecogProcess AS LONG 'SAPI GLOBAL RecognitionStatus AS LONG 'SAPI GLOBAL giStartStopRecognition AS LONG 'SAPI GLOBAL oRecoContext AS ISpeechRecoContext 'SAPI GLOBAL oRecognizer AS ISpeechRecognizer 'SAPI GLOBAL oMyGrammar AS ISpeechRecoGrammar 'SAPI GLOBAL oCategory AS ISpeechObjectTokenCategory 'SAPI GLOBAL oToken AS ISpeechObjectToken 'SAPI GLOBAL giCCGrammarLoaded AS LONG 'SAPI GLOBAL gsBannerDictation AS STRING 'SAPI GLOBAL gsBannerListen AS STRING 'SAPI GLOBAL giProcessingRecog AS LONG 'SAPI GLOBAL giRecogNotUnderstood AS LONG 'SAPI GLOBAL MyDataX AS STRING 'SAPI contains the recognized phrase 'END SAPI GLOBAL hDlg AS DWORD GLOBAL giProgStat AS LONG GLOBAL VistaPlus AS LONG 'Vista to 10 GLOBAL sBuffer AS STRING GLOBAL gsMasterVolumeIsChangeable AS STRING '"YES" OR "NO" GLOBAL gpIMMDeviceEnumStereoSpeakers AS IMMDeviceEnumerator GLOBAL gpIMMDeviceStereoSpeakers AS IMMDevice GLOBAL gpIAudioEndpointVolumeStereoSpeakers AS IAudioEndpointVolume GLOBAL giStereoSpeakers AS LONG ' default stereo speaker availablility yes = 1, no = 0 GLOBAL giStereoSpeakersHr AS LONG GLOBAL giMasterStereoSpeakersLevel AS LONG GLOBAL gsTheStereoSpeakersName AS STRING GLOBAL giMasterStereoSpeakerMuteLevel AS LONG GLOBAL giSpeakersMute AS LONG GLOBAL gpIMMDeviceEnumMicrophone AS IMMDeviceEnumerator GLOBAL gpIMMDeviceMicrophone AS IMMDevice GLOBAL gpIAudioEndpointVolumeMicrophone AS IAudioEndpointVolume GLOBAL giMicrophone AS LONG ' default microphone availablility yes = 1, no = 0 GLOBAL giMicrophoneHr AS LONG GLOBAL giMasterMicrophoneLevel AS LONG GLOBAL gsTheMicrophoneName AS STRING GLOBAL giMasterMicrophoneMuteLevel AS LONG GLOBAL giMicrophoneMute AS LONG GLOBAL giMasterMicroBoostLevel AS LONG GLOBAL gpIMMNotificationClientMicrophone AS IMMNotificationClient GLOBAL gpMeterInfo AS IAudioMeterInformation GLOBAL pDeviceTopology AS IDeviceTopology GLOBAL pConnFrom AS IConnector GLOBAL pConnTo AS IConnector GLOBAL pPartPrev AS IPart GLOBAL pPartNext AS IPart GLOBAL ppParts AS IPartsList GLOBAL pIaudioVolumeLevel AS IAudioVolumeLevel GLOBAL pSelector AS IAudioInputSelector GLOBAL ppNotify_1 AS IAudioEndpointVolumeCallback 'speakers GLOBAL ppNotify_2 AS IAudioEndpointVolumeCallback 'microphone GLOBAL ppNotify_3 AS IControlChangeNotify 'microphone boost GLOBAL PEAK AS SINGLE 'for peak meter GLOBAL SCALER_MB AS SINGLE GLOBAL pDevId AS WSTRINGZ PTR GLOBAL devName AS WSTRING GLOBAL pName AS WSTRINGZ PTR 'LPWSTR pName GLOBAL giMicroMute AS LONG 'Tracks Microphone Mute status GLOBAL pflow AS LONG 'DataFlow pflow GLOBAL pPartType AS LONG 'PartType GLOBAL bConnected AS LONG 'BOOL bConnected GLOBAL connType AS LONG 'ConnectorType GLOBAL ComponentName AS WSTRINGZ * 255 GLOBAL XFill AS STRING 'used to post text to clipboard GLOBAL giPRTDMessage AS LONG GLOBAL giPumpingMessages AS LONG GLOBAL CLSID_MMDeviceEnumerator AS GUID GLOBAL IID_IMMDeviceEnumerator AS GUID 'new GLOBAL IID_IPart AS GUID GLOBAL IID_IAudioVolumeLevel AS GUID GLOBAL IID_IConnector AS GUID GLOBAL IID_IAudioInputSelector AS GUID GLOBAL IID_IAudioEndpointVolume AS GUID GLOBAL IID_IDeviceTopology AS GUID GLOBAL IID_IAudioMeterInformation AS GUID GLOBAL IID_IAudioEndpointVolumeCallback AS GUID 'new GLOBAL IID_IControlChangeNotify AS GUID 'new $AppName = "Audio with Callback" %LabelMinSpeaker = 101 'MIN %LabelMaxSpeaker = 102 'MAX %LabelVolSpeaker = 103 %LabelInfoSpeaker = 104 %LabelOnOffSpeaker = 105 %TrackbarVolSpeaker = 201 %CheckboxVolOnOffSpeaker = 301 %ButtonSndVolExeSpeaker = 401 %LabelMinMicro = 1101 'MIN %LabelMaxMicro = 1102 'MAX %LabelVolMicro = 1103 %LabelInfoMicro = 1104 %LabelOnOffMicro = 1105 %TrackbarVolMicro = 1201 %CheckboxVolOnOffMicro = 1301 '%ButtonSndVolExeMicro = 1401 'not used %LabelMinMicroBoost = 2101 'MIN %LabelMaxMicroBoost = 2102 'MAX %LabelVolMicroBoost = 2103 %LabelInfoMicroBoost = 2104 '%LabelOnOffMicroBoost = 2105 'not used %TrackbarVolMicroBoost = 2201 '%CheckboxVolOnOffMicroBoost = 2301 'not used '%ButtonSndVolExeMicroBoost = 2401 'not used %ID_VOLUME = 1002 %IDC_PEAK_METER = 1003 %IDC_Timer0 = 1004 %TrackbarMax = 100 'for speaker and microphone trackbar %TrackbarMaxBoost = 3 'for microphone boost trackbar %ID_RefreshBanner = 5000 'SAPI '#INCLUDE ONCE "MB_API_A.inc" 'WHEN USED {6,735 total lines} COMPILE TIME 0.1 seconds 'OR THESE #INCLUDE ONCE "Win32Api.inc" 'WHEN USED {289,533 total lines} COMPILE TIME 1.5 seconds #INCLUDE ONCE "CommCtrl.inc" 'Needed if manifest and WinXP #INCLUDE ONCE "mmdeviceapi.inc" 'used for WASAPI #INCLUDE ONCE "devpkey.inc" 'used for WASAPI #INCLUDE ONCE "propvarutil.inc" 'used for WASAPI #INCLUDE ONCE "endpointvolume.inc" 'used for WASAPI #INCLUDE ONCE "propsys.inc" 'used for WASAPI #INCLUDE ONCE "sapi.inc" 'used for SAPI #INCLUDE ONCE "WinNls.inc" 'User language ' ######################################################################################## ' Class CISpeechRecoContextEvents SAPI ' Interface name = _ISpeechRecoContextEvents ' IID = {7B8FCB42-0E9D-4F00-A048-7B04D6179D3D} ' Attributes = 4096 [&H1000] [Dispatchable] ' ######################################################################################## CLASS CISpeechRecoContextEventsImplemented GUID$("{5B344ADB-C0C7-4B5F-8046-7D2DB91A1D75}") AS EVENT INTERFACE ISpeechRecoContextEventsImplemented GUID$("{7B8FCB42-0E9D-4F00-A048-7B04D6179D3D}") AS EVENT INHERIT IDISPATCH ' ===================================================================================== METHOD Recognition <7> ( _ BYVAL StreamNumber AS LONG _ ' __in long StreamNumber , BYVAL StreamPosition AS VARIANT _ ' __in VARIANT StreamPosition , BYVAL RecognitionType AS LONG _ ' __in SpeechRecognitionType RecognitionType , BYVAL Result AS ISpeechRecoResult _ ' __in ISpeechRecoResult *Result ) ' void LOCAL pDisp AS IDISPATCH LOCAL bstrText AS WSTRING IF ISNOTHING(Result) THEN EXIT METHOD pDisp = Result OBJECT CALL pDisp.PhraseInfo.GetText TO bstrText IF OBJRESULT THEN ? "GetText error: " & OBJRESULT$ ELSE giRecogNotUnderstood = 0 MyDataX = TRIM$(bstrText) END IF END METHOD ' ===================================================================================== ' ===================================================================================== METHOD FalseRecognition <11> ( _ BYVAL StreamNumber AS LONG _ ' __in long StreamNumber , BYVAL StreamPosition AS VARIANT _ ' __in VARIANT StreamPosition , BYVAL Result AS ISpeechRecoResult _ ' __in ISpeechRecoResult *Result ) ' void LOCAL pDisp AS IDISPATCH LOCAL bstrText AS WSTRING IF ISNOTHING(Result) THEN EXIT METHOD END IF pDisp = Result OBJECT CALL pDisp.PhraseInfo.GetText TO bstrText IF OBJRESULT THEN ? "GetText error: " & OBJRESULT$ ELSE giRecogNotUnderstood = 1 MyDataX = "What was that?" END IF END METHOD END INTERFACE END CLASS ' ######################################################################################## ' Class CIAudioEndpointVolumeCallback ' Interface name = _IAudioEndpointVolumeCallback ' IID = {657804FA-D6AD-4496-8A60-352752AF4F89} ' Inherited interface = IUnknown ' ######################################################################################## CLASS CIAudioEndpointVolumeCallback_1 AS COM INTERFACE IAudioEndpointVolumeCallback $IID_IAudioEndpointVolumeCallback INHERIT IUNKNOWN ' ===================================================================================== METHOD OnNotify ( _ ' VTable offset = 12 BYREF pNotify_1 AS AUDIO_VOLUME_NOTIFICATION_DATA _ ' __in PAUDIO_VOLUME_NOTIFICATION_DATA pNotify ) AS LONG ' HRESULT 'Method-Callback that receives a pointer to the sample buffer. 'Callback method for endpoint-volume-change notifications. IF VARPTR(pNotify_1) = %NULL THEN METHOD = %E_INVALIDARG ELSE IF (hDlg <> %NULL) THEN IF (pNotify_1.guidEventContext <> g_guid_1_Context) THEN PostMessageA (hDlg, %WM_APP, %CheckboxVolOnOffSpeaker, pNotify_1.bMuted) PostMessageA (hDlg, %WM_APP, %TrackbarVolSpeaker, pNotify_1.fMasterVolume * %TrackbarMax) END IF END IF METHOD = %S_OK END IF END METHOD ' ===================================================================================== END INTERFACE END CLASS ' ######################################################################################## ' Class CIAudioEndpointVolumeCallback ' Interface name = _IAudioEndpointVolumeCallback ' IID = {657804FA-D6AD-4496-8A60-352752AF4F89} ' Inherited interface = IUnknown ' ######################################################################################## CLASS CIAudioEndpointVolumeCallback_2 AS COM INTERFACE IAudioEndpointVolumeCallback $IID_IAudioEndpointVolumeCallback INHERIT IUNKNOWN ' ===================================================================================== METHOD OnNotify ( _ ' VTable offset = 12 BYREF pNotify_2 AS AUDIO_VOLUME_NOTIFICATION_DATA _ ' __in PAUDIO_VOLUME_NOTIFICATION_DATA pNotify ) AS LONG ' HRESULT 'Method-Callback that receives a pointer to the sample buffer. 'Callback method for endpoint-volume-change notifications. IF VARPTR(pNotify_2) = %NULL THEN METHOD = %E_INVALIDARG ELSE IF (hDlg <> %NULL) THEN IF (pNotify_2.guidEventContext <> g_guid_2_Context) THEN 'Post notification to main dialog PostMessageA (hDlg, %WM_APP, %CheckboxVolOnOffMicro, pNotify_2.bMuted) PostMessageA (hDlg, %WM_APP, %TrackbarVolMicro, pNotify_2.fMasterVolume * %TrackbarMax) END IF END IF METHOD = %S_OK END IF END METHOD ' ===================================================================================== END INTERFACE END CLASS ' ######################################################################################## ' Class CIAudioEndpointVolumeCallback CURRENTLY NOT USED ' Interface name = _IAudioEndpointVolumeCallback ' IID = {657804FA-D6AD-4496-8A60-352752AF4F89} ' Inherited interface = IUnknown ' ######################################################################################## CLASS CIAudioEndpointVolumeCallback_3 AS COM INTERFACE IAudioEndpointVolumeCallback $IID_IAudioEndpointVolumeCallback INHERIT IUNKNOWN ' ===================================================================================== METHOD OnNotify ( _ ' VTable offset = 12 BYREF pNotify_3 AS AUDIO_VOLUME_NOTIFICATION_DATA _ ' __in PAUDIO_VOLUME_NOTIFICATION_DATA pNotify ) AS LONG ' HRESULT 'Method-Callback that receives a pointer to the sample buffer. 'Callback method for endpoint-volume-change notifications. IF VARPTR(pNotify_3) = %NULL THEN METHOD = %E_INVALIDARG ELSE IF (hDlg <> %NULL) THEN IF (pNotify_3.guidEventContext <> g_guid_3_Context) THEN 'Post notification to main dialog 'PostMessageA (hDlg, %WM_APP, %TrackbarVolMicroBoost, pNotify_3.fMasterVolume * %TrackbarMaxBoost) END IF END IF METHOD = %S_OK END IF END METHOD ' ===================================================================================== END INTERFACE END CLASS ' ######################################################################################## ' Class CIControlChangeNotify ' Interface name = IControlChangeNotify ' IID = A09513ED-C709-4D21-BD7B-5F34C47F3947 ' Inherited interface = IUnknown ' ######################################################################################## CLASS CIControlChangeNotify AS COM INTERFACE IControlChangeNotify $IID_IControlChangeNotify INHERIT IUNKNOWN ' ===================================================================================== METHOD OnNotify ( _ ' VTable offset = 12 BYVAL dwSenderProcessId AS DWORD _ ' __in DWORD dwSenderProcessId , BYREF pguidEventContext AS GUID _ ' __in LPCGUID pguidEventContext ) AS LONG ' HRESULT ' ===================================================================================== IF (hDlg <> %NULL) THEN IF (pguidEventContext <> g_guid_3_Context) THEN 'Get the microphone boost values CALL GetVolumeMicrophoneBoost END IF END IF METHOD = %S_OK END METHOD END INTERFACE END CLASS '_____________________________________________________________________________ ' SUB IconSet_1(iconOn AS LONG) DIM hIcon(0 TO 3) AS STATIC DWORD LOCAL Looper AS LONG SELECT CASE iconOn CASE 0, 1 'Set "disable icon" or "enable icon" on dialog ans static SetClassLongA (hDlg, %GCL_HICONSM, hIcon(iconOn)) SendMessageA (hDlg, %WM_SETICON, %ICON_SMALL, hIcon(iconOn)) SendDlgItemMessageA (hDlg, %LabelOnOffSpeaker, %STM_SETIMAGE, %IMAGE_ICON, hIcon(iconOn + 02)) CASE -2 'Get "disable icon" and "enable icon" from appropriate files IF VistaPlus THEN 'Vista to 10 ExtractIconExA ("SndVol.exe", 1, BYVAL VARPTR(hIcon(3)), BYVAL VARPTR(hIcon(1)), 1) 'Vista to 10, Enable-Big-Small ExtractIconExA ("SndVol.exe", 2, BYVAL VARPTR(hIcon(2)), BYVAL VARPTR(hIcon(0)), 1) 'Vista to 10, Disable-Big-Small ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF CASE -1 'Release memory clean-up FOR Looper = 0 TO 3 DestroyIcon (hIcon(Looper)) NEXT END SELECT END SUB ' ======================================================================================== ' Helper function to retrieve the friendly name of the audio device. ' ======================================================================================== FUNCTION AfxGetDeviceName (BYVAL pDev AS IMMDevice) AS WSTRING LOCAL hr AS LONG LOCAL pPropStore AS IPropertyStore hr = pDev.OpenPropertyStore(%STGM_READ, pPropStore) IF FAILED(hr) THEN EXIT FUNCTION LOCAL friendlyName AS PROPVARIANT PropVariantInit(friendlyName) hr = pPropStore.getValue(DEVPKEY_Device_FriendlyName, friendlyName) IF FAILED(hr) THEN EXIT FUNCTION LOCAL wszDevName AS WSTRINGZ * 128 PropVariantToString(friendlyName, wszDevName, 128) FUNCTION = wszDevName PropVariantClear(friendlyName) END FUNCTION ' ======================================================================================== FUNCTION StereoSpeakersMuteSelect AS LONG IF giStereoSpeakers = 1 THEN IF giSpeakersMute = 0 THEN MuteStereoSpeakers ELSE UnMuteStereoSpeakers END IF END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION SetVolumeCallback AS LONG 'Pointer to the IAudioEndpointVolumeCallback interface that the client 'is registering for notification callbacks. If the 'RegisterControlChangeNotify method succeeds, it calls the AddRef 'method on the client's IAudioEndpointVolumeCallback interface. LOCAL xhr AS LONG IF ISOBJECT(gpIAudioEndpointVolumeStereoSpeakers) THEN xhr = CoCreateGuid (g_guid_1_Context) LET ppNotify_1 = CLASS "CIAudioEndpointVolumeCallback_1" xhr = gpIAudioEndpointVolumeStereoSpeakers.RegisterControlChangeNotify(BYVAL ppNotify_1) 'IAudioEndpointVolumeCallback IF FAILED(xhr) THEN ? "Unable to set stereo speaker callback." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default stereo speaker callback." END IF END IF FUNCTION = 1 END FUNCTION 'When notifications are no longer needed, the client can call the 'IAudioEndpointVolume.UnregisterControlChangeNotify method to terminate the notifications. ' ======================================================================================== FUNCTION GetMuteStereoSpeakers AS LONG LOCAL xhr AS LONG LOCAL fMute AS LONG IF ISOBJECT(gpIAudioEndpointVolumeStereoSpeakers) THEN xhr = gpIAudioEndpointVolumeStereoSpeakers.GetMute(fMute) IF FAILED(xhr) THEN ? "Unable to get stereo speaker mute level." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default stereo speaker mute level is " + STR$(fMute) END IF END IF giMasterStereoSpeakerMuteLevel = fMute SELECT CASE fMute CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeaker), %BM_SETCHECK, %BST_CHECKED, 0) IconSet_1(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeaker), %BM_SETCHECK, %BST_UNCHECKED, 0) IconSet_1(1) END SELECT FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION MuteStereoSpeakers AS LONG LOCAL xhr AS LONG IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeStereoSpeakers) THEN xhr = gpIAudioEndpointVolumeStereoSpeakers.SetMute(1, g_guid_1_Context) 'BYVAL %NULL) '%TRUE BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to mute default stereo speakers." ELSE '? "Default StereoSpeakers muted successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION UnMuteStereoSpeakers AS LONG LOCAL xhr AS LONG IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeStereoSpeakers) THEN xhr = gpIAudioEndpointVolumeStereoSpeakers.SetMute(0, g_guid_1_Context) 'BYVAL %NULL) '%FALSE BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to unmute default stereo speakers." ELSE '? "Default StereoSpeakers unmuted successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION GetVolumeStereoSpeakers AS LONG LOCAL xhr AS LONG LOCAL fVolume AS SINGLE IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeStereoSpeakers) THEN xhr = gpIAudioEndpointVolumeStereoSpeakers.GetMasterVolumeLevelScalar(fVolume) IF FAILED(xhr) THEN ? "Unable to get scalar on default stereo speakers." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default Stereo Speakers volume scalar is " + STR$(fVolume) END IF END IF '? "Speaker Volume=" & STR$(fVolume) giMasterStereoSpeakersLevel = fVolume * 100 '? STR$(giMasterStereoSpeakersLevel) SendDlgItemMessageA (hDlg, %TrackbarVolSpeaker, %TBM_SETPOS, %TRUE, %TrackbarMax - fVolume * 100) SetDlgItemTextA (hDlg, %LabelVolSpeaker, FORMAT$(fVolume * 100, "##0")) END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION SetVolumeStereoSpeakers(BYVAL SpeakerScalar AS SINGLE) AS LONG LOCAL xhr AS LONG IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeStereoSpeakers) THEN xhr = gpIAudioEndpointVolumeStereoSpeakers.SetMasterVolumeLevelScalar(SpeakerScalar, g_guid_1_Context) 'BYVAL %NULL) 'BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to set scalar on default stereo speakers." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default Stereo Speakers volume set successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION StereoSpeakersCheck '_________________________________________________________________ FUNCTION StereoSpeakersCheck AS LONG LOCAL xhr AS LONG LOCAL pDevId AS WSTRINGZ PTR LOCAL devName AS WSTRING gpIMMDeviceEnumStereoSpeakers = NEWCOM CLSID CLSID_MMDeviceEnumerator IF ISNOTHING(gpIMMDeviceEnumStereoSpeakers) THEN EXIT FUNCTION ' // Enumerate the audio endpoints of interest (in this case audio capture endpoints) ' // The flags that can be used are %EDataFlow_eRender (for audio output endpoints), ' // %EDataFlow_eCapture (for audio capture endpoints) or %EDataFlow_eAll (for all audio endpoints) ' // %EDataFlow_eCapture (for audio capture endpoints), ' // %EDataFlow_eAll (for all audio endpoints) ' // %ERole_eConsole = Games, system notification sounds, and voice commands. ' // %ERole_eMultimedia = Music, movies, narration, and live music recording. ' // %ERole_eCommunications = Voice communications (talking to another person). giStereoSpeakersHr = gpIMMDeviceEnumStereoSpeakers.GetDefaultAudioEndpoint( _ %EDataFlow_eRender, _ %ERole_eMultimedia, _ gpIMMDeviceStereoSpeakers) 'IMMDevice IF FAILED(giStereoSpeakersHr) THEN 'CALL SHOW_NOTES("Unable to find default speakers.") ? "Unable to find the default Stereo Speakers" FUNCTION = 0 EXIT FUNCTION END IF xhr = gpIMMDeviceStereoSpeakers.Activate( _ IID_IAudioEndpointVolume, _ %CLSCTX_INPROC_SERVER, _ BYVAL %NULL, _ gpIAudioEndpointVolumeStereoSpeakers) 'IAudioEndpointVolume IF FAILED(xhr) THEN 'CALL SHOW_NOTES("Unable to activate default speakers.") ? "Unable to activate default Stereo Speakers" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default Stereo Speakers activated successfully!" ' // Get the device identifier xhr = gpIMMDeviceStereoSpeakers.GetId(pDevId) IF pDevId THEN ' "Device id = " & @pDevId CoTaskMemFree(pDevId) END IF ' // Get the device name gsTheStereoSpeakersName = AfxGetDeviceName (gpIMMDeviceStereoSpeakers) 'IMMDevice END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION MicrophoneCheck new 2020 MAY 06 new '_________________________________________________________________ FUNCTION MicrophoneCheck AS LONG LOCAL xhr AS LONG LOCAL fMinDb AS SINGLE 'float fMinDb LOCAL fMaxDb AS SINGLE 'float fMaxDb LOCAL fStepDb AS SINGLE 'float fStepDb LOCAL pfCurrentDb AS SINGLE 'float pfCurrentDb ' Get enumerator for audio endpoint devices. gpIMMDeviceEnumMicrophone = NEWCOM CLSID CLSID_MMDeviceEnumerator IF ISNOTHING(gpIMMDeviceEnumMicrophone) THEN ? "Unable to create audio device enumerator." FUNCTION = 0 EXIT FUNCTION END IF ' // Enumerate the audio endpoints of interest (in this case audio capture endpoints) ' // The flags that can be used are: ' // %EDataFlow_eRender (for audio output endpoints), ' // %EDataFlow_eCapture (for audio capture endpoints), ' // %EDataFlow_eAll (for all audio endpoints) ' // %ERole_eConsole = Games, system notification sounds, and voice commands. ' // %ERole_eMultimedia = Music, movies, narration, and live music recording. ' // %ERole_eCommunications = Voice communications (talking to another person). '%DEVICE_STATE_ACTIVE giMicrophoneHr = gpIMMDeviceEnumMicrophone.GetDefaultAudioEndpoint(%EDataFlow_eCapture, %ERole_eConsole, gpIMMDeviceMicrophone) IF FAILED(giMicrophoneHr) THEN ? "Unable to find default microphone device." FUNCTION = 0 EXIT FUNCTION END IF xhr = gpIMMDeviceMicrophone.Activate( _ IID_IAudioEndpointVolume, _ %CLSCTX_INPROC_SERVER, _ BYVAL %NULL, _ gpIAudioEndpointVolumeMicrophone) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to activate a microphone.") ? "Unable to activate default microphone" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone activated successfully!" ' // Get the device identifier xhr = gpIMMDeviceMicrophone.GetId(pDevId) IF pDevId THEN XFill = "Device id = " & @pDevId 'Device id = {0.0.1.00000000}.{be4cea6b-aba4-4420-8e08-dbfb7a6be10c} 'call COPY_TO_CLIPBOARD CoTaskMemFree(pDevId) END IF ' // Get the device name gsTheMicrophoneName = AfxGetDeviceName(gpIMMDeviceMicrophone) '? gsTheMicrophoneName 'Get the endpoint device's IDeviceTopology interface. xhr = gpIMMDeviceMicrophone.Activate( _ IID_IDeviceTopology, _ %CLSCTX_ALL, _ BYVAL %NULL, _ pDeviceTopology) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get microphone topology.") ? "Unable to get microphone topology." FUNCTION = 0 EXIT FUNCTION END IF 'The device topology for an endpoint device always 'contains just one connector (connector number 0). xhr = pDeviceTopology.GetConnector(0, pConnFrom) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get the connector info.") ? "Unable to get the connector info." FUNCTION = 0 EXIT FUNCTION END IF pDeviceTopology = NOTHING 'Make sure that this is a capture device. xhr = pConnFrom.GetDataFlow(pflow) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get connector flow data.") ? "Unable to get connector flow data." FUNCTION = 0 EXIT FUNCTION ELSE 'For example, a typical rendering device on an adapter has a connector 'with data-flow direction "In" through which the Windows audio engine 'streams PCM data into the device. The same device has a connector with 'data-flow direction "Out" through which the device transmits an audio 'signal to speakers or headphones. '%DataFlow_In = 0 Input stream. The audio stream flows into the device through the connector. '%DataFlow_Out = 1 Output stream. The audio stream flows out of the device through the connector. SELECT CASE pFlow CASE 0 'In 'Error -- this is a rendering device. 'EXIT_ON_ERROR(xhr = %AUDCLNT_E_WRONG_ENDPOINT_TYPE) 'CALL SHOW_NOTES_NO_WAIT("Error! The connector flow data was wrong.") ? "Error! The connector flow data was wrong." FUNCTION = 0 EXIT FUNCTION CASE 1 'Out '? "DataFlow is out stream." END SELECT END IF '-------------------------------------- 'Computer\HKEY_CURRENT_USER\Control Panel\International\User Profile\en-US (if exists)0x00000001 (1) 'Name 0409:00000409 'Type: REG_DWORD 'Data: 0x00000001 (1) LOCAL dwReserved AS DWORD LOCAL MyVal AS DWORD LOCAL zLocale AS ASCIIZ * %MAX_PATH IF EnumUILanguagesA (CODEPTR(EnumUILanguagesCB()), dwReserved, MyVal) THEN 'If the function succeeds, the return value is TRUE. 'let pass ELSE ? "Error determining language to support" END IF REPLACE "English 0409" WITH "en-US" IN sBuffer 'windows 10 REPLACE "English 0009" WITH "en" IN sBuffer 'windows 7 REPLACE "French 040C" WITH "fr-FR" IN sBuffer 'windows 10 REPLACE "French 000C" WITH "fr" IN sBuffer 'windows 7 IF INSTR(sBuffer, "fr") THEN ComponentName = "Ampli Microphone" 'french ELSE ComponentName = "Microphone Boost" 'english END IF '-------------------------------------- CALL SelectCaptureDevice pConnFrom = NOTHING '\\\\\\\\\\\\\\\ 'Get the endpoint device's IAudioMeterInformation interface. xhr = gpIMMDeviceMicrophone.Activate( _ IID_IAudioMeterInformation, _ %CLSCTX_ALL, _ BYVAL %NULL, _ gpMeterInfo) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get peak meter info.") ? "Unable to get peak meter info." FUNCTION = 0 EXIT FUNCTION END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION SetVolumeMicrophone '_________________________________________________________________ FUNCTION SetVolumeMicrophone(BYVAL MicroScalar AS SINGLE) AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.SetMasterVolumeLevelScalar(MicroScalar, g_guid_2_Context) 'BYVAL %NULL) 'BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on default microphone.") ? "Unable to set volume state on default microphone" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone volume set successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION RefreshVolumeTrackbarPos '_________________________________________________________________ FUNCTION RefreshVolumeTrackbarPos(BYVAL MicroScalar AS SINGLE) AS LONG giMasterMicrophoneLevel = MicroScalar * 100 '? STR$(giMasterMicrophoneLevel) SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETPOS, %TRUE, %TrackbarMax - MicroScalar * 100) SetDlgItemTextA (hDlg, %LabelVolMicro, FORMAT$(MicroScalar * 100, "##0")) END FUNCTION '_________________________________________________________________ ' ' FUNCTION GetVolumeMicrophone '_________________________________________________________________ FUNCTION GetVolumeMicrophone() AS LONG LOCAL xhr AS LONG LOCAL fVolume AS SINGLE IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.GetMasterVolumeLevelScalar(fVolume) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on default microphone.") ? "Unable to get volume state on default microphone" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone volume get successfully!" END IF '? "Microphone Volume=" & STR$(fVolume) giMasterMicrophoneLevel = fVolume * 100 '? STR$(giMasterMicrophoneLevel) SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETPOS, %TRUE, %TrackbarMax - fVolume * 100) SetDlgItemTextA (hDlg, %LabelVolMicro, FORMAT$(fVolume * 100, "##0")) END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION GetMuteMicrophone '_________________________________________________________________ FUNCTION GetMuteMicrophone AS LONG LOCAL xhr AS LONG LOCAL fMute AS LONG IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.GetMute(fMute) IF FAILED(xhr) THEN ? "Unable to get microphone mute level." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default microphone mute level is " + STR$(fMute) END IF END IF giMasterMicrophoneMuteLevel = fMute SELECT CASE fMute CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_CHECKED, 0) 'IconSet_2(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_UNCHECKED, 0) 'IconSet_2(1) END SELECT FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION MuteMicrophone '_________________________________________________________________ FUNCTION MuteMicrophone AS LONG LOCAL xhr AS LONG IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.SetMute(1, g_guid_2_Context) '%TRUE, BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to mute default microphone." '? "Unable to set mute state on default microphone" ELSE '? "Default microphone muted successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION UnMuteMicrophone '_________________________________________________________________ FUNCTION UnMuteMicrophone AS LONG LOCAL xhr AS LONG IF gsMasterVolumeIsChangeable = "YES" THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = gpIAudioEndpointVolumeMicrophone.SetMute(0, g_guid_2_Context) '%FALSE, BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN ? "Unable to unmute default microphone." '? "Unable to set unmute state on default microphone" ELSE '? "Default microphone unmuted successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION MicrophoneMuteSelect '_________________________________________________________________ FUNCTION MicrophoneMuteSelect AS LONG IF giMicrophone = 1 THEN IF giMicrophoneMute = 0 THEN MuteMicrophone ELSE UnMuteMicrophone END IF END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION SetMicrophoneCallback AS LONG 'Pointer to the IAudioEndpointVolumeCallback interface that the client 'is registering for notification callbacks. If the 'RegisterControlChangeNotify method succeeds, it calls the AddRef 'method on the client's IAudioEndpointVolumeCallback interface. LOCAL xhr AS LONG IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN xhr = CoCreateGuid (g_guid_2_Context) LET ppNotify_2 = CLASS "CIAudioEndpointVolumeCallback_2" xhr = gpIAudioEndpointVolumeMicrophone.RegisterControlChangeNotify(BYVAL ppNotify_2) 'IAudioEndpointVolumeCallback IF FAILED(xhr) THEN ? "Unable to set microphone callback." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default microphone callback." END IF END IF FUNCTION = 1 END FUNCTION 'MICROPHONE BOOST '_________________________________________________________________ ' ' FUNCTION GetVolumeMicrophoneBoost '_________________________________________________________________ FUNCTION GetVolumeMicrophoneBoost() AS LONG LOCAL xhr AS LONG LOCAL fVolume AS SINGLE IF giMicrophone = 1 THEN IF ISOBJECT(pIaudioVolumeLevel) THEN xhr = pIaudioVolumeLevel.GetLevel(0, fVolume) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on microphone boost.") ? "Unable to get volume state on microphone boost" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone boost volume get successful!" END IF giMasterMicroBoostLevel = fVolume '? "Microphone Boost Volume=" & STR$(fVolume) '? str$(fVolume/10) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, %TrackbarMaxBoost - fVolume/10) SetDlgItemTextA (hDlg, %LabelVolMicroBoost, FORMAT$(fVolume, "##0") & " dB") END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION SetVolumeMicrophoneBoost '_________________________________________________________________ FUNCTION SetVolumeMicrophoneBoost(BYVAL MicroScalar AS SINGLE) AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(pIaudioVolumeLevel) THEN xhr = pIaudioVolumeLevel.SetLevel(0, MicroScalar, g_guid_3_Context) 'BYVAL %NULL) 'BYREF pguidEventContext AS GUID IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on microphone boost.") ? "Unable to set volume state on microphone boost" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone boost volume set successful!" END IF END IF END IF FUNCTION = 1 END FUNCTION ' ======================================================================================== FUNCTION SetMicrophoneBoostCallback AS LONG LOCAL xhr AS LONG IF ISOBJECT(pPartNext) THEN xhr = CoCreateGuid (g_guid_3_Context) LET ppNotify_3 = CLASS "CIControlChangeNotify" xhr = pPartNext.RegisterControlChangeCallback( _ IID_IAudioVolumeLevel, _ BYVAL ppNotify_3) IF FAILED(xhr) THEN ? "Unable to set microphone boost callback." FUNCTION = 0 EXIT FUNCTION ELSE '? "Default microphone boost callback." END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION GlobalVariableTest86 VER4 '_________________________________________________________________ FUNCTION GlobalVariableTest86() AS LONG IF giProgStat = 0 THEN FUNCTION = 1 END IF END FUNCTION '_________________________________________________________________ ' ' FUNCTION GlobalVariableTestOn VER4 '_________________________________________________________________ FUNCTION GlobalVariableTestOn() AS LONG IF giProgStat = 1 THEN FUNCTION = 1 END IF END FUNCTION '_________________________________________________________________ ' ' Processes pending Windows messages. VER4 ' Call this procedure if you are performing a tight ' FOR/NEXT or DO/LOOP and need to allow ' your application to be responsive to user input. ' Modified version of AfxPumpMessages '_________________________________________________________________ SUB MyPumpMessages(BYVAL xTimes AS LONG) EXPORT '///////////////////////////////////////////////////////////// 'Do not want to remove the WM_QUIT message from message que. IF GlobalVariableTest86 = 1 THEN EXIT SUB '///////////////////////////////////////////////////////////// LOCAL Ix AS LONG IF giPumpingMessages = 1 THEN EXIT SUB giPumpingMessages = 1 IF GlobalVariableTestOn THEN IF xTimes <= 0 THEN xTimes = 1 FOR Ix = 1 TO xTimes CALL PeekRemoveTranslateDispatchMessage IF GlobalVariableTest86 = 1 THEN GOTO NoMoreNeeded NEXT Ix END IF NoMoreNeeded: giPumpingMessages = 0 END SUB '_________________________________________________________________ ' ' GetEvents dialog procedure (replacement for Sleep 0) ' Sleep 0 releases time slices back to the OS but does ' not necessarily give your program the slices back. ' ' SUB GetEvents '_________________________________________________________________ SUB GetEvents(SleepTime AS LONG) EXPORT IF SleepTime <= 0 THEN SleepTime = 1 CALL PeekRemoveTranslateDispatchMessage SLEEP SleepTime/4 CALL PeekRemoveTranslateDispatchMessage SLEEP SleepTime/4 CALL PeekRemoveTranslateDispatchMessage SLEEP SleepTime/4 CALL PeekRemoveTranslateDispatchMessage SLEEP SleepTime/4 END SUB '_________________________________________________________________ ' ' SUB PeekRemoveTranslateDispatchMessage VER4 '_________________________________________________________________ SUB PeekRemoveTranslateDispatchMessage '///////////////////////////////////////////////////////////// 'Do not want to remove the WM_QUIT message from message que. IF GlobalVariableTest86 = 1 THEN EXIT SUB '///////////////////////////////////////////////////////////// 'Could use this to signal main message loop to close 'PostThreadMessageA (GetCurrentThreadID, %WM_QUIT, 0, 0) ' Signal Quit to Msg Loop IF giPRTDMessage = 1 THEN EXIT SUB giPRTDMessage = 1 STATIC Msg AS tagMsg IF PeekMessageA(Msg, %NULL, %NULL, %NULL, %PM_REMOVE) THEN TranslateMessage Msg DispatchMessageA Msg END IF giPRTDMessage = 0 END SUB '//----------------------------------------------------------- '// This function traverses the data path that extends from the '// endpoint device to the system bus (for example, PCI) '// or external bus (USB). If the function discovers a MUX '// (input selector) in the path, it selects the MUX input '// that connects to the stream from the endpoint device. '// In this case we are looking for the Microphone or Microphone '// Boost parts. '//----------------------------------------------------------- 'Limits of Device Topology 'Where (con) is a connector 'microphone -> endpoint device B (con) physical external ' '-> Input Multiplexer Device (Topology Filter) ' (con) physical external IPart & IConnector ' subunit Mute -> IPart & ISubUnit ' subunit Vol -> IPart & ISubUnit ' subunit MUX -> IPart & ISubUnit ' (Con) Software Fixed IPart & IConnector ' '-> Wave Capture Device (Wave Filter) ' (Con) Software Fixed IPart & IConnector ' subunit ADC IPart & ISubUnit ' (Con) Software IO IPart & IConnector ' '-> System Bus Wave-in Stream (DMA) FUNCTION SelectCaptureDevice() AS LONG LOCAL hr AS LONG LOCAL ppwstrGlobalId AS WSTRINGZ PTR LOCAL ppBoostTopology AS IDeviceTopology hr = %S_OK pIaudioVolumeLevel = NOTHING IF ISOBJECT(pConnFrom) THEN 'continue ELSE GOTO ExitHere END IF '// Outer loop: Each iteration traverses the data path '// through a device topology starting at the input '// connector and ending at the output connector. WHILE %TRUE IF giProgStat = 0 THEN GOTO ExitHere hr = pConnFrom.IsConnected(bConnected) IF FAILED(hr) THEN GOTO ExitHere '// Does this connector connect to another device? IF bConnected = %FALSE THEN '// This is the end of the data path that '// stretches from the endpoint device to the '// system bus or external bus. Verify that '// the connection type is Software_IO. hr = pConnFrom.GetType(connType) IF FAILED(hr) THEN GOTO ExitHere IF connType = %ConnectorType_Software_IO THEN '? "Finished looking for connections." EXIT LOOP '// finished END IF IF FAILED(hr = %E_FAIL) THEN GOTO ExitHere END IF '// Get the connector in the next device topology, '// which lies on the other side of the connection. hr = pConnFrom.GetConnectedTo(pConnTo) IF FAILED(hr) THEN GOTO ExitHere '// Get the connector's IPart interface. hr = pConnTo.QueryInterface( _ IID_IPart, _ BYVAL VARPTR(pPartPrev)) IF FAILED(hr) THEN GOTO ExitHere pConnTo = NOTHING '// Inner loop: Each iteration traverses one link in a '// device topology and looks for input multiplexers. WHILE %TRUE IF giProgStat = 0 THEN GOTO ExitHere MyPumpMessages(2000) '// Follow downstream link to next part. hr = pPartPrev.EnumPartsOutgoing(ppParts) IF FAILED(hr) THEN GOTO ExitHere hr = ppParts.GetPart(0, pPartNext) ppParts = NOTHING IF FAILED(hr) THEN GOTO ExitHere hr = pPartNext.GetPartType(pPartType) IF FAILED(hr) THEN GOTO ExitHere IF SUCCEEDED(pPartNext.GetName(pName)) THEN '? @pName 'Microphone Boost 'Failure of the following call means only that 'the part is not a boost (microphone boost). IF UCASE$(ComponentName) <> UCASE$(@pName) THEN '? "Not a match." ELSE '? "The part name matched." 'get IAudioVolumeLevel to control volume hr = pPartNext.Activate( _ %CLSCTX_ALL, _ IID_IAudioVolumeLevel, _ pIaudioVolumeLevel) CALL SetMicrophoneBoostCallback GOTO ExitHere END IF CoTaskMemFree(pName) END IF '? "Try again..." SELECT CASE pPartType CASE %PartType_Connector '=0 '? "Connector found." '// We've reached the output connector that '// lies at the end of this device topology. hr = pPartNext.QueryInterface( _ IID_IConnector, _ BYVAL VARPTR(pConnFrom)) IF FAILED(hr) THEN GOTO ExitHere pPartPrev = NOTHING pPartNext = NOTHING EXIT LOOP CASE %PartType_Subunit '=1 '? "Subunit found." END SELECT '// Failure of the following call means only that '// the part is not a MUX (input selector). hr = pPartNext.Activate( _ %CLSCTX_ALL, _ IID_IAudioInputSelector, _ pSelector) IF hr = %S_OK THEN ? "The MUX was found." '// We found a MUX (input selector), so select '// the input from our endpoint device. LOCAL localId AS DWORD hr = pPartPrev.GetLocalId(localId) IF FAILED(hr) THEN GOTO ExitHere hr = pSelector.SetSelection(localId, BYVAL %NULL) IF FAILED(hr) THEN GOTO ExitHere pSelector = NOTHING END IF pPartPrev = NOTHING pPartPrev = pPartNext pPartNext = NOTHING WEND WEND ExitHere: ppParts = NOTHING pConnTo = NOTHING pPartPrev = NOTHING pPartNext = NOTHING pSelector = NOTHING FUNCTION = hr END FUNCTION '_____________________________________________________________________________ CALLBACK FUNCTION DlgProc LOCAL pNMHDR AS NMHDR POINTER LOCAL rcThumb_1 AS RECT LOCAL rcThumb_2 AS RECT LOCAL rcThumb_3 AS RECT LOCAL xhr AS LONG STATIC Mute AS LONG STATIC TrackBarPos_1 AS LONG STATIC TrackBarPos_2 AS LONG STATIC TrackBarPos_3 AS LONG LOCAL pid AS DWORD '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Create a timer event every 1/8 Sec = 125 '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SetTimer hDlg, %IDC_Timer0, 125, BYVAL %NULL SELECT CASE CBMSG CASE %WM_INITDIALOG giProgStat = 1 gsMasterVolumeIsChangeable = "YES" giStartStopRecognition = 1 'start recognition IF VistaPlus THEN 'Vista to 10 giStereoSpeakers = StereoSpeakersCheck '? str$(giStereoSpeakers) CALL GetMuteStereoSpeakers CALL GetVolumeStereoSpeakers CALL SetVolumeCallback gpMeterInfo = NOTHING giMicrophone = MicrophoneCheck CALL GetMuteMicrophone CALL GetVolumeMicrophone CALL SetMicrophoneCallback CALL GetVolumeMicrophoneBoost ' SetVolumeMicrophone(SCALER_MB) ' '? str$(giMicrophone) CALL CREATE_THREAD_SERVICES ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF CASE %WM_APP SELECT CASE CB.WPARAM CASE %CheckboxVolOnOffSpeaker 'NOTIFY MASTER MUTE SELECT CASE CB.LPARAM CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeaker), %BM_SETCHECK, %BST_CHECKED, 0) IconSet_1(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeaker), %BM_SETCHECK, %BST_UNCHECKED, 0) IconSet_1(1) END SELECT CASE %TrackbarVolSpeaker 'NOTIFY MASTER VOLUME PostMessageA (GetDlgItem(hDlg, %TrackbarVolSpeaker), %TBM_SETPOS, %TRUE, %TrackbarMax - CB.LPARAM) SetDlgItemTextA (hDlg, %LabelVolSpeaker, FORMAT$(CB.LPARAM, "##0")) CASE %CheckboxVolOnOffMicro 'NOTIFY MICROPHONE MUTE SELECT CASE CB.LPARAM CASE 1 PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_CHECKED, 0) 'IconSet_2(0) CASE ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_UNCHECKED, 0) 'IconSet_2(1) END SELECT CASE %TrackbarVolMicro 'NOTIFY MICROPHONE VOLUME PostMessageA (GetDlgItem(hDlg, %TrackbarVolMicro), %TBM_SETPOS, %TRUE, %TrackbarMax - CB.LPARAM) SetDlgItemTextA (hDlg, %LabelVolMicro, FORMAT$(CB.LPARAM, "##0")) CASE %TrackbarVolMicroBoost 'NOTIFY MICROPHONE BOOST SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, %TrackbarMaxBoost - CB.LPARAM/10) SetDlgItemTextA (hDlg, %LabelVolMicroBoost, FORMAT$(CB.LPARAM, "##0") & " dB") END SELECT CASE %WM_TIMER SELECT CASE CB.WPARAM CASE %IDC_Timer0 '// Update the peak meter in the dialog box. IF ISOBJECT(gpMeterInfo) THEN gpMeterInfo.GetPeakValue(PEAK) CONTROL SET TEXT hDlg, %IDC_PEAK_METER, USING$("##.#", PEAK * 100) CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETPOS, (PEAK * 100), 0 END IF END SELECT 'An application should return zero if it processes this message. FUNCTION = 0 EXIT FUNCTION CASE %WM_COMMAND SELECT CASE CB.CTL 'SPEAKERS CASE %LabelOnOffSpeaker IF (CBCTLMSG = %STN_CLICKED) OR (CBCTLMSG = 1) THEN IF IsDlgButtonChecked (hDlg, %CheckboxVolOnOffSpeaker) THEN PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeaker), %BM_SETCHECK, %BST_UNCHECKED, 0) ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffSpeaker), %BM_SETCHECK, %BST_CHECKED, 0) END IF PostMessageA (hDlg, %WM_COMMAND, MAKDWD(%CheckboxVolOnOffSpeaker, %BN_CLICKED), GetDlgItem(hDlg, %CheckboxVolOnOffSpeaker)) END IF CASE %CheckboxVolOnOffSpeaker IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN IF IsDlgButtonChecked(hDlg, %CheckboxVolOnOffSpeaker) THEN Mute = %TRUE IconSet_1(0) ELSE Mute = %FALSE 'Mute XOR %TRUE IconSet_1(1) END IF IF VistaPlus THEN 'Vista to 10 !!!!!! mute change SELECT CASE Mute CASE %TRUE CALL MuteStereoSpeakers CASE %FALSE CALL UnMuteStereoSpeakers END SELECT ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END IF CASE %ButtonSndVolExeSpeaker IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN IF VistaPlus THEN 'Vista to 10 'SndVol.exe, use the -f flag to show the master volume slider only: SndVol.exe -f 'SndVol.exe allows you to specify window location by adding coordinates after -f switch: pid = SHELL("SndVol.exe") '"C:\Windows\System32\SndVol.exe" ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END IF 'MICROPHONE CASE %LabelOnOffMicro IF (CBCTLMSG = %STN_CLICKED) OR (CBCTLMSG = 1) THEN IF IsDlgButtonChecked (hDlg, %CheckboxVolOnOffMicro) THEN PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_UNCHECKED, 0) ELSE PostMessageA (GetDlgItem(hDlg, %CheckboxVolOnOffMicro), %BM_SETCHECK, %BST_CHECKED, 0) END IF PostMessageA (hDlg, %WM_COMMAND, MAKDWD(%CheckboxVolOnOffMicro, %BN_CLICKED), GetDlgItem(hDlg, %CheckboxVolOnOffMicro)) END IF CASE %CheckboxVolOnOffMicro IF (CBCTLMSG = %BN_CLICKED) OR (CBCTLMSG = 1) THEN IF IsDlgButtonChecked(hDlg, %CheckboxVolOnOffMicro) THEN Mute = %TRUE 'IconSet_2(0) ELSE Mute = %FALSE 'Mute XOR %TRUE 'IconSet_2(1) END IF IF VistaPlus THEN 'Vista to 10 !!!!!! mute change SELECT CASE Mute CASE %TRUE CALL MuteMicrophone CASE %FALSE CALL UnMuteMicrophone END SELECT ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END IF END SELECT CASE %WM_NOTIFY pNMHDR = CBLPARAM 'SPEAKERS IF @pNMHDR.hwndFrom = GetDlgItem(hDlg, %TrackbarVolSpeaker) THEN IF @pNMHDR.code = %NM_RELEASEDCAPTURE THEN BEEP END IF SendMessageA (@pNMHDR.hwndFrom, %TBM_GETTHUMBRECT, 0, VARPTR(rcThumb_1)) MapWindowPoints (@pNMHDR.hwndFrom, hDlg, BYVAL VARPTR(rcThumb_1), 2) SetWindowPos (GetDlgItem(hDlg, %LabelVolSpeaker), 0, rcThumb_1.nRight + 5, _ rcThumb_1.nTop - 2, 0, 0, %SWP_NOZORDER OR %SWP_NOSIZE) END IF 'MICROPHONE IF @pNMHDR.hwndFrom = GetDlgItem(hDlg, %TrackbarVolMicro) THEN IF @pNMHDR.code = %NM_RELEASEDCAPTURE THEN 'BEEP END IF SendMessageA (@pNMHDR.hwndFrom, %TBM_GETTHUMBRECT, 0, VARPTR(rcThumb_2)) MapWindowPoints (@pNMHDR.hwndFrom, hDlg, BYVAL VARPTR(rcThumb_2), 2) SetWindowPos (GetDlgItem(hDlg, %LabelVolMicro), 0, rcThumb_2.nRight + 5, _ rcThumb_2.nTop - 2, 0, 0, %SWP_NOZORDER OR %SWP_NOSIZE) END IF 'MICROPHONE BOOST IF @pNMHDR.hwndFrom = GetDlgItem(hDlg, %TrackbarVolMicroBoost) THEN IF @pNMHDR.code = %NM_RELEASEDCAPTURE THEN 'BEEP END IF 'SendMessageA (@pNMHDR.hwndFrom, %TBM_GETTHUMBRECT, 0, VARPTR(rcThumb_3)) 'MapWindowPoints (@pNMHDR.hwndFrom, hDlg, BYVAL VARPTR(rcThumb_3), 2) 'SetWindowPos (GetDlgItem(hDlg, %LabelVolMicro), 0, rcThumb_3.nRight + 5, _ ' rcThumb_3.nTop - 2, 0, 0, %SWP_NOZORDER OR %SWP_NOSIZE) END IF CASE %WM_VSCROLL 'SPEAKERS IF CBLPARAM = GetDlgItem(hDlg, %TrackbarVolSpeaker) THEN SELECT CASE LOWRD(CBWPARAM) CASE %TB_LINEDOWN, %TB_LINEUP, %TB_THUMBPOSITION, %TB_THUMBTRACK, _ %TB_PAGEDOWN, %TB_PAGEUP, %TB_TOP, %TB_BOTTOM', %TB_ENDSCROLL TrackBarPos_1 = %TrackbarMax - SendMessageA (CBLPARAM, %TBM_GETPOS, 0, 0) SetDlgItemTextA (hDlg, %LabelVolSpeaker, FORMAT$(TrackBarPos_1, "##0")) 'Set speaker volume IF VistaPlus THEN 'Vista to 10 !!!!! volume change CALL SetVolumeStereoSpeakers(TrackBarPos_1 / 100) 'range 0 to 100 ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END SELECT END IF 'MICROPHONE IF CBLPARAM = GetDlgItem(hDlg, %TrackbarVolMicro) THEN SELECT CASE LOWRD(CBWPARAM) CASE %TB_LINEDOWN, %TB_LINEUP, %TB_THUMBPOSITION, %TB_THUMBTRACK, _ %TB_PAGEDOWN, %TB_PAGEUP, %TB_TOP, %TB_BOTTOM', %TB_ENDSCROLL TrackBarPos_2 = %TrackbarMax - SendMessageA (CBLPARAM, %TBM_GETPOS, 0, 0) SetDlgItemTextA (hDlg, %LabelVolMicro, FORMAT$(TrackBarPos_2, "##0")) 'Set microphone volume IF VistaPlus THEN 'Vista to 10 !!!!! volume change CALL SetVolumeMicrophone(TrackBarPos_2 / 100) 'range 0 to 100 ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END SELECT END IF 'MICROPHONE BOOST IF CBLPARAM = GetDlgItem(hDlg, %TrackbarVolMicroBoost) THEN SELECT CASE LOWRD(CBWPARAM) CASE %TB_LINEDOWN, %TB_LINEUP, %TB_THUMBPOSITION, %TB_THUMBTRACK, _ %TB_PAGEDOWN, %TB_PAGEUP, %TB_TOP, %TB_BOTTOM', %TB_ENDSCROLL TrackBarPos_3 = %TrackbarMaxBoost - SendMessageA (CBLPARAM, %TBM_GETPOS, 0, 0) SetDlgItemTextA (hDlg, %LabelVolMicroBoost, FORMAT$(TrackBarPos_3 * 10, "##0") & " dB") 'Set microphone volume IF VistaPlus THEN 'Vista to 10 !!!!! volume change CALL SetVolumeMicrophoneBoost(TrackBarPos_3 * 10) 'range 0 to 3 ELSE '95 to XP ? "Sorry, this app does not support this OS." END IF END SELECT END IF CASE %WM_CLOSE giProgStat = 0 'DestroyWindow hWnd CASE %WM_DESTROY 'window is being destroyed 'after windows is removed from screen (children still exist) KillTimer (hDlg, %IDC_Timer0) pSelector = NOTHING gpIMMDeviceEnumMicrophone = NOTHING gpIMMDeviceMicrophone = NOTHING gpIAudioEndpointVolumeMicrophone = NOTHING gpMeterInfo = NOTHING pDeviceTopology = NOTHING pConnFrom = NOTHING pConnTo = NOTHING pPartPrev = NOTHING pPartNext = NOTHING ppParts = NOTHING pIaudioVolumeLevel = NOTHING PostQuitMessage 0 'If an application processes this message, it should return zero. FUNCTION = 0 EXIT FUNCTION 'CASE %WM_DESTROY ' IF VistaPlus THEN 'Vista to 10 !!!!! destroy created objects ' IF pIMMDeviceEnumerator THEN ' 'PP = @pAudioEndpointVolume + 16 'UnRegisterControlChangeNotify ' 'CALL DWORD @PP USING F2(BYVAL pAudioEndpointVolume, BYVAL pAudioEndpointVolumeCallBack) TO xhr ' 'CALL DWORD @@pIMMDeviceEnumerator[2] USING F1(@pIMMDeviceEnumerator) 'Release object ' 'CALL DWORD @@pIMMDevice[2] USING F1(@pIMMDevice) 'Release object ' 'CALL DWORD @@pAudioEndpointVolume[2] USING F1(@pAudioEndpointVolume) 'Release object ' END IF ' CoUninitialize ' ' ELSE '95 to XP ' ? "Sorry, this app does not support this OS." ' END IF ' giProgStat = 0 END SELECT END FUNCTION '______________________________________________________________________________ FUNCTION PBMAIN() LOCAL OS AS OSVERSIONINFOEXA OS.dwOSVersionInfoSize = SIZEOF(OSVERSIONINFOEXA) GetVersionExA (BYVAL VARPTR(OS)) IF (OS.dwPlatformId = %VER_PLATFORM_WIN32_NT) AND (OS.dwMajorVersion >= 6) THEN VistaPlus = %TRUE 'Vista to 10 END IF CLSID_MMDeviceEnumerator = GUID$("{BCDE0395-E52F-467C-8E3D-C4579291692E}") IID_IMMDeviceEnumerator = GUID$("{A95664D2-9614-4F35-A746-DE8DB63617E6}") IID_IAudioMeterInformation = GUID$("{C02216F6-8C67-4B5B-9D00-D008E73E0064}") IID_IDeviceTopology = GUID$("{2A07407E-6497-4A18-9787-32F79BD0D98F}") IID_IAudioEndpointVolume = GUID$("{5CDF2C82-841E-4546-9722-0CF74078229A}") IID_IPart = GUID$("{AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9}") IID_IAudioVolumeLevel = GUID$("{7FB7B48F-531D-44A2-BCB3-5AD5A134B3DC}") IID_IConnector = GUID$("{9C2C4058-23F5-41DE-877A-DF3AF236A09E}") IID_IAudioInputSelector = GUID$("{4F03DC02-5E6E-4653-8F72-A030C123D598}") IID_IAudioEndpointVolumeCallback = GUID$("{657804FA-D6AD-4496-8A60-352752AF4F89}") IID_IControlChangeNotify = GUID$("{A09513ED-C709-4D21-BD7B-5F34C47F3947}") DIALOG FONT "Segoe UI", 9 DIALOG NEW PIXELS, %HWND_DESKTOP, $AppNAme, , , 280, 400, _ %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg 'SPEAKERS IconSet_1(-2) 'Init IconSet_1(1) 'Set to icon on CONTROL ADD LABEL, hDlg, %LabelInfoSpeaker, "Speakers:", _ 15, 10, 80, 20, %WS_CHILD OR %WS_VISIBLE OR %SS_NOPREFIX OR %SS_CENTER, %WS_EX_CLIENTEDGE CONTROL ADD LABEL, hDlg, %LabelInfoMicro, "Microphone:", _ 100, 10, 80, 20, %WS_CHILD OR %WS_VISIBLE OR %SS_NOPREFIX OR %SS_CENTER, %WS_EX_CLIENTEDGE CONTROL ADD LABEL, hDlg, %LabelInfoMicroBoost, "MicroBoost:", _ 185, 10, 80, 20, %WS_CHILD OR %WS_VISIBLE OR %SS_NOPREFIX OR %SS_CENTER, %WS_EX_CLIENTEDGE CONTROL ADD LABEL, hDlg, %LabelMaxSpeaker, "Max", 35, 40, 30, 12 CONTROL ADD LABEL, hDlg, %LabelMinSpeaker, "Min", 35, 195, 30, 12 CONTROL ADD LABEL, hDlg, %LabelVolSpeaker, "---", 60, 120, 30, 12 CONTROL ADD "MsCtls_TrackBar32", hDlg, %TrackbarVolSpeaker, "msctls_trackbar321", 30, 55, 25, 140, _ %WS_VISIBLE OR %WS_CHILD OR %TBS_BOTH OR %TBS_NOTICKS OR %WS_TABSTOP OR %TBS_VERT OR %TBS_REVERSED SendDlgItemMessageA (hDlg, %TrackbarVolSpeaker, %TBM_SETPOS, %TRUE, 50) SendDlgItemMessageA (hDlg, %TrackbarVolSpeaker, %TBM_SETPAGESIZE,0, 10) SendDlgItemMessageA (hDlg, %TrackbarVolSpeaker, %TBM_SETRANGEMAX, %TRUE, %TrackbarMax) SendDlgItemMessageA (hDlg, %TrackbarVolSpeaker, %TBM_SETRANGEMIN, %TRUE, 0) CONTROL ADD LABEL, hDlg, %LabelMaxMicro, "Max", 125, 40, 30, 12 CONTROL ADD LABEL, hDlg, %LabelMinMicro, "Min", 125, 195, 30, 12 CONTROL ADD LABEL, hDlg, %LabelVolMicro, "---", 150, 120, 30, 12 CONTROL ADD "MsCtls_TrackBar32", hDlg, %TrackbarVolMicro, "msctls_trackbar321", 120, 55, 25, 140, _ %WS_VISIBLE OR %WS_CHILD OR %TBS_BOTH OR %TBS_NOTICKS OR %WS_TABSTOP OR %TBS_VERT OR %TBS_REVERSED SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETPOS, %TRUE, 50) SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETPAGESIZE,0, 10) SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETRANGEMAX, %TRUE, %TrackbarMax) SendDlgItemMessageA (hDlg, %TrackbarVolMicro, %TBM_SETRANGEMIN, %TRUE, 0) CONTROL ADD LABEL, hDlg, %LabelMaxMicroBoost, "Max", 90 + 125, 40, 30, 12 CONTROL ADD LABEL, hDlg, %LabelMinMicroBoost, "Min", 90 + 125, 195, 30, 12 CONTROL ADD LABEL, hDlg, %LabelVolMicroBoost, "---", 90 + 150, 120, 30, 12 CONTROL ADD "MsCtls_TrackBar32", hDlg, %TrackbarVolMicroBoost, "msctls_trackbar321", 90 + 120, 55, 25, 140, _ %WS_VISIBLE OR %WS_CHILD OR %TBS_BOTH OR %TBS_NOTICKS OR %WS_TABSTOP OR %TBS_VERT OR %TBS_REVERSED 'SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPOS, %TRUE, 10) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETPAGESIZE,0, 10) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETRANGEMAX, %TRUE, 3) SendDlgItemMessageA (hDlg, %TrackbarVolMicroBoost, %TBM_SETRANGEMIN, %TRUE, 0) CONTROL ADD CHECKBOX, hDlg, %CheckboxVolOnOffMicro, "Microphone Mute", 50, 20 + 210, 140, 12, _ %BS_AUTOCHECKBOX OR %WS_TABSTOP CONTROL ADD CHECKBOX, hDlg, %CheckboxVolOnOffSpeaker, "Speaker Mute", 50, 20 + 230, 140, 12, _ %BS_AUTOCHECKBOX OR %WS_TABSTOP CONTROL ADD LABEL, hDlg, %LabelOnOffSpeaker, "", 190, 240, _ GetSystemMetrics (%SM_CXICON), GetSystemMetrics(%SM_CYICON), %SS_ICON OR %SS_NOTIFY IconSet_1(1) CONTROL ADD BUTTON, hDlg, %ButtonSndVolExeSpeaker, "Volume Mixer", 50, 280, 180, 22 CONTROL ADD PROGRESSBAR, hDlg, %ID_VOLUME, "", 15, 320, 250, 20 CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETRANGE, 0, MAKLNG(0, 100) CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETSTEP, -1, 0 CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETBKCOLOR, 0, RGB(50,50,50) CONTROL SEND hDlg, %ID_VOLUME, %PBM_SETBARCOLOR, 0, RGB(55,224,230) CONTROL ADD LABEL, hDlg, %IDC_PEAK_METER, "", 15, 345, 250, 20 DIALOG SHOW MODAL hDlg CALL DlgProc IconSet_1(-1) 'Release END FUNCTION '______________________________________________________________________________ '_________________________________________________________________ ' ' SUB CREATE_THREAD_SERVICES ' full time '_________________________________________________________________ SUB CREATE_THREAD_SERVICES CALL CreateRecognitionProcess LOCAL idThreadPeakMeter AS LONG THREAD CREATE PeakMeterThread(1) TO idThreadPeakMeter THREAD CLOSE idThreadPeakMeter TO idThreadPeakMeter END SUB '_________________________________________________________________ ' ' THREAD FUNCTION PeakMeterThread VER4 ' full time '_________________________________________________________________ THREAD FUNCTION PeakMeterThread(BYVAL yyy AS LONG) AS LONG DO WHILE GlobalVariableTestOn '// Update the peak meter in the dialog box. IF ISOBJECT(gpMeterInfo) THEN gpMeterInfo.GetPeakValue(PEAK) CONTROL SEND hDlg, %IDC_PEAK_METER, %PBM_SETPOS, PEAK * 1000, 0 END IF SLEEP 10 IF GlobalVariableTest86 = 1 THEN GOTO LoopEnd SLEEP 20 LOOP LoopEnd: END FUNCTION '_________________________________________________________________ ' ' SUB CreateRecognitionProcess Jarvis '_________________________________________________________________ SUB CreateRecognitionProcess LOCAL idThreadRecognition AS LONG THREAD CREATE RecogProcessThread(1) TO idThreadRecognition THREAD CLOSE idThreadRecognition TO idThreadRecognition END SUB '_________________________________________________________________ ' ' THREAD FUNCTION RecogProcessThread Jarvis ' full time '_________________________________________________________________ THREAD FUNCTION RecogProcessThread(BYVAL yyy AS LONG) AS LONG LOCAL MyPhraseData AS STRING SLEEP 1000 '75 'small delay giRunningRecogProcess = 1 DO WHILE GlobalVariableTestOn = 1 IF TRIM$(MyDataX) <> "" THEN MyPhraseData = MyDataX MyDataX = "" CALL PutColonOnMarque CALL PROCESS_RECOGNITION(MyPhraseData) CALL ResetRecognition END IF SLEEP 20 CALL MyPumpMessages(100) IF GlobalVariableTest86 = 1 THEN EXIT LOOP END IF SELECT CASE RecognitionStatus CASE 0 IF giStartStopRecognition = 1 THEN giStartStopRecognition = 0 'reset signal IF ISFALSE ISOBJECT(oRecoContext) THEN CALL CREATE_RECOGNITION_CONTEXT END IF CALL RECOGNITION_ENABLE RecognitionStatus = 1 'Emmulate recognition to test the interface. oRecoContext.Recognizer.EmulateRecognition("Recognition has started") END IF CASE 1 IF giStartStopRecognition = 2 THEN giStartStopRecognition = 0 'reset signal CALL RECOGNITION_OFF END IF END SELECT SLEEP 20 CALL MyPumpMessages(100) IF GlobalVariableTest86 = 1 THEN EXIT LOOP END IF LOOP giRunningRecogProcess = 0 'winbeep(5000, 75) END FUNCTION '_________________________________________________________________ ' ' SUB CREATE_RECOGNITION_CONTEXT Jarvis '_________________________________________________________________ SUB CREATE_RECOGNITION_CONTEXT LOCAL vInput AS STRING SLEEP 10 'Create an instance of the ISpeechRecoContext Interface oRecoContext = NEWCOM "SAPI.SpInProcRecoContext" '** VB WithEvents work around. ** 'Link the events of oRecoContext to InProcEvents to 'process a recognition event. InProcEvents = CLASS "CISpeechRecoContextEventsImplemented" EVENTS FROM oRecoContext CALL InProcEvents 'Create the InProc Speech Recognizer. oRecognizer = oRecoContext.Recognizer 'Create the InProc Speech Grammar. oMyGrammar = oRecoContext.CreateGrammar(1) 'Disable Grammar while loading it. oMyGrammar.State = %SGSDisabled 'Load the default Dictation Grammar. vInput = "" oMyGrammar.DictationLoad(vInput, %SLOstatic) oMyGrammar.DictationSetState(%SGDSInactive) 'Load the command and control grammar IF FileExists(EXE.PATH$ + $CandCGrammar) THEN '"jarvis.xml" oMyGrammar.CmdLoadFromFile(EXE.PATH$ + $CandCGrammar, %SLODynamic) 'SLOStatic) 'dim gData As Variant 'gData = gsSOLXML 'oMyGrammar.CmdLoadFromMemory gData, %SLODynamic 'Load from memory oMyGrammar.CmdSetRuleIdState(0, %SGDSInactive) giCCGrammarLoaded = 1 gsBannerDictation = "*" ELSE 'CALL FLASH_NOTE_FOR_SECONDS("Unable to load C&C grammar.", 1.5) '? "Unable to load C&C grammar." giCCGrammarLoaded = 0 gsBannerDictation = ">" END IF CALL RECOGNITION_ENABLE 'Enable Grammar after loading it. oMyGrammar.State = %SGSEnabled CALL RECOGNITION_DISABLE 'Create the Audio Token Category. oCategory = NEWCOM "SAPI.SpObjectTokenCategory" 'Set the Audio Token category ID. oCategory.SetId("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\AudioInput") 'Create the Audio Token. oToken = NEWCOM "SAPI.SpObjectToken" 'Set the Token Category ID. oToken.SetId(oCategory.Default()) 'Give the Recognizer the Token. oRecognizer.PutRef_AudioInput() = oToken END SUB '_________________________________________________________________ ' ' SUB RECOGNITION_ENABLE new 2020 MAY 13 new ' ' Includes workaround for recognition volume AGC forcing volume to 91 ' The solution was to capture the volume level before using %SGDSActive ' and then reapplying the value after %SGDSActive was executed. ' For some unknown reason the callback didn't get a new level so the ' trackbar had to be refreshed as well. '_________________________________________________________________ SUB RECOGNITION_ENABLE LOCAL LastValue AS SINGLE 'NOTE: oMyGrammar.DictationSetState(%SGDSActive) 'Turn Dictation on. 'This causes the microphone volume to drop to 91 the second time it is enabled 'instead of leaving the volume where it was originally set. 'Microsoft's way of making speech recognition idiot proof. 'Start the recognition by activating one of the grammars IF ISTRUE ISOBJECT(oRecoContext) THEN CALL GetVolumeMicrophone 'workaround LastValue = giMasterMicrophoneLevel/100 'workaround IF giCCGrammarLoaded = 1 THEN IF gsBannerDictation = "*" THEN oMyGrammar.DictationSetState(%SGDSInactive) 'Turn Dictation off. oMyGrammar.CmdSetRuleIdState(0, %SGDSActive) 'turn command / contol on ELSE oMyGrammar.CmdSetRuleIdState(0, %SGDSInactive) 'turn command / contol off oMyGrammar.DictationSetState(%SGDSActive) 'Turn Dictation on. END IF ELSE oMyGrammar.DictationSetState(%SGDSActive) 'Turn Dictation on. END IF CALL SetVolumeMicrophone(LastValue) 'workaround CALL RefreshVolumeTrackbarPos(LastValue) 'workaround ELSE CALL PutEqualSignOnMarque END IF END SUB '_________________________________________________________________ ' ' SUB RECOGNITION_DISABLE '_________________________________________________________________ SUB RECOGNITION_DISABLE 'Stop the recognition by deactivating both of the grammars IF ISTRUE ISOBJECT(oRecoContext) THEN CALL PutTildeOnMarque oMyGrammar.DictationSetState(%SGDSInactive) 'Turn Dictation off. IF giCCGrammarLoaded = 1 THEN oMyGrammar.CmdSetRuleIdState(0, %SGDSInactive) 'turn command / contol off END IF ELSE CALL PutEqualSignOnMarque END IF END SUB '_________________________________________________________________ ' ' SUB RECOGNITION_OFF VISTA PLUS '_________________________________________________________________ SUB RECOGNITION_OFF CALL RECOGNITION_DISABLE RecognitionStatus = 0 END SUB '_________________________________________________________________ ' ' SUB PROCESS_RECOGNITION '_________________________________________________________________ SUB PROCESS_RECOGNITION(TheWordPhrase AS STRING) LOCAL lsMyData AS STRING LOCAL lsMessage AS STRING IF giProcessingRecog = 1 THEN CALL ResetRecognition: EXIT SUB giProcessingRecog = 1 lsMyData = LCASE$(TRIM$(TheWordPhrase)) 'IF lsMyData = "recognition has started" then ? "Recognition has started." 'used to validate recognition TheWordPhrase = "" CALL ResetRecognition END SUB '_________________________________________________________________ ' ' SUB ResetRecognition Jarvis '_________________________________________________________________ SUB ResetRecognition GetEvents(80) IF RecognitionStatus = 1 THEN 'Pause Recognition oRecoContext.Pause() GetEvents(8) 'Resume Recognition oRecoContext.Resume() END IF END SUB SUB F698 'REFRESH_MARQUEE_BANNER PostMessageA hDlg, %WM_COMMAND, %ID_RefreshBanner, 0 END SUB '_________________________________________________________________ ' ' SUB PutTildeOnMarque the recognition context is available but not activated '_________________________________________________________________ SUB PutTildeOnMarque gsBannerListen = "~" CALL F698 END SUB '_________________________________________________________________ ' ' SUB PutColonOnMarque means a recognition has happened and is being processed are you ok '_________________________________________________________________ SUB PutColonOnMarque IF RecognitionStatus = 1 THEN IF giMicroMute = 0 THEN gsBannerListen = ":" CALL F698 END IF END IF END SUB '_________________________________________________________________ ' ' SUB PutQuestionMarkOnMarque the recognition context is available and active '_________________________________________________________________ SUB PutQuestionMarkOnMarque IF RecognitionStatus = 1 THEN IF giMicroMute = 0 THEN 'microphone is not muted gsBannerListen = "?" CALL F698 END IF END IF END SUB '_________________________________________________________________ ' ' SUB PutEqualSignOnMarque no recognition context available '_________________________________________________________________ SUB PutEqualSignOnMarque IF RecognitionStatus = 0 THEN gsBannerListen = "=" CALL F698 END IF END SUB '_________________________________________________________________ ' ' FileExists - make sure a file or folder exists '_________________________________________________________________ FUNCTION FileExists(sFileName AS ASCIIZ) AS LONG LOCAL sFN AS STRING sFN = REMOVE$(sFileName, $CRLF) FUNCTION = PathFileExistsA(BYVAL STRPTR(sFN)) 'Return non-zero if file or folder exist. END FUNCTION '_________________________________________________________________ ' ' SUB EnumUILanguagesCB '_________________________________________________________________ FUNCTION EnumUILanguagesCB(lpUILanguageString AS ASCIIZ, lParam AS LONG) AS LONG LOCAL zLocale AS ASCIIZ * %MAX_PATH GetLocaleInfoA (VAL("&h" & lpUILanguageString), %LOCALE_SENGLANGUAGE, zLocale, %MAX_PATH) sBuffer = zLocale & $SPC & lpUILanguageString & $CRLF FUNCTION = %TRUE 'To continue enumeration, the callback function should return TRUE. END FUNCTION
This site says:Upload failed due to your usergroups's upload quota. This file willrequire 20.3 KB but you only have 13.8 KB of 30.00 MBremaining.
Leave a comment:
-
Microphone with boost controls
Code:#COMPILE EXE "MicrophoneWithBoost.exe" #DIM ALL 'FINDING AND ADJUSTING MICROPHONE BOOST CODE TRANSLATED FROM THESE LINKS 'http://dhavalbc.blogspot.com/2014/05/getting-and-setting-microphone-gain-or.html and 'https://docs.microsoft.com/en-us/windows/win32/coreaudio/device-topologies 'Works with PBWIN 10.4 and Jose' includes #REGISTER NONE '#INCLUDE ONCE "MB_API_A.inc" 'WHEN USED {2,640 total lines} COMPILE TIME 0.1 seconds 'OR THESE #INCLUDE ONCE "Win32Api.inc" 'WHEN USED {278,386 total lines} COMPILE TIME 1.4 seconds #INCLUDE ONCE "CommCtrl.inc" 'Needed if manifest and WinXP #INCLUDE ONCE "mmdeviceapi.inc" 'used for WASAPI #INCLUDE ONCE "devpkey.inc" 'used for WASAPI #INCLUDE ONCE "propvarutil.inc" 'used for WASAPI #INCLUDE ONCE "endpointvolume.inc" 'used for WASAPI GLOBAL hWndMain AS DWORD GLOBAL dwNoRetMLTextBoxStyle AS DWORD GLOBAL giProgStat AS LONG GLOBAL hPeakMeter AS DWORD GLOBAL PEAK AS SINGLE GLOBAL dwSProgressStyle AS DWORD GLOBAL dwSNBProgressStyle AS DWORD GLOBAL dwProgressStyle AS DWORD GLOBAL dwNBProgressStyle AS DWORD GLOBAL dwButtonStyle AS DWORD GLOBAL SCALER AS SINGLE GLOBAL SCALER_MB AS SINGLE GLOBAL pDevId AS WSTRINGZ PTR GLOBAL devName AS WSTRING GLOBAL pName AS WSTRINGZ PTR 'LPWSTR pName GLOBAL giMicroMute AS LONG 'Tracks Microphone Mute status GLOBAL pflow AS LONG 'DataFlow pflow GLOBAL pPartType AS LONG 'PartType GLOBAL bConnected AS LONG 'BOOL bConnected GLOBAL connType AS LONG 'ConnectorType GLOBAL ComponentName AS WSTRINGZ * 255 GLOBAL XFill AS STRING 'used to post text to clipboard GLOBAL giPRTDMessage AS LONG GLOBAL giPumpingMessages AS LONG GLOBAL giMicrophone AS LONG ' default microphone availablility yes = 1, no = 0 GLOBAL giMicrophoneHr AS LONG GLOBAL giMasterMicrophoneLevel AS LONG GLOBAL gsTheMicrophoneName AS STRING GLOBAL gpIMMDeviceEnumMicrophone AS IMMDeviceEnumerator GLOBAL gpIMMDeviceMicrophone AS IMMDevice GLOBAL gpIAudioEndpointVolumeMicrophone AS IAudioEndpointVolume GLOBAL gpMeterInfo AS IAudioMeterInformation GLOBAL pDeviceTopology AS IDeviceTopology GLOBAL pConnFrom AS IConnector GLOBAL pConnTo AS IConnector GLOBAL pPartPrev AS IPart GLOBAL pPartNext AS IPart GLOBAL ppParts AS IPartsList GLOBAL pIaudioVolumeLevel AS IAudioVolumeLevel GLOBAL pSelector AS IAudioInputSelector GLOBAL CLSID_MMDeviceEnumerator AS GUID GLOBAL IID_IPart AS GUID GLOBAL IID_IAudioVolumeLevel AS GUID GLOBAL IID_IConnector AS GUID GLOBAL IID_IAudioInputSelector AS GUID GLOBAL IID_IAudioEndpointVolume AS GUID GLOBAL IID_IDeviceTopology AS GUID GLOBAL IID_IAudioMeterInformation AS GUID %IDC_STATIC_MINVOL = 1001 %IDC_STATIC_MAXVOL = 1002 %IDC_PEAK_METER = 1003 %IDC_Timer0 = 1004 %ID_VOLUME = 1005 %ID_MUTE = 1006 %ID_VUP = 1007 %ID_VDN = 1008 %ID_VUP_MB = 1009 %ID_VDN_MB = 1010 DECLARE SUB DrawPeakMeter(HWND AS DWORD, float AS SINGLE) '**************************** ' **** MAIN ENTRY POINT **** '**************************** FUNCTION WINMAIN (BYVAL hInstance AS DWORD, _ BYVAL hPrevInstance AS DWORD, _ BYVAL lpCmdLine AS ASCIIZ PTR, _ BYVAL iCmdShow AS LONG) AS LONG LOCAL Msg AS tagMsg LOCAL W AS WndClassExA LOCAL szAppName AS ASCIIZ * 80 LOCAL szClassName AS ASCIIZ * 80 LOCAL WndStyle AS LONG LOCAL WndStyleX AS LONG giProgStat = 1 CLSID_MMDeviceEnumerator = GUID$("{BCDE0395-E52F-467C-8E3D-C4579291692E}") IID_IAudioMeterInformation = GUID$("{C02216F6-8C67-4B5B-9D00-D008E73E0064}") IID_IDeviceTopology = GUID$("{2A07407E-6497-4A18-9787-32F79BD0D98F}") IID_IAudioEndpointVolume = GUID$("{5CDF2C82-841E-4546-9722-0CF74078229A}") IID_IPart = GUID$("{AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9}") IID_IAudioVolumeLevel = GUID$("{7FB7B48F-531D-44A2-BCB3-5AD5A134B3DC}") IID_IConnector = GUID$("{9C2C4058-23F5-41DE-877A-DF3AF236A09E}") IID_IAudioInputSelector = GUID$("{4F03DC02-5E6E-4653-8F72-A030C123D598}") 'register window class szAppName = "Microphone with boost" szClassName = "#32770" W.cbSize = SIZEOF(W) W.Style = %CS_HREDRAW OR %CS_VREDRAW '%WS_OverlappedWindow Or %WS_HScroll Or %WS_VScroll ' W.lpfnWndProc = CODEPTR(WndProc) W.cbClsExtra = 0 W.cbWndExtra = 0 W.hInstance = hInstance W.hIcon = 0 'LoadImage(hInstance, BYVAL 3000, %IMAGE_ICON, 0, 0, %LR_LOADMAP3DCOLORS OR %LR_DEFAULTSIZE) W.hCursor = LoadCursorA(%NULL, BYVAL %IDC_ARROW) W.hbrBackground = GetStockObject(%DKGRAY_BRUSH) '(%LTGRAY_BRUSH) '%COLOR_3DDKSHADOW 'COLOR_BTNSHADOW'%Color_BtnFace+1 (%COLOR_ACTIVEBORDER) W.lpszMenuName = %NULL W.lpszClassName = VARPTR(szClassName) W.hIconSm = W.hIcon RegisterClassExA W 'create window of that class WndStyle = %WS_VISIBLE OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_SYSMENU OR %DS_SETFONT OR %DS_NOFAILCREATE 'OR %WS_POPUP OR %WS_BORDER OR %DS_MODALFRAME WndStyleX = %WS_EX_LEFT OR %WS_EX_WINDOWEDGE OR %WS_EX_APPWINDOW hWndMain = CreateWindowExA( _ WndStyleX, _ ' extended styles szClassName, _ ' window class name szAppName, _ ' caption WndStyle, _ ' window styles 300, _ ' left 300, _ ' top 270, _ ' width 190, _ ' height %HWND_DESKTOP, _ ' parent window handle %NULL, _ ' window menu handle hInstance, _ ' program instance handle BYVAL %NULL) ' creation parameters CALL CreateDlgControls ShowWindow hWndMain, iCmdShow 'controls how window is to be shown. 1st must use iCmdShow UpdateWindow hWndMain 'sends the window it's first WM_Create to display the window on the screen 'message pump - calls WndProc whenever an application-specific message is received 'WndProc can process the message, or pass it on to a the default window procedure that is built into Windows. WHILE GetMessageA(Msg, %NULL, 0, 0) > 0 IF ISFALSE IsDialogMessageA (hWndMain, Msg) THEN TranslateMessage Msg DispatchMessageA Msg END IF WEND END FUNCTION '//----------------------------------------------------------- '// DlgProc -- Dialog box procedure '//----------------------------------------------------------- FUNCTION WndProc (BYVAL hWnd AS DWORD, _ BYVAL wMsg AS DWORD, _ BYVAL wParam AS DWORD, _ BYVAL lParam AS LONG) EXPORT AS LONG LOCAL xhr AS LONG '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Create a timer event every 1/8 Sec = 125 '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SetTimer hWndMain, %IDC_Timer0, 125, BYVAL %NULL SELECT CASE wMsg CASE %WM_CREATE gpMeterInfo = NOTHING giMicrophone = MicrophoneCheck SetVolumeMicrophone(SCALER) 'If an application processes this message, it should return zero to continue creation of the window. FUNCTION = 0 EXIT FUNCTION CASE %WM_COMMAND SELECT CASE LO(WORD, wParam) CASE %IDCANCEL gpIMMDeviceEnumMicrophone = NOTHING gpIMMDeviceMicrophone = NOTHING gpMeterInfo = NOTHING KillTimer (hWnd, %IDC_Timer0) EndDialog(hWnd, %TRUE) 'function = 1 CASE %ID_MUTE IF giMicrophone = 1 THEN IF giMicroMute = 0 THEN 'mute microphone CALL MuteMicrophone ELSE 'unmute microphone CALL UnMuteMicrophone END IF END IF CASE %ID_VUP SCALER = SCALER + .05 IF SCALER > 1 THEN SCALER = 1 SetVolumeMicrophone(SCALER) 'SCALER RANGE IS 0 TO 1 CASE %ID_VDN SCALER = SCALER - .05 IF SCALER < 0 THEN SCALER = 0 SetVolumeMicrophone(SCALER) 'SCALER RANGE IS 0 TO 1 CASE %ID_VUP_MB IF ISOBJECT(pIaudioVolumeLevel) THEN SCALER_MB = SCALER_MB + 10 IF SCALER_MB > 30 THEN SCALER_MB = 30 pIaudioVolumeLevel.SetLevel(0, SCALER_MB, BYVAL %NULL) 'SCALER RANGE IS 0 TO 30 END IF CASE %ID_VDN_MB IF ISOBJECT(pIaudioVolumeLevel) THEN SCALER_MB = SCALER_MB - 10 IF SCALER_MB < 0 THEN SCALER_MB = 0 pIaudioVolumeLevel.SetLevel(0, SCALER_MB, BYVAL %NULL) 'SCALER RANGE IS 0 TO 30 END IF END SELECT 'If an application processes this message, it should return zero. FUNCTION = 0 EXIT FUNCTION CASE %WM_TIMER SELECT CASE wParam CASE %IDC_Timer0 '// Update the peak meter in the dialog box. IF ISOBJECT(gpMeterInfo) THEN gpMeterInfo.GetPeakValue(PEAK) CONTROL SET TEXT hWndMain, %IDC_PEAK_METER, USING$("##.#", PEAK * 100) CONTROL SEND hWndMain, %ID_VOLUME, %PBM_SETPOS, (PEAK * 100), 0 END IF END SELECT 'An application should return zero if it processes this message. FUNCTION = 0 EXIT FUNCTION CASE %WM_CLOSE giProgStat = 0 DestroyWindow hWnd CASE %WM_DESTROY 'window is being destroyed 'after windows is removed from screen (children still exist) pSelector = NOTHING gpIMMDeviceEnumMicrophone = NOTHING gpIMMDeviceMicrophone = NOTHING gpIAudioEndpointVolumeMicrophone = NOTHING gpMeterInfo = NOTHING pDeviceTopology = NOTHING pConnFrom = NOTHING pConnTo = NOTHING pPartPrev = NOTHING pPartNext = NOTHING ppParts = NOTHING pIaudioVolumeLevel = NOTHING PostQuitMessage 0 'If an application processes this message, it should return zero. FUNCTION = 0 EXIT FUNCTION END SELECT FUNCTION = DefWindowProcA(hWnd, wMsg, wParam, lParam) 'if not handled above, pass to Windows default message handler. END FUNCTION SUB CreateDLGControls LOCAL MyCtrl AS DWORD dwNoRetMLTextBoxStyle = %WS_CHILD OR %WS_VISIBLE OR %ES_NOHIDESEL OR %ES_READONLY OR %WS_BORDER dwSProgressStyle = %WS_CHILD OR %WS_VISIBLE OR %PBS_SMOOTH OR %WS_BORDER '%PBS_SMOOTH for undotted bar dwSNBProgressStyle = %WS_CHILD OR %WS_VISIBLE OR %PBS_SMOOTH dwProgressStyle = %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER dwNBProgressStyle = %WS_CHILD OR %WS_VISIBLE dwButtonStyle = %WS_CHILD OR %WS_VISIBLE MyCtrl = addTextBox(hWndMain, %IDC_STATIC_MINVOL, "", 10, 12, 20, 24, dwNoRetMLTextBoxStyle OR %SS_LEFT) MyCtrl = addTextBox(hWndMain, %IDC_PEAK_METER, "", 31, 12, 40 + 164, 24, dwNoRetMLTextBoxStyle OR %SS_CENTER) MyCtrl = addTextBox(hWndMain, %IDC_STATIC_MAXVOL, "", 40 + 196, 12, 20, 24, dwNoRetMLTextBoxStyle OR %SS_RIGHT) MyCtrl = addProgress(hWndMain, %ID_VOLUME, "", 10, 40, 40 + 205, 12, dwSProgressStyle) CONTROL SEND hWndMain, %ID_VOLUME, %PBM_SETRANGE, 0, MAKLNG(0, 100) CONTROL SEND hWndMain, %ID_VOLUME, %PBM_SETSTEP, -1, 0 CONTROL SEND hWndMain, %ID_VOLUME, %PBM_SETBKCOLOR, 0, RGB(50,50,50) CONTROL SEND hWndMain, %ID_VOLUME, %PBM_SETBARCOLOR, 0, RGB(55,224,230) MyCtrl = addButton(hWndMain, %ID_MUTE, "Mute/Unmute", 10, 60 + 13, 120, 24, dwButtonStyle) MyCtrl = addButton(hWndMain, %ID_VUP, "Volume Up", 10, 60 + 40, 120, 24, dwButtonStyle) MyCtrl = addButton(hWndMain, %ID_VDN, "Volume Down", 10, 60 + 67, 120, 24, dwButtonStyle) MyCtrl = addButton(hWndMain, %ID_VUP_MB, "Boost Up", 135, 60 + 40, 120, 24, dwButtonStyle) MyCtrl = addButton(hWndMain, %ID_VDN_MB, "Boost Down", 135, 60 + 67, 120, 24, dwButtonStyle) END SUB FUNCTION addTextBox(BYVAL hParent AS DWORD, BYVAL nID AS LONG, zCaption AS ASCIIZ, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL w AS LONG, BYVAL h AS LONG, BYVAL dwStyle AS DWORD) AS DWORD LOCAL hCtrl AS DWORD LOCAL hInstance AS DWORD hInstance = GetWindowLongA (hWndMain, %GWL_HINSTANCE) hCtrl = CreateWindowExA(%WS_EX_CLIENTEDGE, "Edit", zCaption, dwStyle, x, y, w, h, hParent, nID, hInstance, BYVAL %NULL) 'DisableXPThemeControl hCtrl 'IF hCtrl THEN SendMessage(hCtrl, %WM_SETFONT, gP.usefont, 0) FUNCTION = hCtrl END FUNCTION FUNCTION addProgress(BYVAL hParent AS DWORD, BYVAL nID AS LONG, zCaption AS ASCIIZ, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL w AS LONG, BYVAL h AS LONG, BYVAL dwStyle AS DWORD) AS DWORD LOCAL hCtrl AS DWORD LOCAL hInstance AS DWORD hInstance = GetWindowLongA (hWndMain, %GWL_HINSTANCE) hCtrl = CreateWindowExA (0, "MsCtls_Progress32", zCaption, dwStyle, x, y, w, h, hParent, nID, hInstance, BYVAL %NULL) 'DisableXPThemeControl hCtrl 'IF hCtrl THEN SendMessage(hCtrl, %WM_SETFONT, gP.usefont, 0) '%WS_EX_TRANSPARENT FUNCTION = hCtrl END FUNCTION '_________________________________________________________________ ' ' FUNCTION addButton '_________________________________________________________________ FUNCTION addButton( _ BYVAL hParent AS DWORD _ , BYVAL nID AS LONG _ , zCaption AS ASCIIZ _ , BYVAL x AS LONG _ , BYVAL y AS LONG _ , BYVAL w AS LONG _ , BYVAL h AS LONG _ , BYVAL dwStyle AS DWORD _ ) AS DWORD LOCAL hCtrl AS DWORD LOCAL hInstance AS DWORD hInstance = GetWindowLongA (hWndMain, %GWL_HINSTANCE) hCtrl = CreateWindowExA( _ 0 _ , "Button" _ , zCaption _ , dwStyle _ , x, y, w, h _ , hParent _ , nID _ , hInstance _ , BYVAL %NULL) 'DisableXPThemeControl hCtrl 'IF hCtrl THEN SendMessageA(hCtrl, %WM_SETFONT, gP.usefont, 0) FUNCTION = hCtrl END FUNCTION '_________________________________________________________________ ' ' FUNCTION MuteMicrophone '_________________________________________________________________ FUNCTION MuteMicrophone AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN ' // Do whathever you wish, e.g. SetMasterVolumeLevel, SetMute, etc. ' // See available methods at http://msdn.microsoft.com/en-us/library/windows/desktop/dd370892%28v=vs.85%29.aspx xhr = gpIAudioEndpointVolumeMicrophone.SetMute(%TRUE, BYVAL %NULL) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to mute default microphone.") ? "Unable to set mute state on default microphone" ELSE ' "Default microphone muted successfully!" giMicroMute = 1 'CALL PutPeriodOnMarque END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION UnMuteMicrophone '_________________________________________________________________ FUNCTION UnMuteMicrophone AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN ' // Do whathever you wish, e.g. SetMasterVolumeLevel, SetMute, etc. ' // See available methods at http://msdn.microsoft.com/en-us/library/windows/desktop/dd370892%28v=vs.85%29.aspx xhr = gpIAudioEndpointVolumeMicrophone.SetMute(%FALSE, BYVAL %NULL) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to unmute default microphone.") ? "Unable to set unmute state on default microphone" ELSE ' "Default microphone unmuted successfully!" giMicroMute = 0 'INCR giTestIt 'IF RecognitionStatus = 1 THEN ' CALL PutQuestionMarkOnMarque 'ELSE ' 'recognition is not enabled ' IF ISTRUE ISOBJECT(oRecoContext) THEN ' CALL PutTildeOnMarque ' ELSE ' CALL PutEqualSignOnMarque ' END IF 'END IF END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION SetVolumeMicrophone '_________________________________________________________________ FUNCTION SetVolumeMicrophone(BYVAL MicroScalar AS SINGLE) AS LONG LOCAL xhr AS LONG IF giMicrophone = 1 THEN IF ISOBJECT(gpIAudioEndpointVolumeMicrophone) THEN ' // Do whathever you wish, e.g. SetMasterVolumeLevel, SetMute, etc. ' // See available methods at http://msdn.microsoft.com/en-us/library/windows/desktop/dd370892%28v=vs.85%29.aspx xhr = gpIAudioEndpointVolumeMicrophone.SetMasterVolumeLevelScalar(MicroScalar, BYVAL %NULL) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to set scalar on default microphone.") ? "Unable to set volume state on default microphone" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone volume set successfully!" END IF END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION MicrophoneCheck new 2020 MAY 06 new '_________________________________________________________________ FUNCTION MicrophoneCheck AS LONG LOCAL xhr AS LONG LOCAL fMinDb AS SINGLE 'float fMinDb LOCAL fMaxDb AS SINGLE 'float fMaxDb LOCAL fStepDb AS SINGLE 'float fStepDb LOCAL pfCurrentDb AS SINGLE 'float pfCurrentDb ' Get enumerator for audio endpoint devices. gpIMMDeviceEnumMicrophone = NEWCOM CLSID CLSID_MMDeviceEnumerator IF ISNOTHING(gpIMMDeviceEnumMicrophone) THEN ? "Unable to create audio device enumerator." FUNCTION = 0 EXIT FUNCTION END IF ' // Enumerate the audio endpoints of interest (in this case audio capture endpoints) ' // The flags that can be used are: ' // %EDataFlow_eRender (for audio output endpoints), ' // %EDataFlow_eCapture (for audio capture endpoints), ' // %EDataFlow_eAll (for all audio endpoints) ' // %ERole_eConsole = Games, system notification sounds, and voice commands. ' // %ERole_eMultimedia = Music, movies, narration, and live music recording. ' // %ERole_eCommunications = Voice communications (talking to another person). '%DEVICE_STATE_ACTIVE giMicrophoneHr = gpIMMDeviceEnumMicrophone.GetDefaultAudioEndpoint(%EDataFlow_eCapture, %ERole_eConsole, gpIMMDeviceMicrophone) IF FAILED(giMicrophoneHr) THEN ? "Unable to find default microphone device." FUNCTION = 0 EXIT FUNCTION END IF xhr = gpIMMDeviceMicrophone.Activate(IID_IAudioEndpointVolume, %CLSCTX_INPROC_SERVER, BYVAL %NULL, gpIAudioEndpointVolumeMicrophone) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to activate a microphone.") ? "Unable to activate default microphone" FUNCTION = 0 EXIT FUNCTION ELSE ' "Default microphone activated successfully!" ' // Get the device identifier xhr = gpIMMDeviceMicrophone.GetId(pDevId) IF pDevId THEN XFill = "Device id = " & @pDevId 'Device id = {0.0.1.00000000}.{be4cea6b-aba4-4420-8e08-dbfb7a6be10c} 'call COPY_TO_CLIPBOARD CoTaskMemFree(pDevId) END IF ' // Get the device name gsTheMicrophoneName = AfxGetDeviceName(gpIMMDeviceMicrophone) '? gsTheMicrophoneName 'Get the endpoint device's IDeviceTopology interface. xhr = gpIMMDeviceMicrophone.Activate(IID_IDeviceTopology, %CLSCTX_ALL, BYVAL %NULL, pDeviceTopology) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get microphone topology.") ? "Unable to get microphone topology." FUNCTION = 0 EXIT FUNCTION END IF 'The device topology for an endpoint device always 'contains just one connector (connector number 0). xhr = pDeviceTopology.GetConnector(0, pConnFrom) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get the connector info.") ? "Unable to get the connector info." FUNCTION = 0 EXIT FUNCTION END IF pDeviceTopology = NOTHING 'Make sure that this is a capture device. xhr = pConnFrom.GetDataFlow(pflow) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get connector flow data.") ? "Unable to get connector flow data." FUNCTION = 0 EXIT FUNCTION ELSE 'For example, a typical rendering device on an adapter has a connector 'with data-flow direction "In" through which the Windows audio engine 'streams PCM data into the device. The same device has a connector with 'data-flow direction "Out" through which the device transmits an audio 'signal to speakers or headphones. '%DataFlow_In = 0 Input stream. The audio stream flows into the device through the connector. '%DataFlow_Out = 1 Output stream. The audio stream flows out of the device through the connector. SELECT CASE pFlow CASE 0 'In 'Error -- this is a rendering device. 'EXIT_ON_ERROR(xhr = %AUDCLNT_E_WRONG_ENDPOINT_TYPE) 'CALL SHOW_NOTES_NO_WAIT("Error! The connector flow data was wrong.") ? "Error! The connector flow data was wrong." FUNCTION = 0 EXIT FUNCTION CASE 1 'Out '? "DataFlow is out stream." END SELECT END IF '-------------------------------------- ComponentName = "Microphone" pfCurrentDb = 0 CALL SelectCaptureDevice IF ISOBJECT(pIaudioVolumeLevel) THEN pIaudioVolumeLevel.GetLevelRange(0, fMinDb, fMaxDb, fStepDb) '? "VMIN" & STR$(fMinDb) '? "VMAX" & STR$(fMaxDb) '? "VSTEP" & STR$(fStepDb) pIaudioVolumeLevel.GetLevel(0, pfCurrentDb) '? "VCUR" & STR$(pfCurrentDb) pfCurrentDb = (INT(10 * ((pfCurrentDb + 34.5)/46.5) * 100)) /10 'rescale values SELECT CASE pfCurrentDb CASE 0 TO 17.2 '? STR$(pfCurrentDb) SCALER = 0 CASE 17.3 TO 28.4 '? STR$(pfCurrentDb) SCALER = .05 CASE 28.5 TO 36.8 '? STR$(pfCurrentDb) SCALER = .1 CASE 36.9 TO 43.4 '? STR$(pfCurrentDb) SCALER = .15 CASE 43.5 TO 48.9 '? STR$(pfCurrentDb) SCALER = .2 CASE 49 TO 53.7 '? STR$(pfCurrentDb) SCALER = .25 CASE 53.8 TO 57.8 '? STR$(pfCurrentDb) SCALER = .3 CASE 57.9 TO 61.5 '? STR$(pfCurrentDb) SCALER = .3 CASE 61.6 'to 67.7 '? STR$(pfCurrentDb) SCALER = .4 CASE 64.8 'to 67.7 '? STR$(pfCurrentDb) SCALER = .45 CASE 67.8 TO 70.5 '? STR$(pfCurrentDb) SCALER = .5 CASE 70.6 TO 73 '? STR$(pfCurrentDb) SCALER = .55 CASE 73.1 TO 75.4 '? STR$(pfCurrentDb) SCALER = .6 CASE 75.5 TO 78 '? STR$(pfCurrentDb) SCALER = .65 CASE 78.1 TO 80.7 '? STR$(pfCurrentDb) SCALER = .7 CASE 80.8 TO 83.8 '? STR$(pfCurrentDb) SCALER = .75 CASE 83.9 TO 87.1 '? STR$(pfCurrentDb) SCALER = .8 CASE 87.2 TO 90.8 '? STR$(pfCurrentDb) SCALER = .855 CASE 90.9 TO 95 '? STR$(pfCurrentDb) SCALER = .9 CASE 95.1 TO 99.9 '? STR$(pfCurrentDb) SCALER = .95 CASE 100 '? STR$(pfCurrentDb) SCALER = 1 CASE ELSE '? STR$(pfCurrentDb) SCALER = pfCurrentDb END SELECT ELSE ? "There is no audio level object!" END IF '-------------------------------------- ComponentName = "Microphone Boost" pIaudioVolumeLevel = NOTHING pfCurrentDb = 0 CALL SelectCaptureDevice IF ISOBJECT(pIaudioVolumeLevel) THEN '? "made it here" pIaudioVolumeLevel.GetLevelRange(0, fMinDb, fMaxDb, fStepDb) '? "VMIN" & STR$(fMinDb) '? "VMAX" & STR$(fMaxDb) '? "VSTEP" & STR$(fStepDb) pIaudioVolumeLevel.GetLevel(0, pfCurrentDb) '? "VCUR" & STR$(pfCurrentDb) pIaudioVolumeLevel.SetLevel(0, pfCurrentDb, BYVAL %NULL) SCALER_MB = pfCurrentDb END IF pConnFrom = NOTHING '\\\\\\\\\\\\\\\ 'Get the endpoint device's IAudioMeterInformation interface. xhr = gpIMMDeviceMicrophone.Activate(IID_IAudioMeterInformation, %CLSCTX_ALL, BYVAL %NULL, gpMeterInfo) IF FAILED(xhr) THEN 'CALL SHOW_NOTES_NO_WAIT("Unable to get peak meter info.") ? "Unable to get peak meter info." FUNCTION = 0 EXIT FUNCTION END IF END IF FUNCTION = 1 END FUNCTION '_________________________________________________________________ ' ' FUNCTION AfxGetDeviceName Jarvis '_________________________________________________________________ ' ================================================================ ' Helper function to retrieve the friendly name of the ' audio device. ' ================================================================ FUNCTION AfxGetDeviceName (BYVAL pDev AS IMMDevice) AS WSTRING LOCAL hr AS LONG LOCAL pPropStore AS IPropertyStore hr = pDev.OpenPropertyStore(%STGM_READ, pPropStore) IF FAILED(hr) THEN EXIT FUNCTION LOCAL friendlyName AS PROPVARIANT PropVariantInit(friendlyName) hr = pPropStore.getValue(DEVPKEY_Device_FriendlyName, friendlyName) IF FAILED(hr) THEN EXIT FUNCTION LOCAL wszDevName AS WSTRINGZ * 128 PropVariantToString(friendlyName, wszDevName, 128) FUNCTION = wszDevName PropVariantClear(friendlyName) END FUNCTION '_________________________________________________________________ ' ' SUB COPY_TO_CLIPBOARD EjectDrive '_________________________________________________________________ SUB COPY_TO_CLIPBOARD CopyToClipBoard 0, BYCOPY XFill XFill = "" END SUB '_________________________________________________________________ ' ' FUNCTION CopyToClipBoard VER4 '_________________________________________________________________ FUNCTION CopyToClipBoard(HParent AS LONG, MyText AS STRING) AS LONG LOCAL HptrMemory AS DWORD LOCAL HptrAsciiz AS ASCIIZ PTR OpenClipboard HParent IF ISFALSE(EmptyClipboard) THEN CloseClipboard EXIT FUNCTION END IF HptrMemory = GlobalAlloc(%GHND, ((LEN(MyText) + 1) + TALLY(MyText, ANY ($CRLF & $TAB)))) HptrAsciiz = GlobalLock(HptrMemory) @HptrAsciiz = MyText GlobalUnlock HptrMemory FUNCTION = SetClipboardData(%CF_TEXT, HptrMemory) CloseClipboard END FUNCTION '_________________________________________________________________ '_________________________________________________________________ ' ' Processes pending Windows messages. VER4 ' Call this procedure if you are performing a tight ' FOR/NEXT or DO/LOOP and need to allow ' your application to be responsive to user input. ' Modified version of AfxPumpMessages '_________________________________________________________________ SUB MyPumpMessages(BYVAL xTimes AS LONG) EXPORT '///////////////////////////////////////////////////////////// 'Do not want to remove the WM_QUIT message from message que. ' IF GlobalVariableTest86 = 1 THEN EXIT SUB '///////////////////////////////////////////////////////////// LOCAL Ix AS LONG IF giPumpingMessages = 1 THEN EXIT SUB giPumpingMessages = 1 ' IF GlobalVariableTestOn THEN IF xTimes <= 0 THEN xTimes = 1 FOR Ix = 1 TO xTimes CALL PeekRemoveTranslateDispatchMessage ' IF GlobalVariableTest86 = 1 THEN GOTO NoMoreNeeded NEXT Ix ' END IF NoMoreNeeded: giPumpingMessages = 0 END SUB '_________________________________________________________________ ' ' SUB PeekRemoveTranslateDispatchMessage VER4 '_________________________________________________________________ SUB PeekRemoveTranslateDispatchMessage '///////////////////////////////////////////////////////////// 'Do not want to remove the WM_QUIT message from message que. ' IF GlobalVariableTest86 = 1 THEN EXIT SUB '///////////////////////////////////////////////////////////// 'Could use this to signal main message loop to close 'PostThreadMessageA (GetCurrentThreadID, %WM_QUIT, 0, 0) ' Signal Quit to Msg Loop IF giPRTDMessage = 1 THEN EXIT SUB giPRTDMessage = 1 STATIC Msg AS tagMsg IF PeekMessageA(Msg, %NULL, %NULL, %NULL, %PM_REMOVE) THEN TranslateMessage Msg DispatchMessageA Msg END IF giPRTDMessage = 0 END SUB '//----------------------------------------------------------- '// This function traverses the data path that extends from the '// endpoint device to the system bus (for example, PCI) '// or external bus (USB). If the function discovers a MUX '// (input selector) in the path, it selects the MUX input '// that connects to the stream from the endpoint device. '// In this case we are looking for the Microphone or Microphone '// Boost parts. '//----------------------------------------------------------- 'Limits of Device Topology 'Where (con) is a connector 'microphone -> endpoint device B (con) physical external ' '-> Input Multiplexer Device (Topology Filter) ' (con) physical external IPart & IConnector ' subunit Mute -> IPart & ISubUnit ' subunit Vol -> IPart & ISubUnit ' subunit MUX -> IPart & ISubUnit ' (Con) Software Fixed IPart & IConnector ' '-> Wave Capture Device (Wave Filter) ' (Con) Software Fixed IPart & IConnector ' subunit ADC IPart & ISubUnit ' (Con) Software IO IPart & IConnector ' '-> System Bus Wave-in Stream (DMA) FUNCTION SelectCaptureDevice() AS LONG LOCAL hr AS LONG hr = %S_OK pIaudioVolumeLevel = NOTHING IF ISOBJECT(pConnFrom) THEN 'continue ELSE GOTO ExitHere END IF '// Outer loop: Each iteration traverses the data path '// through a device topology starting at the input '// connector and ending at the output connector. WHILE %TRUE IF giProgStat = 0 THEN GOTO ExitHere hr = pConnFrom.IsConnected(bConnected) IF FAILED(hr) THEN GOTO ExitHere '// Does this connector connect to another device? IF bConnected = %FALSE THEN '// This is the end of the data path that '// stretches from the endpoint device to the '// system bus or external bus. Verify that '// the connection type is Software_IO. hr = pConnFrom.GetType(connType) IF FAILED(hr) THEN GOTO ExitHere IF connType = %ConnectorType_Software_IO THEN '? "Finished looking for connections." EXIT LOOP '// finished END IF IF FAILED(hr = %E_FAIL) THEN GOTO ExitHere END IF '// Get the connector in the next device topology, '// which lies on the other side of the connection. hr = pConnFrom.GetConnectedTo(pConnTo) IF FAILED(hr) THEN GOTO ExitHere '// Get the connector's IPart interface. hr = pConnTo.QueryInterface( _ IID_IPart, _ BYVAL VARPTR(pPartPrev)) IF FAILED(hr) THEN GOTO ExitHere pConnTo = NOTHING '// Inner loop: Each iteration traverses one link in a '// device topology and looks for input multiplexers. WHILE %TRUE IF giProgStat = 0 THEN GOTO ExitHere MyPumpMessages(2000) '// Follow downstream link to next part. hr = pPartPrev.EnumPartsOutgoing(ppParts) IF FAILED(hr) THEN GOTO ExitHere hr = ppParts.GetPart(0, pPartNext) ppParts = NOTHING IF FAILED(hr) THEN GOTO ExitHere hr = pPartNext.GetPartType(pPartType) IF FAILED(hr) THEN GOTO ExitHere IF SUCCEEDED(pPartNext.GetName(pName)) THEN '? @pName '=Microphone or Microphone Boost 'Failure of the following call means only that 'the part is not a boost (microphone boost). IF UCASE$(ComponentName) <> UCASE$(@pName) THEN '? "Not a match." ELSE '? "The part name matched." 'get IAudioVolumeLevel to control volume hr = pPartNext.Activate(%CLSCTX_ALL, IID_IAudioVolumeLevel, pIaudioVolumeLevel) GOTO ExitHere END IF CoTaskMemFree(pName) END IF '? "Try again..." SELECT CASE pPartType CASE %PartType_Connector '=0 '? "Connector found." '// We've reached the output connector that '// lies at the end of this device topology. hr = pPartNext.QueryInterface( _ IID_IConnector, _ BYVAL VARPTR(pConnFrom)) IF FAILED(hr) THEN GOTO ExitHere pPartPrev = NOTHING pPartNext = NOTHING EXIT LOOP CASE %PartType_Subunit '=1 '? "Subunit found." END SELECT '// Failure of the following call means only that '// the part is not a MUX (input selector). hr = pPartNext.Activate( _ %CLSCTX_ALL, _ IID_IAudioInputSelector, _ pSelector) IF hr = %S_OK THEN ? "The MUX was found." '// We found a MUX (input selector), so select '// the input from our endpoint device. LOCAL localId AS DWORD hr = pPartPrev.GetLocalId(localId) IF FAILED(hr) THEN GOTO ExitHere hr = pSelector.SetSelection(localId, BYVAL %NULL) IF FAILED(hr) THEN GOTO ExitHere pSelector = NOTHING END IF pPartPrev = NOTHING pPartPrev = pPartNext pPartNext = NOTHING WEND WEND ExitHere: ppParts = NOTHING pConnTo = NOTHING pPartPrev = NOTHING pPartNext = NOTHING pSelector = NOTHING FUNCTION = hr END FUNCTION
Tags: None
Leave a comment: