gritts Posted May 11, 2022 Share Posted May 11, 2022 I am working on a script that I hope expand on. Its end goal is a scaled down version of the Voicemeeter.Remote. Second benefit is to better learn DLLCalls. To say I am weak in this area is probably putting it mildly. Below is my current basic version of the script I am using to test / learn with. When the line with "VBVMR_GetParameterFloat" is executed, I get the error about being unable to use the DLL file. The other commands within the script work without error (though getting the type and version has unexpected results). I can see the API is being accessed as Voicemeeter has indicators when one is connected. expandcollapse popup#AutoIt3Wrapper_UseX64=y #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.14.5 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #Include <array.au3> Local $hDll = DllOpen("C:\Program Files (x86)\VB\Voicemeeter\VoicemeeterRemote64.dll") If @error Then ConsoleWriteError('Error DllOpen: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf $str1stat = 255 DllCall($hDll,"NONE","VBVMR_Login") If @error Then ConsoleWriteError('Error VBVMR_Login: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf DllCall($hDll,"NONE","VBVMR_IsParametersDirty") If @error Then ConsoleWriteError('Error VBVMR_IsParametersDirty: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf ;~ DllCall($hDll,"STR","VBVMR_GetParameterFloat","APTR","Strip[1].A1","INT",$str1stat) If @error Then ConsoleWriteError('Error VBVMR_GetParameterFloat: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf ;~ ConsoleWrite("Error: " & @error & " Extended: " & @extended & @CRLF) ;~ ConsoleWrite($str1stat & @CRLF) $aVMType=DllCall($hDll,"LONG","VBVMR_GetVoicemeeterType") If @error Then ConsoleWriteError('Error VBVMR_GetVoicemeeterType: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf $aVMVer=DllCall($hDll,"LONG_PTR","VBVMR_GetVoicemeeterVersion") If @error Then ConsoleWriteError('Error VBVMR_GetVoicemeeterVersion: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf _ArrayDisplay($aVMType) _ArrayDisplay($aVMVer) DllCall($hDll, "NONE","VBVMR_Logout") If @error Then ConsoleWriteError('Error VBVMR_Logout: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf DllClose($hDll) I have attached the current .h file for the version of Voicemeeter I am using as well. If I have tried different types (STR,INT,etc) within the DLL call. The script will either return an unknown "return type" or the DLL open will crash. (Sits for up to 30 seconds then errors). I have attempted to adopt this from other code I have seen on the internet but I suspect I just lack understanding when translating from the .h file to what is needed here. VoicemeeterRemote.h Link to comment Share on other sites More sharing options...
UEZ Posted May 11, 2022 Share Posted May 11, 2022 I'm not familiar with C/C++ but have you tried the cdecl call convention already? Something like: DllCall($hDll,"NONE:cdecl","VBVMR_Login") Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
gritts Posted May 11, 2022 Author Share Posted May 11, 2022 I did give the ":cdecl" option a try on the line in question but still received the same results.. ; This line results in an Error code 1 even with the "cdecl" option DllCall($hDll,"STR:cdecl","VBVMR_GetParameterFloat","APTR","Strip[1].A1","INT",$str1stat) The other DLLCalls work without issue. Link to comment Share on other sites More sharing options...
Nine Posted May 11, 2022 Share Posted May 11, 2022 Seems your call does not make sense. "APTR" is not a valid type, and further more the param "Strip[1].A1" is everything but valid. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
gritts Posted May 13, 2022 Author Share Posted May 13, 2022 I agree the "APTR" type is not valid. When I change to "PTR", I receive this error when attempting to run " !>18:31:08 AutoIt3.exe ended.rc:-1073741819" As to the "Strip[1].A1" being invalid, that is how Voicemeeter references the first "control" button A1. That form of reference does work in another scripting language. I wanted to stick with AutoIt since I was a bit more familiar with it. Perhaps you can tell me what I missed to make that param incorrect? I have also modified it to "'Strip[1].A1'". From the other scripting language, this line works" "Result := DllCall("VoicemeeterRemote64\VBVMR_GetParameterFloat", "AStr", "Strip[1].A1", "Ptr", &str1stat, "Int")" Attached a screenshot for reference. Link to comment Share on other sites More sharing options...
Danyfirex Posted May 14, 2022 Share Posted May 14, 2022 This should work: Local $aCall=DllCall($hDll,"long","VBVMR_GetParameterFloat","str","Strip[1].A1","float*",0) Local $iParameterFloat=$aCall[2] Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
gritts Posted May 15, 2022 Author Share Posted May 15, 2022 On 5/14/2022 at 8:23 AM, Danyfirex said: This should work: Local $aCall=DllCall($hDll,"long","VBVMR_GetParameterFloat","str","Strip[1].A1","float*",0) Local $iParameterFloat=$aCall[2] Saludos This is producing much more promising results. I am able to use "_ArrayDisplay($aCall)" and see results. The status of the "A1" control isn't being displayed correctly. Looking at the other scripting tool, I see a function called "NumGet" is being used. The description of the function says "Returns the binary number stored at the specified address+offset." (ie Number := NumGet(VarOrAddress , Offset := 0, Type := "UPtr") ) I looked at the binary functions (BinaryToString) and the Binary UDF posted by @Ward in the past and either they are not what I need or I just don't understand well enough to follow. Link to comment Share on other sites More sharing options...
Danyfirex Posted May 15, 2022 Share Posted May 15, 2022 what result you get and what should it be? Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
gritts Posted May 15, 2022 Author Share Posted May 15, 2022 1 hour ago, Danyfirex said: what result you get and what should it be? Saludos I included a screenshot of what I see. If the A1 "control" is active, I expect to have a numeric 1 returned and likewise if it is inactive I expect a numeric 0 returned. My code segment as it is now... $aCall = DllCall($hDll,"float","VBVMR_GetParameterFloat","str","Strip[1].A1","float*",0) If @error Then ConsoleWriteError('Error VBVMR_GetParameterFloat: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf $iParameterFloat=$aCall[2] MsgBox(0,"$iParameterFloa",$iParameterFloat) _ArrayDisplay($aCall) Thank you for assisting me... 😊 Link to comment Share on other sites More sharing options...
Danyfirex Posted May 15, 2022 Share Posted May 15, 2022 But documentation says it returns a float: long __stdcall VBVMR_GetParameterFloat(char * szParamName, float * pValue); try this: Local $tFloat=DllStructCreate("float value") $aCall = DllCall($hDll,"long","VBVMR_GetParameterFloat","str","Strip[1].A1","ptr",DllStructGetPtr($tFloat)) ConsoleWrite($tFloat.value) Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
gritts Posted May 16, 2022 Author Share Posted May 16, 2022 16 hours ago, Danyfirex said: But documentation says it returns a float: long __stdcall VBVMR_GetParameterFloat(char * szParamName, float * pValue); try this: Local $tFloat=DllStructCreate("float value") $aCall = DllCall($hDll,"long","VBVMR_GetParameterFloat","str","Strip[1].A1","ptr",DllStructGetPtr($tFloat)) ConsoleWrite($tFloat.value) Saludos I agree, the .h says it returns a float. I tried your snippet of code, replacing my previous attempt. I am still seeing "0" regardless if the control is selected or not. For grins, I changed "long" to "float" to test and received the same result. Link to comment Share on other sites More sharing options...
Danyfirex Posted May 16, 2022 Share Posted May 16, 2022 I would like to check this deeply. PM me. I could probably get remote access and do some tests to get a solution. Saludos Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut Link to comment Share on other sites More sharing options...
gritts Posted May 17, 2022 Author Share Posted May 17, 2022 I added a couple more ConsoleWrites to the code you provided yesterday. The DllStructCreate seems to be doing something... Below are 2 results, one as type "long" and the other as type "float". As type "long"... $aCall[0]: 0 $aCall[1]: Strip[1].A1 $aCall[2]: 0x000001F74AEA3AE0 $tFloat.value Output: 0 As type "float"... $aCall[0]: 0 $aCall[1]: Strip[1].A1 $aCall[2]: 0x000001F74AEA3AE0 $tFloat.value Output: 0 In both instances the "A1" control is set to active. ; adapted code Local $tFloat=DllStructCreate("float value") $aCall = DllCall($hDll,"float","VBVMR_GetParameterFloat","str","Strip[1].A1","ptr",DllStructGetPtr($tFloat)) ConsoleWrite("$aCall[0]: " & $aCall[0] & @CRLF & "$aCall[1]: " & $aCall[1] & @CRLF & "$aCall[2]: " & $aCall[2] & @CRLF) ConsoleWrite("$tFloat.value Output: " & $tFloat.value & @CRLF) (Face palm moment) I suppose attaching the RemoteAPI doc might help some as well? Link to product site: https://vb-audio.com/Voicemeeter/ VoicemeeterRemoteAPI.pdf Link to comment Share on other sites More sharing options...
TheXman Posted May 17, 2022 Share Posted May 17, 2022 (edited) Danyfirex's first suggestion for VBVMR_GetParameterFloat, where he used float* for the second parameter, works fine. The one I use is very similar except it is set up as an API wrapper function (see below). You keep referencing "Strip[1].A1" for the parameter. You're aware that you are referencing the 2nd strip, not the first one, since the strip indexes starts at 0, right? (See the Input Strip Parameters section in the API PDF for details) Could that be the reason you aren't seeing the expected value? The image below shows the test settings on the first strip in my Voicemeeter (not Voicemeeter Banana): When I run my script against it, using my API wrappers, I get the following info written to the console: DllOpen successful VBVMR_Login successful VBVMR_IsParametersDirty = False VBVMR_GetVoicemeeterType = VoiceMeeter VBVMR_GetVoicemeeterVersion = 1.0.8.2 Strip[0].Color_y = +0.90 Strip[0].Color_x = -0.15 Strip[0].Mono = 1 VBVMR_Logout executed DllClose executed The 3 strip parameters, in the console output above, uses the following API wrapper function in my script. As you can see, it passes back valid float values. For example, I used VBVMR_GetParameterFloat("Strip[0].Mono") in my test script to get the first strips Mono setting. Func VBVMR_GetParameterFloat($sParamName) Local $aResult ;Call API $aResult = DllCall($ghVMDll, "long", "VBVMR_GetParameterFloat", _ "str" , $sParamName, _ "float*", 0) If @error Then Return SetError(-99, @error, -99.0) If $aResult[0] <> 0 Then Return SetError($aResult[0], 0, -99.0) Return $aResult[2] EndFunc This a sample of how I called the wrapper function in my test script: ;Display Strip[0].Color_y value $sParam = "Strip[0].Color_y" $fValue = VBVMR_GetParameterFloat($sParam) If @error Then MsgBox($MB_ICONWARNING + $MB_TOPMOST, "ERROR", _ "VBVMR_GetParameterFloat error occurred." & @LF & @LF & _ "@error = " & @error & @LF & _ "@extended = " & @extended) Exit EndIf ConsoleWrite(StringFormat("%-27s = %+0.2f", $sParam, $fValue) & @CRLF) For the record, all of the VBVMR APIs, except 1, pass back a LONG return code. All of the DllCalls in your original post that have "NONE" as the return code, should have "LONG". For instance, the VBVMR_Login declaration in the header file is: /** @name Communication Login / logout * @{ */ /** @brief Open Communication Pipe With Voicemeeter (typically called on software startup). @return : 0: OK (no error). 1: OK but Voicemeeter Application not launched. -1: cannot get client (unexpected) -2: unexpected login (logout was expected before). */ long __stdcall VBVMR_Login(void); So the corresponding AutoIt DllCall would be something like: $aResult = DllCall($ghVMDll, "long", "VBVMR_Login") If you aren't correctly defining and checking the return code after executing the API, then it is very difficult to tell if the API call was successful or not. If it wasn't, it's the return code that will let you know why. Lastly, there are several "return values" that you need to be aware of when using DllCalls. All of them are important and, in my opinion, all should be checked. There's @error and the array returned by the DllCall function itself. There's the return code/value that is returned in array[0] after a successful API call, if it has a return code defined. And there's the parameter values passed back from the API function call, if any exist. So when you refer the return codes and values, you need to be specific as to which ones you are referring to. Looking at some of your previous posts, you seems to be getting the return code from the API function mixed up with the parameter values that are passed back from the API call. Hopefully that helps. Edited May 17, 2022 by TheXman Added a sample API wrapper call; Reduce image size Danyfirex 1 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
gritts Posted May 18, 2022 Author Share Posted May 18, 2022 Thank you @TheXman . You are right about the "Strip[1].A1". I will call it a face-palm moment. I was looking an a different script and forgot the numbering started at 0. Thank you very much for going into detail with how you use AutoIt with Voicemeeter Banana. Using what @Danyfirex provided ( DllCall($hDll,"long","VBVMR_GetParameterFloat","str","Strip[1].A1","float*",0) ) and changing the return types to "long", I got slightly different results. For a brief bit, executing the script would return the opposite status of "A1". So if it was enabled, I would see "0", disabled showed "1". This didn't make sense to me. I rebooted my PC on the off chance the testing left things in an odd state. That did not fix it. When I run the script after rebooting, it seems to be pot luck whether I get a correct status back. I have tried getting the state of "mono" and "B1" with minimal luck. I might get the correct state initially then after changing the setting. After that, no matter how often I change the setting or run the script, the same value is returned. For example, "A1" could be enabled but the script returns disabled. It's almost as if the DLL is not really connecting to Voicemeeter. I have adopted your function and error checking in the hopes of getting more detail. In this case, no errors are being reported with how my script is now. expandcollapse popup#cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.14.5 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #AutoIt3Wrapper_UseX64=y #Include <array.au3> #Include <Binary.au3> $aCall = 0 ; Open DLL Local $hDll = DllOpen("C:\Program Files (x86)\VB\Voicemeeter\VoicemeeterRemote64.dll") If @error Then ConsoleWriteError('Error DllOpen: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf ; Login to the DLL $aResult = DllCall($hDll,"long","VBVMR_Login") If @error Then ConsoleWriteError('Error VBVMR_Login: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf ;_ArrayDisplay($aResult) ; Check parameter status $aResult = DllCall($hDll,"long","VBVMR_IsParametersDirty") If @error Then ConsoleWriteError('Error VBVMR_IsParametersDirty: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf ; Check option status $sParam = "Strip[1].A1" $fValue = VBVMR_GetParameterFloat($sParam) If @error Then MsgBox($MB_ICONWARNING + $MB_TOPMOST, "ERROR", _ "VBVMR_GetParameterFloat error occurred." & @LF & @LF & _ "@error = " & @error & @LF & _ "@extended = " & @extended) Exit EndIf ConsoleWrite("Results: " &$sParam&" - "&$fValue&@CRLF) ; Logout of DLL $aResult = DllCall($hDll, "long","VBVMR_Logout") If @error Then ConsoleWriteError('Error VBVMR_Logout: ' & ' Error: ' & @error & ' Extended: ' & @extended & @CR) EndIf ; Close DLL DllClose($hDll) Func VBVMR_GetParameterFloat($sParamName) Local $aResult ;Call API $aResult = DllCall($hDll, "long", "VBVMR_GetParameterFloat", _ "str" , $sParamName, _ "float*", 0) If @error Then Return SetError(-99, @error, -99.0) If $aResult[0] <> 0 Then Return SetError($aResult[0], 0, -99.0) Return $aResult[2] EndFunc Link to comment Share on other sites More sharing options...
TheXman Posted May 19, 2022 Share Posted May 19, 2022 (edited) If you are making a change to Voicemeeter parameters and then rerunning the script, then that is why you are seeing odd results. The APIs do not work that way. The only way you will accurately see your changes running your script that way would be to change the parameters, stop & restart Voicemeeter, and then rerun your script. If you want to be able to monitor parameter changes in real time, then you need to poll for changes by constantly checking for changes using the Is...Dirty API functions and when it is true, then do what you want to do. I do the polling using a loop, but I guess you could also use some sort of timer-based method like AdlibRegister(). In my test script, I check for parameter changes about 10 times a second. That seems to work fine. The log below is an example run of a script that monitors for parameter changes using the VBVMR_IsParametersDirty() API and displays a few specific parameters whenever it detects ANY parameter change. In the log below, you can see that I toggle A1, Mono, and Mute in the first strip. I then toggle them again in the same order. 2022-05-18 15:37:38 DllOpen successful 2022-05-18 15:37:38 VBVMR_Login successful 2022-05-18 15:37:38 2022-05-18 15:37:38 Strip[0].A1 = True 2022-05-18 15:37:38 Strip[0].Mono = True 2022-05-18 15:37:38 Strip[0].Mute = True 2022-05-18 15:37:44 2022-05-18 15:37:44 Strip[0].A1 = False 2022-05-18 15:37:44 Strip[0].Mono = True 2022-05-18 15:37:44 Strip[0].Mute = True 2022-05-18 15:37:46 2022-05-18 15:37:46 Strip[0].A1 = False 2022-05-18 15:37:46 Strip[0].Mono = False 2022-05-18 15:37:46 Strip[0].Mute = True 2022-05-18 15:37:48 2022-05-18 15:37:48 Strip[0].A1 = False 2022-05-18 15:37:48 Strip[0].Mono = False 2022-05-18 15:37:48 Strip[0].Mute = False 2022-05-18 15:37:50 2022-05-18 15:37:50 Strip[0].A1 = True 2022-05-18 15:37:50 Strip[0].Mono = False 2022-05-18 15:37:50 Strip[0].Mute = False 2022-05-18 15:37:51 2022-05-18 15:37:51 Strip[0].A1 = True 2022-05-18 15:37:51 Strip[0].Mono = True 2022-05-18 15:37:51 Strip[0].Mute = False 2022-05-18 15:37:52 2022-05-18 15:37:52 Strip[0].A1 = True 2022-05-18 15:37:52 Strip[0].Mono = True 2022-05-18 15:37:52 Strip[0].Mute = True 2022-05-18 15:37:54 2022-05-18 15:37:54 VBVMR_Logout executed 2022-05-18 15:37:54 DllClose executed My example script is below. Click "Reveal hidden contents" to view it. Spoiler This is the example script that created the log above. It is a crude, over-simplified, example written solely to conceptually show how the Voicemeeter APIs can be implemented. Of course there are many ways to do it. This is just one simple example. Note: Change the $VBVMR_DIR constant to point to where your VoiceMeeter is installed. The script runs continously. Press ESC to gracefully end the script. The script looks for ANY parameter changes. When ANY parameter is changed, it will just display the value of A1, Mono, and Mute in Strip 1. So it would be best to just modify those parameters to see them change in the log. expandcollapse popup#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #include <Constants.au3> ;========================================================================== ; Main Code Block ;========================================================================== Const $VBVMR_DIR = "C:\Program Files\VB\Voicemeeter" ; <== Modify as needed Global $ghVMDll = -1 ;Set up hotkey to end script HotKeySet("{ESC}", "exit_script") MsgBox($MB_ICONINFORMATION + $MB_TOPMOST, "VMR API EXAMPLE", "Press ESC to end the script.") ;Get handle to Dll (if successful, then register func to close handle on exit) $ghVMDll = DllOpen($VBVMR_DIR & (@AutoItX64 ? "\VoicemeeterRemote64.dll" : "\VoicemeeterRemote.dll")) If $ghVMDll = -1 Then Exit MsgBox($MB_ICONERROR + $MB_TOPMOST, "ERROR", "Unable to load Voicemeeter DLL") log_write("DllOpen successful" & @CRLF) ;Register exit routine to clean up OnAutoItExitRegister("on_autoit_exit") voicemeeter_api_example() ;========================================================================== ; Functions ;========================================================================== Func voicemeeter_api_example() Local $sParam = "" Local $fValue = 0.0 ;Login to Voicemeeter VBVMR_Login() If @error Then MsgBox($MB_ICONWARNING + $MB_TOPMOST, "ERROR", _ "VBVMR_Login error occurred." & @LF & @LF & _ "@error = " & @error & @LF & _ "@extended = " & @extended) Exit EndIf log_write("VBVMR_Login successful" & @CRLF) ;Continously check for changes While 1 If VBVMR_IsParametersDirty() Then log_write(@CRLF) ;Display Strip[0].A1 value $sParam = "Strip[0].A1" $fValue = VBVMR_GetParameterFloat($sParam) If @error Then MsgBox($MB_ICONWARNING + $MB_TOPMOST, "ERROR", _ "VBVMR_GetParameterFloat error occurred." & @LF & @LF & _ "@error = " & @error & @LF & _ "@extended = " & @extended) Exit EndIf log_write(StringFormat("%-14s = %s", $sParam, ($fValue <> 0)) & @CRLF) ;Display Strip[0].Mono value $sParam = "Strip[0].Mono" $fValue = VBVMR_GetParameterFloat($sParam) If @error Then MsgBox($MB_ICONWARNING + $MB_TOPMOST, "ERROR", _ "VBVMR_GetParameterFloat error occurred." & @LF & @LF & _ "@error = " & @error & @LF & _ "@extended = " & @extended) Exit EndIf log_write(StringFormat("%-14s = %s", $sParam, ($fValue <> 0)) & @CRLF) ;Display Strip[0].Mute value $sParam = "Strip[0].Mute" $fValue = VBVMR_GetParameterFloat($sParam) If @error Then MsgBox($MB_ICONWARNING + $MB_TOPMOST, "ERROR", _ "VBVMR_GetParameterFloat error occurred." & @LF & @LF & _ "@error = " & @error & @LF & _ "@extended = " & @extended) Exit EndIf log_write(StringFormat("%-14s = %s", $sParam, ($fValue <> 0)) & @CRLF) EndIf Sleep(100) WEnd EndFunc Func on_autoit_exit() log_write(@CRLF) ;Logout of voicemeeter VBVMR_Logout() log_write("VBVMR_Logout executed" & @CRLF) ;Close dll handle DllClose($ghVMDll) log_write("DllClose executed" & @CRLF) EndFunc Func exit_script() Exit EndFunc Func log_write($sMsg) Local $sDateTime = StringFormat("%s-%s-%s %02i:%02i:%02i", _ @YEAR, @MON, @MDAY, @HOUR, @MIN, @SEC) ConsoleWrite($sDateTime & " " & $sMsg) EndFunc ;=============== Voicemeeter Remote API Wrappers Below ============== Func VBVMR_Login() Local $aResult ;Call API $aResult = DllCall($ghVMDll, "long", "VBVMR_Login") If @error Then Return SetError(-99, @error, False) If $aResult[0] <> 0 Then Return SetError($aResult[0], 0, False) Return True EndFunc Func VBVMR_Logout() Local $aResult ;Call API $aResult = DllCall($ghVMDll, "long", "VBVMR_Logout") If @error Then Return SetError(-99, @error, False) If $aResult[0] <> 0 Then Return SetError($aResult[0], 0, False) Return True EndFunc Func VBVMR_IsParametersDirty() Local $aResult ;Call API $aResult = DllCall($ghVMDll, "long", "VBVMR_IsParametersDirty") If @error Then Return SetError(-99, @error, False) If $aResult[0] < 0 Then Return SetError($aResult[0], 0, False) Return ($aResult[0] ? True : False) EndFunc Func VBVMR_GetParameterFloat($sParamName) Local $aResult ;Call API $aResult = DllCall($ghVMDll, "long", "VBVMR_GetParameterFloat", _ "str" , $sParamName, _ "float*", 0) If @error Then Return SetError(-99, @error, -1.0) If $aResult[0] <> 0 Then Return SetError($aResult[0], 0, -1.0) Return $aResult[2] EndFunc Edited May 19, 2022 by TheXman Danyfirex and Werty 2 CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
TheXman Posted May 19, 2022 Share Posted May 19, 2022 @gritts I updated my last post by adding the example script that created the log. CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
gritts Posted May 21, 2022 Author Share Posted May 21, 2022 Thank you @TheXman. My day time job had me busy so I haven't had a moment to reply. I will look at your post in detail today. Link to comment Share on other sites More sharing options...
gritts Posted May 23, 2022 Author Share Posted May 23, 2022 After taking a look at your additional example and plinking around with my own code, I came up with the following tweak to my login function: Func VBVMR_Login($apiDLL) ; Login to the DLL Local $aResult $aResult = DllCall($apiDLL, "long", "VBVMR_Login") If @error Then Return SetError(-99, @error, -99.0) If $aResult[0] <> 0 Then Return SetError($aResult[0], 0, -99.0) Sleep(250) EndFunc ;==>VBVMR_Login Adding the Sleep function appears to have allowed the script to pause a little and then when I follow with the "VBVMR_GetParameterFloat" call, I get the values expected. I have tested this with the "A1" button and the "color" setting. Still tinkering but I suspect the more GetParamaterFloat calls I make between logout and login may require a longer sleep time. Learning as I go 😄. You mentioned... On 5/17/2022 at 5:56 PM, TheXman said: For the record, all of the VBVMR APIs, except 1, pass back a LONG return code. I attempted to pull the current version using "VBVMR_GetVoicemeeterVersion" using long as they type and "50332162" is what I get returned. I see in your example you appear to have converted the result you received into a decimal translation. Can you suggest a path I can take that might make sense? I appreciate all of the help you have provided so far and I was hoping I might figure this one out. My end goal for all of this is 2 fold. First is to learn about handling DLL files. Second is to create a smaller GUI (if at all) version of the VM Remote. I want to be able to capture the current settings, save them along with other versions then be able to call the settings on demand. (Like one for office Teams meeting, another for personal Discord, etc) Link to comment Share on other sites More sharing options...
TheXman Posted May 23, 2022 Share Posted May 23, 2022 (edited) 22 hours ago, gritts said: I attempted to pull the current version using "VBVMR_GetVoicemeeterVersion" using long as they type and "50332162" is what I get returned. . . . Can you suggest a path I can take that might make sense? Unless you were running the current version of Voicemeeter Potato at the time, I have no idea what "50332162" is or how you got it. Since I have no intention of guessing, I would suggest that you show the code that you attempted to execute and also say which Voicemeeter product was running at the time. With that, I can help you understand why your VBVMR_GetVoicemeeterVersion() didn't return the correct result. If you were running your script against the current version of Voicemeeter Banana, then VBVMR_GetVoicemeeterVersion() would've returned a LONG value containing 33555970, which after decoding would be "2.0.6.2". If you were running your script against the current version of Voicemeeter (not Voicemeeter Banana), then VBVMR_GetVoicemeeterVersion() would've returned a LONG value containing 16779266, which after decoding would be "1.0.8.2". As it says in the header file, the version is passed back as a 32-bit (4 byte) LONG value. To decode the version number, you get the decimal value of each of the 4 bytes. For example, the decimal value 33555978, is 0x0200060A (big endian). So the version number is 0x02 0x00 0x06 0x0A or v2.0.6.10 . My VBVMR_GetVoicemeeterVersion() API wrapper achieves this by using the BinaryMid() function, but it could be done in several different ways. Now that I've explained how to decode the LONG value into the x.x.x.x version number, why don't you try to decode 50332162 and see what you get. Edited May 24, 2022 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now