Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

MIDI Output from AHK


  • Please log in to reply
65 replies to this topic
Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004

After a couple of days debugging I ended up rewriting the whole code. Now it works with the default midi device: ID 0: Microsoft GS Wavetable SW Synth. Most of the changes were bug fixes and simplifications, to reduce code size. The hardest part is TomB's original discovery work, which made midi output possible from an AHK script.

Wow! Once you finalize it, perhaps this would be a good candidate for the standard library -- especially if it works on all OSes.

TomB
  • Members
  • 17 posts
  • Last active: Oct 29 2009 03:03 PM
  • Joined: 14 Jan 2005
Laszlo wrote:

After a couple of days debugging I ended up rewriting the whole code. Now it works with the default midi device: ID 0: Microsoft GS Wavetable SW Synth. Most of the changes were bug fixes and simplifications, to reduce code size. The hardest part is TomB's original discovery work, which made midi output possible from an AHK script.


Well, now I am just plain embarrassed - I guess I proved my point that I am a novice programmer. The scripts worked for me, but I certainly didn't test them out thoroughly.

I wanted to throw them out there in hopes that this would happen - someone who actually knows what they are doing would clean all of this up.

Sorry I created so much work for you Laszlo. It took me probably 15-20 hours to get it to where I did, so between the two of us, there are a lot of man-hours in this little project.

Tom

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
40 hours work for such a nice tool is not much. Before your post I did not even know that Windows has built in midi support, so your work was very important. Our code always has bugsā€¦ well, almost. I know someone, who's code always worked so far at the first run, but we, mere mortals just have to bug fix two hours for every hour of coding.

dpg
  • Members
  • 3 posts
  • Last active: Jul 31 2007 01:55 AM
  • Joined: 30 Jul 2007
Hi,

Thanks very much TomB for developing these MIDI functions, and Laszlo for the edits.

I tried Laszlo's edited code and examples, but I am getting the following errors:

- When it executes the example "single middle C note by midiOutShortMsg," it works fine and I hear the single note.

- When it executes the example "Send two notes on device 0 by MidiStream":

Error 11 in setting the Timebase
Error 7 in midiOutPrepareHeader

- Then, when it executes the example "Send a decaying series of C notes":

Error 11 in setting the Timebase

I'm running Windows ME and using the default MIDI output (device 0).

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Search the Web, maybe ME does not support MIDI streaming? I could only test the script on XP SP2, where it works.

dpg
  • Members
  • 3 posts
  • Last active: Jul 31 2007 01:55 AM
  • Joined: 30 Jul 2007
Laszlo,

Thanks for the quick response.

Search the Web, maybe ME does not support MIDI streaming?


I found this page about midiStreamOpen from the MSDN Library:

http://msdn2.microso...y/ms711645.aspx

At the bottom of the article, it says:

Requirements
Windows NT/2000/XP: Included in Windows NT 3.1 and later.
Windows 95/98/Me: Included in Windows 95 and later.
Header: Declared in Mmsystem.h; include Windows.h.
Library: Use Winmm.lib.I guess this means that Windows 9x/Me is supported.

Then I tried running the same script on my XP (SP2) computer, and it gives the following error:

Error at line 30.
Line Text: DllCall("FreeLibrary", UInt,hModule), hModule := ""
Error: This line does not contain a recognized action.
The program will exit.Thanks,
dpg

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005

Line Text: DllCall("FreeLibrary", UInt,hModule), hModule := ""
Error: This line does not contain a recognized action.

It looks like you have an old AHK version.

dpg
  • Members
  • 3 posts
  • Last active: Jul 31 2007 01:55 AM
  • Joined: 30 Jul 2007

It looks like you have an old AHK version.

Yup! Updated AHK, and it works on the XP now. Thanks.

robcheese
  • Members
  • 27 posts
  • Last active: Aug 13 2011 12:35 AM
  • Joined: 07 Jul 2008
I just started useing this MIDI output library and its working great. However when I try to combine it with a MIDI input library(<!-- m -->http://www.autohotke...pic.php?t=30715<!-- m -->) it stops working.

here's some code I used to test it out.

-------------------------------------------------------------------------------
hModule := OpenMidiAPI()
mm6 := midiOutOpen(1)

OnExit, sub_exit
if (midi_in_Open(8))
ExitApp

listenCC(64, "SustainIn", 2)

return

sub_exit:
midi_in_Close()
midiOutClose(mm6)
FreeMidiAPI(hModule)
ExitApp

a::
midiOutShortMsg(mm6, "CC", 2, 64, 127)
return

SustainIn(CCNum, Vel)
{
midiOutShortMsg(mm6, "CC", 2, 64, 127)
}

#Include midi_out_lib.ahk
#Include midi_in_lib.ahk

------------------------------------------------------------------------

When I trigger the output with "a" it works fine but when I trigger it with my sustain pedal I get message box that says "there was error sending the MIDI event".

anyone have any suggestions or other ways to get MIDI input and output.

thanks

conchfeld
  • Members
  • 16 posts
  • Last active: Sep 01 2009 08:49 PM
  • Joined: 21 Sep 2008
So I've been using this library a lot and it is really fantastic. Thanks both of you guys for working so hard on it. Been having huge success with it, but theres one thing thats got me stumped, so I've got a bit of whats probably a newbie question for you.

About sending pitch wheel events-- what kinds of values should I put into parameter 2 for pitch wheel? I can't seem to get any consistent output. Everything is all over the place. Something like -638000 sends the pitchwheel to -64 and 8192 sends it to -32 or something. I don't remember the exact values but I figure I am using the wrong kind of input?

Thanks a bunch.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
I am using a dllcall directly, for speed. If you have a pitch bend value 0 <= PB < 16384 (with the center value 8192 corresponding to no bend, 0 to the max downward bend and 16383 to the max upward bend), a possible call is
DllCall("winmm.dll\midiOutShortMsg", UInt,h_midiout, UInt,(channel+0xDF)|(PB&0x7F)<<8|(PB>>7)<<16) ; channel = 1..16
That is, Param1 := PB & 127, Param2 := PB>>7. We need the bit-manipulation operations because only 7 bits of the PB value should be included in MIDI messages.

conchfeld
  • Members
  • 16 posts
  • Last active: Sep 01 2009 08:49 PM
  • Joined: 21 Sep 2008
Thanks man. That took a little bit of studying on my part to decipher, but you solved my problem.

rockum
  • Members
  • 23 posts
  • Last active: Jul 11 2013 10:50 PM
  • Joined: 20 Dec 2007
I am using the orginal MIDI functions with success in my first major AHK's project. However, being a newbie I am finding what I want to do a bit out of my grasp.

The sample code...

NumPorts := MidiOutsEnumerate()     ;function that fills an global array called MidiOutPortName and returns the number of ports
    Loop, % NumPorts
    {
      Port := A_Index -1
      msg := msg . "ID: " . Port . " --> " . MidiOutPortName%Port% . "`n"
    }
    InputBoxH := 100 + NumPorts * 25
    InputBox, MidiDevice, Select Midi Port, Select the MIDI Output Port for MuCKeys`n`n%msg%,, 350, % (NumPorts * 25 + 100),,,,, 0
    if (errorlevel)
        exit
h_midiout := midiOutOpen(MidiDevice)

...brings up a msgbox with the MIDI port numbers and names, but I would like to save the selected port name in an ini file and then when the program is run in the future seek to see if that output port is still available and if so use it as default. If it is not available, then the msgbox could just pop back up and let the user rechoose. Is this hard? I don't get arrays too well and spent an hour or so trying to guess my way to success, but couldn't. How can I search the array and set the MIDI output port from the ini file if it is available ? Thanks

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Your script does not use arrays, but a long msg string of fields delimited by new lines (`n). You can later use
Loop Parse, msg, `n
to get the pieces in the automatic loop variable A_LoopField. A_Index contains the number of the current iteration inside the loop block, delimited by {...}.

rockum
  • Members
  • 23 posts
  • Last active: Jul 11 2013 10:50 PM
  • Joined: 20 Dec 2007
Got it working. Thanks.