Jason (jcreed) wrote,

So, I never really got into windows programming much during my youth — by the time I actually knew how to program, I was mostly using Linux — so it's an amusing exercise to mess around with little corners of the Windows API, like for instance MIDI I/O. It's far less scary than I thought.

The following C program just dumps MIDI messages to stdout:
#include <windows.h>

void CALLBACK callback(HMIDIIN handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) {
  if (uMsg == MIM_DATA) {
    printf( "%ld %d %d %d\n", dwParam2,  dwParam1 & 0x000000FF, (dwParam1>>8) & 0x000000FF, (dwParam1>>16) & 0x000000FF);

int main(void) {
  HMIDIIN inHandle;

  if (midiInOpen(&inHandle, 0, (DWORD)callback, 0, CALLBACK_FUNCTION)) {
    printf("There was an error opening the default MIDI In device!\n");
  while(1) { Sleep(1000); }

and using some (sigh) perl module that someone wrote years ago, it is disgustingly convenient to transform this into a standard midi file:


use MIDI;
use strict;
use warnings;

my $patch = 0;
my $bank = 0;
my $curt = 0;

my @events = (['set_tempo', 0, 500_000], 
	      ['control_change', 0, 0, 0, $bank],
	      ['patch_change', 0, 0, $patch],

while (<>) {
    my ($t, $code, $note, $vel) = split;
    my $delta = int(($t - $curt) );
    if ($code == 144) { # note on
	push @events, ['note_on', $delta, 0, $note, $vel];
    if ($code == 176) { # control change
	push @events, ['control_change', $delta, 0, $note, $vel];
    $curt = $t;

my $opus = MIDI::Opus->new({ 'ticks' => 500, 'tracks' => [ MIDI::Track->new({ 'events' => \@events }) ] } );
$opus->write_to_handle( *STDOUT{IO} );

The only tricky things were finding out that I needed to link to libwinmm to compile the C program under msys, and understanding the crazy midi "ticks" field and what I needed to set it to in order to make ticks = milliseconds.

Clearly the thing to do is wrap this all in some saner language...

Anyway, here is a quick recording of the head of "Blue Monk".
Tags: music, programming

  • (no subject)

    K got back tonight, pretty late in subjective time (3-4am or so, coming from europe) but all in one piece. None of her houseplants, which were…

  • (no subject)

    K is off tonight to Old Country for a couple weeks, to fulfill family-seeing obligations. Sad! Thankfully we still have internet and skype and…

  • (no subject)

    Finally home. This time instead of mysteriously attracting screaming babies I mysteriously attracted full grown adults biting their nails or maybe…

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded