MIDI handler API

165 views
Skip to first unread message

Juha-Pekka Jokela

unread,
Jun 5, 2015, 8:07:33 AM6/5/15
to kerber...@googlegroups.com
As I mentioned elsewhere, I'm working on a "common" low level MIDI handler, that could be used with any program to interface with MIDI without having to consider different interfaces (except maybe selecting one at the beginning), manually checking status registers etc. but just concentrate on the obvious: Different midi commands & their arguments.

Here's a simple "silent" test program (using Sequential Circuits) that basically just prints received arguments for specific midi commands (NoteOn, NoteOff, TimeCode, SongSelect, Start, Stop) and SHOULD handle running state properly (something I was mistakenly completely ignoring before) http://jupp3.binaryriot.org/miditest1.zip

So, as for the API itself...

Currently I basically have 3 arrays for different types of messages:
;                           NoteOff         NoteOn        AfterTouch ContolChange ProgramChange ChannelPressure PitchBend
.define CommandHandler      HandleNoteOff,  HandleNoteOn, $0000,     $0000,       $0000,        $0000,          $0000

;                           SysEx  MidiTimeCodeQF      SongPosPtr SongSel            Und    Und    TuneReq EndOfSysEx
.define SystemCommonHandler $0000, HandleMidiTimeCode, $0000,     HandleSongSelect,  $0000, $0000, $0000,  $0000

;                           TimingClock Und    Start        Cont   Stop        Und    ActiveSens Reset
.define RealTimeHandler     $0000,      $0000, HandleStart, $0000, HandleStop, $0000, $0000,     $0000

Then, you can replace any array element with your own function, and then that function will be called, when there's a message of that type with all the args read (which will be always stored in same zero page array). If you're not interested in some message type, just add $0000 instead, and it will just be ignored (internally args will still be read etc. but no callback will be called)

In addition, program can have raster interrupt that will be called, whenever there's an interrupt that wasn't caused by the MIDI cart instead.

So what's currently missing?

Support for anything else than Sequential Circuits midi. Not an issue for Kerberos users, of course (should be relatively easy to add, just been busy with other things)

Midi channel handling: Should that be handled globally within API itself, or should the channel information be passed to callbacks to let them decide, whether to handle / ignore the command?

SysEx: This would definitely need some special handling, but there's currently none. Sure, there are callbacks in the list, simply because I just can't "leave out one midi command type" (as that would change the index of all commands that come after). I don't think this is too high priority though, but could be used as workaround for saving, as long as the cartridge floppy write support isn't implemented.

Midi out: Again, not that important in my opinion. Perhaps I could just have simple low level "send single byte" API for this...

Currently the whole thing is 368 bytes with all debug disabled.

Comments? Ideas?

Juha-Pekka Jokela

unread,
Jun 6, 2015, 9:44:12 AM6/6/15
to kerber...@googlegroups.com
And here's a second test program, that actually produces sound. One channel only, next note overrides the previous, and NoteOff signals stop the note, if it's currently playing.

http://jupp3.binaryriot.org/miditest2.zip

Nothing useful really, just testing my implementation... As before, Sequential Circuits only.

Juha-Pekka Jokela

unread,
Oct 2, 2015, 8:46:06 AM10/2/15
to kerberos-midi
Fixed quite a few bugs, and the whole library feels more "ready" now. If you want to test the current test / example application, see the current example program (hardcoded to sequential circuits, although now it's possible to select the midi interface on init)

Currently, it simply listens to note on & off messages on the first channel, and assign SID channels to 3 first ones. Channels are "freed" only on NoteOff messages for currently playing note. Sustain level is set according to note velocity. The program will also print incoming MIDI messages (internal debug functionality of the library)
I haven't tested this on "real" hardware though, as my Kerberos module seems to be lost currently...

The program itself isn't really much useful, but then again, it's not meant to be. It's meant to be as simple as possible example program that shows how to use the API. So any changes I might be making, are to simplify the code etc. If you want any extra features, you're on your own here.

There's now also MIDI channel support. When building, you can either completely ignore MIDI channel (library discards it), keep it (and manually check in your MIDI message handlers, whenever you want to), OR automatically compare againist pre-set MIDI channel internally, and reject all messages with a wrong one.

As for the code, I've sent it to few people for feedback, and will be publishing it later. If you want to get "early access", feel free to contact me.

Of course I'll also need to think of some suitable license for it, something like GPL is definitely way too restricted in this case (writing MIDI handler is relatively simple, but also easy to get wrong. I don't want anyone to code own (potentially "wrong") implementation because the license is seen as too restrictive)

Any suggestions?

regards,
J-P

michal.k...@elpassion.pl

unread,
Sep 9, 2016, 11:32:44 AM9/9/16
to kerberos-midi
Hi, I'm trying to write a little prg that uses midi. Right now without luck (using Vice). Tried an example from kerberos sources, but always get "MIDI IRQ not working". 
I guess you trying do the same, can you share a sources of your programs ? 

Thanks,
Michał 

Juha-Pekka Jokela

unread,
Nov 19, 2016, 9:34:32 PM11/19/16
to kerberos-midi, michal.k...@elpassion.pl
Hi,

Sorry for the delay, haven't been following this group too closely lately.

Took a quick look at some Kerberos examples long ago, and found them quite useless (was there one for C and one for BASIC? I mean, everyone uses asm, right?) - Might have improved since then though...

For a LONG time, I didn't have my Kerberos module, but finally a while ago, I got it back, and have done some more stuff with it.

As for MIDI usage, see http://jupp3.binaryriot.org/c64-midilib-01.tar.gz for the (old) version. Although not much has been changed since then.

Depends what kind of program you are writing, my lib is better suited for programs, where you want one proc to be called on NoteOn, another with NoteOff, no proc for pitch wheel etc.

For a very basic program, you just need to assign pointers to arrays defined in midicore/callbacks_h.s (and if you're not interested in specific message types, leave them as $0000 and they will be mostly ignored)

There's also (optional) CC handler, that will make sure values are below CC-speific maximum, and call CC-specific callbacks, almost like command handler works.

Also note that the library also implements running state (optimization used by some midi devices) which might look slightly complex, but is necessary for better compatibility. It's NOT enough to just parse incoming command bytes, and assign specific amount of data bytes to them.

There's also simple player software, just to demonstrate how to use the library.

The library is written for ca65 (part of cc65 package), adapting to some other assembler might be painful. Build is done with a standard Makefile.

Currently, I've mostly concentrated on input. There might have been some output function, but honestly, haven't even tested it. Can't see much use for MIDI output (except maybe sending data to be stored as SysEx?) - also SysEx input is rather primitive (callback is called for each data byte), probably enough, but haven't tested that either.

As usual, you shouldn't keep interrupts disabled for long, as you might start losing midi bytes. For now, there's space to store only one command & 2 data bytes (on ZP), and whenever new values appear, the old ones are lost (read them before that!) - thought of maybe doing some kind of ring buffer in the future, although not sure how much that might help :)

As for the license, I haven't yet quite figured out what to use yet. Something open source definitely, but nothing, that would require any derivative programs to be 100% open source (as at worst, that might end up with people writing own buggy midi handlers instead)

For now, getting some credit might be nice.

Oh, iirc, the example program is built for sequential circuits as default. For now, there's no midi interface autodetect, you specify which interface to use in init (see the code)

Hope this helps

regards,
J-P
Reply all
Reply to author
Forward
0 new messages