psynegy Posted January 19, 2010 Posted January 19, 2010 (edited) Hi everyone, I'm trying to get autoit to work with my brand new Behringer BCF2000. I've located the MIDI UDF (http://www.autoitscript.com/forum/index.php?showtopic=37072) but whilst this allows me to send the data for a MIDI note, I am struggling to work out how to adapt it to send the control change. Basically, I'm having trouble generating the output 'msg'. #include <MIDI.au3> $open = _MidiOutOpen() _midiOutShortMsg($open, 0x00517FB0) ;Data 1: 81/H51, Data 2: 127/H7F, MIDI Status: 176/HB0 MsgBox(0, "", "Waiting...") _midiOutclose($open) Any ideas? Edit: I've just found this: Private Function CreateMidiMsg(bytNote As Byte, bytVol As Byte, bytStatus As Byte) As Long ' ' Pack the data into a Long variable ' Byte 0 (LSB) = Status ' Byte 1 = Note ' Byte 2 = Volume ' Byte 3 = 00 ' CreateMidiMsg = (bytVol * (16 ^ 4)) CreateMidiMsg = CreateMidiMsg + (bytNote * (16 ^ 2)) CreateMidiMsg = CreateMidiMsg + bytStatus End Function I'm trying to make some sense of it, I'd definitely appreciate any pointers. Working with hexadecimal is a new thing to me. Edited January 19, 2010 by psynegy
PsaltyDS Posted January 20, 2010 Posted January 20, 2010 (edited) You don't have to work with the hex. Let the math do it for you: ; Function _CreateMidiMsg($iNote, $iVol, $iStatus) ; Where: All parameters have valid range 0 to 255 ; $iNote = Note value ; $iVol = Volume value ; $iStatus = Status value ; ; Packs the data into an INT32 format ; Byte 0 (LSB) = Status ; Byte 1 = Note ; Byte 2 = Volume ; Byte 3 = 00 ; ; Returns: On success = formatted INT32 MIDI message ; On failure = 0, @error = 1, @extended = number of parameter out of range Func _CreateMidiMsg($iNote, $iVol, $iStatus) Select Case $iNote > 255 Or $iNote < 0 Return SetError(1, 1, 0) Case $iVol > 255 Or $iVol < 0 Return SetError(1, 2, 0) Case $iStatus > 255 Or $iStatus < 0 Return SetError(1, 3, 0) EndSelect Local $iMidiMsg = $iVol * 2^16 ; Byte 2 $iMidiMsg += $iNote * 2^8 ; Byte 1 $iMidiMsg += $iStatus ; Byte 0 Return $iMidiMsg EndFunc Edit: Using it in you original script would look like this: expandcollapse popup#include <MIDI.au3> $open = _MidiOutOpen() ;Data 1: 81/H51, Data 2: 127/H7F, MIDI Status: 176/HB0 $iMsg = _CreateMidiMsg(127, 81, 176) ; vol = 127, note = 81, status = 176 _midiOutShortMsg($open, $iMsg) MsgBox(0, "", "Waiting...") _midiOutclose($open) ; Function _CreateMidiMsg($iNote, $iVol, $iStatus) ; Where: All parameters have valid range 0 to 255 ; $iNote = Note value ; $iVol = Volume value ; $iStatus = Status value ; ; Packs the data into an INT32 format ; Byte 0 (LSB) = Status ; Byte 1 = Note ; Byte 2 = Volume ; Byte 3 = 00 ; ; Returns: On success = formatted INT32 MIDI message ; On failure = 0, @error = 1, @extended = number of parameter out of range Func _CreateMidiMsg($iNote, $iVol, $iStatus) Select Case $iNote > 255 Or $iNote < 0 Return SetError(1, 1, 0) Case $iVol > 255 Or $iVol < 0 Return SetError(1, 2, 0) Case $iStatus > 255 Or $iStatus < 0 Return SetError(1, 3, 0) EndSelect Local $iMidiMsg = $iVol * 2^16 ; Byte 2 $iMidiMsg += $iNote * 2^8 ; Byte 1 $iMidiMsg += $iStatus ; Byte 0 Return $iMidiMsg EndFunc Note the potential confusion because the prototype function you provided lists the parameters in a different order from how they are packed in the message word. Edited January 20, 2010 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
psynegy Posted January 20, 2010 Author Posted January 20, 2010 I'll give it a try when I get back from work. Many thanks!
psynegy Posted January 20, 2010 Author Posted January 20, 2010 It seems that I've been barking up the wrong tree a little. I've spent hours trying to get that right (which is now perfect thanks to you) but my problems are deeper. I've been trying to get that working but for some reason the initial _MidiOutOpen command doesn't work. Func _midiOutOpen($devid=0,$callback=0,$instance=0,$flags=0) $struct = DllStructCreate("udword") $ret = Dllcall("winmm.dll","long","midiOutOpen","ptr",DllStructGetPtr($struct),"int",$devid,"long",$callback,"long",$instance,"long",$flags) if not @error Then MsgBox(0, "Error", "Error: " & $ret[0]) $Get = Dllstructgetdata($struct,1) Return $get Else MsgBox(0, "Error", "Error: " & $ret[0]) Return $ret[0] EndIf EndFunc (I've used a MsgBox for debug, it returns 11 (which is the error code for MMSYSERR_INVALPARAM) which means the pointer is invalid... apparently.) Seems that @error doesn't get thrown... oh well. Any ideas?
87450kalle Posted February 3, 2010 Posted February 3, 2010 It seems that I've been barking up the wrong tree a little. I've spent hours trying to get that right (which is now perfect thanks to you) but my problems are deeper. I've been trying to get that working but for some reason the initial _MidiOutOpen command doesn't work. Func _midiOutOpen($devid=0,$callback=0,$instance=0,$flags=0) $struct = DllStructCreate("udword") $ret = Dllcall("winmm.dll","long","midiOutOpen","ptr",DllStructGetPtr($struct),"int",$devid,"long",$callback,"long",$instance,"long",$flags) if not @error Then MsgBox(0, "Error", "Error: " & $ret[0]) $Get = Dllstructgetdata($struct,1) Return $get Else MsgBox(0, "Error", "Error: " & $ret[0]) Return $ret[0] EndIf EndFunc (I've used a MsgBox for debug, it returns 11 (which is the error code for MMSYSERR_INVALPARAM) which means the pointer is invalid... apparently.) Seems that @error doesn't get thrown... oh well. Any ideas? I had the same problem, changed $struct = DllStructCreate("udword") to $struct = DllStructCreate("dword") and now it is working... //Johan
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