justinp.io projects about contact


QRMusic creator was one of my first explorations of how fiduciary marks can be used for fun and interesting things instead of the simple cataloguing tasks for which they're usually employed. With this system, simple musical compositions can be embedded in QR codes, and read back in to play them.


The system transcribes notes using a low level system where each note is transcribed into a 6 character sequence containing three key pieces of information. The first two determine which tone is produced— anything from C-2 to G8.


The next three identify a time index at which the note should sound. The wide range allows long, or complex compositions. The last is a duration notator, which will compel the note to continue to sound, for up to 16 beats.


Outside of the usual range of notes are a few commands to the music player, known as control codes. Currently these are employed to allow the tempo, looping options, and voice of the instrument to be changed by sending note-tokens with different properties. Since the MIDI standard for music contains a 128 count of notes, and the remaining space between 128 and 255 remains for these control codes. Each one takes the form of an out of range note, but uses space in the time index and duration slots and depending on its needs.



I created two processing sketches for this project, one simple one that only did playback, and a much more complex one that did on-screen creation and encoding. Both of them made use of the note reading / encoding system used. I implemented it with a pretty simple parsing function

char letters[] = s.toCharArray();
String noteVal = "" +letters[0] + letters[1];
String beatVal = "" + letters[2] + letters[3] + letters[4];
String durVal = "" + letters[5];

midiNote = Integer.parseUnsignedInt(noteVal, 16);
timeCode = Integer.parseUnsignedInt(beatVal, 16);
duration = Integer.parseUnsignedInt(durVal, 16);

The MIDI interface requires a signal for a note being activated, and one specifying that note ending, so these are created and encoded from these values.

Sequence s = new Sequence(Sequence.PPQ, 1);      
Track t = s.createTrack();

ShortMessage onMSG = new ShortMessage();
ShortMessage offMSG = new ShortMessage();

onMSG.setMessage(ShortMessage.NOTE_ON, 0, (int)this.midiNote, 100);
offMSG.setMessage(ShortMessage.NOTE_OFF, 0, (int)this.midiNote, 100);

MidiEvent onEvent = new MidiEvent(onMSG, this.timeCode);
MidiEvent offEvent = new MidiEvent(offMSG, this.timeCode + this.duration);

t.add(onEvent);
t.add(offEvent);

sequencer.setSequence(s);
sequencer.start();

The creation software uses a simple interface to allow you to manually place notes and specify options, and translates the GUI options into proper compositions. It allows for most of the options such as looping, note placement, tempo adjustment, and instrument selection. It also allows you to save out QR codes to disk, or load a previously created project into the editor by scanning the QR code.