MIDI on the LiveScribe pen

I originally thought the LiveScribe pen could only play one note at a time. However, what I did not realize at the time was the pen supports JSR-135, which is a MIDI interface. MIDI is how computers can talk to devices like digital pianos, keyboards, drum kits etc. Using MIDI, chords can be played on the pen – that is, multiple notes playing at the same time to make a chord sound.

Details on MIDI can be found at http://www.midi.org/. I found the table at http://www.midi.org/techspecs/midimessages.php particuarly useful.

The following is some sample code to help you get going. There are some other articles in the LiveScribe forums, but the following shows the essence of talking to the MIDI subsystem. I like wrapping it in a separate class to keep the main code cleaner.

package com.wordpress.alankent.livescribe.support;

import java.io.IOException;

import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.control.MIDIControl;

/**
* Helper class designed for accessing the
* LiveScribe pen internal MIDI interface.
* This class uses JSR135, so should work with
* other MIDI devices but may not make all the
* the functionality of those devices visible.
*/
public class Midi {
    private Player midiPlayer;
    private MIDIControl midiControl;

    /**
     * A suggested channel number to use if only
     * going to play one note at a time.
     */
    public static final int DEFAULT_CHANNEL = 0;

    /**
     * The number of concurrent channels that can
     * play at once.
     * Channels are numbered 0 to 15.
     */
    public static final int NUM_CHANNELS = 16;

    /**
     * The maximum velocity that can be used when
     * playing a note.
     */
    public static final int MAX_VELOCITY = 127;
    /**
     * The MIDI note number for middle C.
     */
    public static final int NOTE_MIDDLE_C = 60;
    /**
     * Program number for a piano sound. See
     *
http://en.wikipedia.org/wiki/General_MIDI
     * for a long list of program numbers. The
     * LiveScribe pen is not a high quality MIDI
     * device, so does not necessarily make
     * sounds like the instruments listed.
     */
    public static final int PROGRAM_ACCOUSTIC_GRAND_PIANO = 0;

    /**
     * Constructor. Connects to the MIDI
     * subsystem and prepares to play sounds.
     *
     * @throws MediaException
     * @throws IOException
     */
    public Midi()
            throws MediaException, IOException {
        midiPlayer = Manager.createPlayer(
                        Manager.MIDI_DEVICE_LOCATOR);
        midiPlayer.prefetch();
        midiPlayer.start();
        midiControl = (MIDIControl)
                midiPlayer.getControl("MIDIControl");
    }

    /**
     * Play a note on the specified channel at
     * the specified velocity.
     *
     * @param channel
     *            The channel to play the note on.
     * @param midiNote
     *            The note to play.
     * @param velocity
     *            The velocity of the note to play.
     */
    public void playNote(int channel,
                         int midiNote,
                         int velocity) {
        midiControl.shortMidiEvent(
                        MIDIControl.NOTE_ON | channel,
                        midiNote,
                        velocity);
    }

    /**
     * Silence a channel (stop playing any sound).
     *
     * @param channel
     *            The channel to silence.
     */
    public void turnSoundOff(int channel) {
        final int CONTROL_ALL_SOUND_OFF = 0x78;
        midiControl.shortMidiEvent(
                MIDIControl.CONTROL_CHANGE | channel,
                CONTROL_ALL_SOUND_OFF, 0);
    }

    /**
     * Silence the MIDI device completely (all
     * channels).
     */
    public void turnAllSoundOff() {
        for (int channel = 0;
                        channel < NUM_CHANNELS;
                        channel++ ) {
            turnSoundOff(channel);
        }
    }

    /**
     * Change the "program" (instrument sound) to
     * be used by the specified channel.
     *
     * @param channel
     *            The channel to use.
     * @param program
     *            The program from the bank to use.
     */
    public void setProgram(int channel, int program) {
        midiControl.setProgram(channel, 0, program);
    }
}

I was going to write up a long explanation, but really the code is pretty simple. There is detailed documentation in the JSR-135 specification if you really want to know more.

2 comments

  1. nikola · · Reply

    impressive…
    can you explain how to make a ludof file…the gramar and all
    and also i have a question for you…
    lets say i have a list of 1500 names and when i write something in a specific area i want the correct name to appear on the OLED…i already did it the old way not with ludof
    and a 1 in 3 times the wrong name appears on the screen…

    do you thing this would be more accurate by using the ludof?

    thanks in advance
    keep up the great work!

    1. Hi. Sorry for delay in replying. Life has been busy.

      I don’t know the official grammar of a ludef file. I just looked at the sample in the forums and used the same constructs. Rules can have sequences (this character followed by another character), alternatives (or branches), repetition, and groups. That is the end of my knowledge.

      Regarding performance, I don’t know. My guess is there is no performance difference. I did not notice any when I tried my big file compared to a ludef file. My guess us the compiler converts the list into something like a ludef file for internal processing. I could imagine a hand crafted ludef file requiring less memory on the pen.

      Regarding accuracy I doubt it would make any difference. Restricing the choices (suze of grammar) did help for me a lot. I found the handwriting recognition pretty average.

      Note: I have not touched the pen since my posts, so others might have more experience these days. Good luck!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: