midilib for Tcl/Tk

<<< BACK TO HOMEPAGE   |   Introduction | Overview | Download | Installation | Examples


Midilib is a loadable module for Tcl/Tk 8.x on the MS Windows platform. With this addition, Tcl/Tk is capable of receiving and sending MIDI sysex messages from and to external MIDI devices. There is already an existing MIDI library for Tcl/Tk, called tclmidi , but it doesn't support low level access to MIDI devices.

Midilib mainly based on the RPMidi.dll by Bruce James <bjames@voyager.co.nz> written to support midi devices for his RPEdit, a nice Patch Editor for Guitar Multi-effects Processors. Thanks for doing this great job. I only less modified the code to make it suitable for other applications.
The package consists of C++ code included in a Visual C++ 6.0 project. This means that at present the library only supports Win32 platforms, line Windows 95/98/ME/NT/2000. But I'm looking forward to extend it for Linux.
BTW, MIDI sysex implemenation in Linux is very simple. Write all sysex messages as binary data to /dev/midiXX!

The source code should also be useful to someone wishing to extend Tcl with C language routines.

 Command Overview 

The MIDI Sysex library contains essentially commands to handle low level MIDI devices and an additionally feature to send short MIDI messages.
Currently supported commands:
midi::openout <device> 
midi::openin <device>
midi::sendshort <status> <data1> <data2>

The midi::openout and midi::openin commands returns a channel id, where the usual tcl channel commands, read, gets, puts, close can then be used.
NOTE:All other MIDI messages, except for System Exclusive, always have 3 or less bytes. The midi::sendshort command can be used to pass such messages, especially to send MIDI note numbers.

Using MIDI sysex commands, you need to first call midi::openout or midi::openin to open some MIDI device for output or input respectively. In order to write out MIDI data to a particular device, you need to first call midi::openout once, passing it the Device ID of that desired device. Get the specific Device ID for your external MIDI device by calling midi::getoutdevs. Then, you can subsequently call a function such as midi::sendshort which (immediately) outputs MIDI data to that device. Or use tcl's channel commands like described above. Don't forget to flush outgoing data using the tcl flush command.

In order to read incoming MIDI data from a particular device, you need to first call midi::openin once, passing it the Device ID of that desired device. Then, Windows will subsequently pass your program each incoming MIDI message from that device. Invoking a "read " your application leeches all data. After you're done inputting or outputting to a device (and have no further use for it), you must close that device. Think of a MIDI device like a file. You open it, you read or write to it, and then you close it.


The midilib package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. Read also the copyright notice in midi.c!
The latest release was created und runs only on Windows.

 Installation Instructions 

  1. If you do not have already installed tcl/tk 8.x, at first you must install it. Get it from the known locations and follow the installation instructions.

  2. Download midilib.zip from here.

  3. Copy the uncompressed files into your current project directory. Include the following lines into your applikation

    	lappend auto_path .
    	package require midi 0.2

  4. Ready!
  5. Because it lacks of documention today some examples are given below...


Here are small examples to show the easily use of the commands.

# get a list of MIDI Output devices
set mididevs(out) {}
foreach device [midi::getoutdevs] {
	lappend mididevs(out) $device
	puts $device
# get a list of MIDI Input devices
set mididevs(in) {}
foreach device [midi::getindevs] {
	lappend mididevs(in) $device
	puts $device
# get the number of MIDI Output devices
set num [llength [midi::getoutdevs]]
# handle MIDI Output device
set rc [catch {set id [midi::getoutid]} msg]
if {$rc} {
	set f [midi::openout $id]
} else {
	puts "Fatal error: $msg."
fconfigure $f -translation binary
puts -nonewline $f "\xf0\x41\x10\x00\x02\x12\xf7"
flush $f
close $f
# playing a note number (middle C - 60) for just a second on the default MIDI device
set f [midi::openout 0]
midi::sendshort 144 60 112
after 1000
midi::sendshort 144 60 0
close $f

©Steffen Traeger
changed: 03/26/01

[Steffen Traeger's Homepage]