Jump to content

Making a MIDI keyboard


sb1920alk
 Share

Recommended Posts

This is related to a hobby I'm working on.

I'm wondering if it's possible to send a MIDI "note on" message when a key is press, and the corresponding "note off" message and the key is released. Does Windows limit the number of keys that can be simultaneously monitored?

Ultimately, I'd want to assign a different note to the alphebet and number keys to make a 32-note "instrument" whose MIDI messages are monitored by a sequencing/sampler program that is running.

I searched the forum for MIDI-related posts but didn't find anything useful. If you know of one I missed, let me know please.

Link to comment
Share on other sites

I'm not really familiar with MIDI but I suppose if you know the note code you could use _IsPressed() and Send() to assign notes to keys and send the "note on" message to your program. This is just a theory and I have no code to back it up but that should at least help you with a start.

Link to comment
Share on other sites

Get the UDF HERE:. Very cool udf.

This is a very simple example, expand on it as needed.

#include <_midiudf.au3>
#Include <Misc.au3>
Global $Layout[23]
Opt("OnExitFunc", "OnAutoItExit")

$open = _midiOutOpen()
$instrument = 01
_MidiOutShortMsg ($open, 256 * $instrument + 192)

$h = 0
For $i = 0x00401590 To 0x00406C90 Step 1024;should actually be 256, but set it to 1024 to cover the keypad
    $Layout[$h] = $i 
    $h += 1
Next
;_ArrayDisplay($Layout)

While 1;The is pressed is layed out as a,b,c,d,e,f,g,h,i,p,q
    If _IsPressed("41") Then
        _MidiOutShortMsg ($open, $Layout[0])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[0] - 0x00400000)
    EndIf
    If _IsPressed("42") Then
        _MidiOutShortMsg ($open, $Layout[1])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[1] - 0x00400000)
    EndIf
    If _IsPressed("43") Then
        _MidiOutShortMsg ($open, $Layout[2])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[2] - 0x00400000)
    EndIf
    If _IsPressed("44") Then
        _MidiOutShortMsg ($open, $Layout[3])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[3] - 0x00400000)
    EndIf
    If _IsPressed("45") Then
        _MidiOutShortMsg ($open, $Layout[4])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[4] - 0x00400000)
    EndIf
    If _IsPressed("46") Then
        _MidiOutShortMsg ($open, $Layout[5])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[5] - 0x00400000)
    EndIf
    If _IsPressed("47") Then
        _MidiOutShortMsg ($open, $Layout[6])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[6] - 0x00400000)
    EndIf
    If _IsPressed("48") Then
        _MidiOutShortMsg ($open, $Layout[7])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[7] - 0x00400000)
    EndIf
    If _IsPressed("49") Then
        _MidiOutShortMsg ($open, $Layout[8])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[8] - 0x00400000)
    EndIf
    If _IsPressed("50") Then
        _MidiOutShortMsg ($open, $Layout[9])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[9] - 0x00400000)
    EndIf
    If _IsPressed("51") Then
        _MidiOutShortMsg ($open, $Layout[10])
        Sleep(200)
        _MidiOutShortMsg ($open, $Layout[10] - 0x00400000)
    EndIf   
    Sleep(60)
WEnd

Func OnAutoItExit()
    _MidiOutClose($open);Call this on the exit of the script
EndFunc
Link to comment
Share on other sites

I got a little more interested in this and decided to have a little more fun, so here. Now you can arbitrarily sustain the notes with each key press.

#include <_midiudf.au3>
#Include <Misc.au3>
Global $Layout[26][2]
Global $NoteOn = False
Opt("OnExitFunc", "OnAutoItExit")


$hGUI = GUICreate("Play Me", 300, 200)
    GUIRegisterMsg(0x0100, "_Pressed")
    GUIRegisterMsg(0x0101, "_Release")
GUISetState()

$open = _midiOutOpen()
$instrument = 01;Change the instrument here
_MidiOutShortMsg ($open, 256 * $instrument + 192)

$g = 0
$h = 65; = "A" --- it goes up to "W" which is 86
For $i = 0x00401590 To 0x00406C90 Step 1024;should actually be 256, but set it to 1024 to cover the keypad relatively evenly
    $Layout[$g][0] = $h
    $Layout[$g][1] = $i 
    $g += 1
    $h += 1
Next
;_ArrayDisplay($Layout)


While 1
    Sleep(10)
WEnd

Func _Pressed($hWnd, $msgID, $wParam, $lParam)

    For $i = 0 To UBound($Layout) - 1
        If $wParam = $Layout[$i][0] And $NoteOn = False Then 
            _MidiOutShortMsg ($open, $Layout[$i][1])
            ;ConsoleWrite("+ " & $wParam & @CRLF)
            $NoteOn = True
            ExitLoop
        EndIf
    Next

EndFunc

Func _Release($hWnd, $msgID, $wParam, $lParam)

    For $i = 0 To UBound($Layout) - 1
        If $wParam = $Layout[$i][0] Then
            _MidiOutShortMsg ($open, $Layout[$i][1] - 0x00400000)
            ;ConsoleWrite("+ " & $wParam & @CRLF)
            $NoteOn = False
            ExitLoop
        EndIf
    Next

EndFunc

Func OnAutoItExit()
    _MidiOutClose($open);Call this on the exit of the script
EndFunc
Edited by Champak
Link to comment
Share on other sites

I have a recording studio so I really don't touch a computers general midi stuff; I only did this because it kind of peaked my interest. If you have a general question maybe I can answer it for you. If you are asking where the drums are because you can't find it in the 127 patches/instruments it is probably because drums/percussions generally arbitrarily reside on channel 10 in the midi domain...from what I remember. I assume that the way the UDF is set up it is transmitting on channel 1. So if this is relating to your question go through the _midiudf and see if there is a way to set this thing to channel 10 and hopefully that will resolve your problem. Keep in mind, when on channel 10 instruments/drum kits are not laid out throughout the entire 127 patch/instrument range; you may only have kits on patch 1,2,5,27,55,100 or something like that(you get the idea), so you may just have to go through every patch on channel 10 to find drum kit, and then not every key has a percussion sound on it....IF you can even set this thing to channel 10.

Hope that helps.

Edited by Champak
Link to comment
Share on other sites

I have a recording studio so I really don't touch a computers general midi stuff; I only did this because it kind of peaked my interest. If you have a general question maybe I can answer it for you. If you are asking where the drums are because you can't find it in the 127 patches/instruments it is probably because drums/percussions generally arbitrarily reside on channel 10 in the midi domain...from what I remember. I assume that the way the UDF is set up it is transmitting on channel 1. So if this is relating to your question go through the _midiudf and see if there is a way to set this thing to channel 10 and hopefully that will resolve your problem. Keep in mind, when on channel 10 instruments/drum kits are not laid out throughout the entire 127 patch/instrument range; you may only have kits on patch 1,2,5,27,55,100 or something like that(you get the idea), so you may just have to go through every patch on channel 10 to find drum kit, and then not every key has a percussion sound on it....IF you can even set this thing to channel 10.

Hope that helps.

More info than I was expecting; thanks. There is an example in the udf that loops through the drum patches so I can see how to produce the sound but I don't understand how/why the _shortmsg works and differently when used his way. I'm trying to figure out how to produce more than one drum sound at a time but there's not ON/OFF mechanism like with the instrument pitches. I'll keep investigating. Thanks for your input.
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...