November 25, 2008

calculator music

Filed under: Uncategorized — aturley @ 10:17 pm

A while back, there was a poll on createdigitalmusic.com where people were asked about mobile music making devices that they would like to see the website cover. A few people said that they wanted to see coverage of calculators. It was treated as a joke, but I thought it might be fun to make it a reality.

I have an HP 48 GX. The HP 48 actually has a speaker that can be controlled programatically. This is fun for little beeps, but it isn’t very flexible. The calculator also has a serial port. This seemed more promising. I decided to try to figure out a way to convert the signal from the serial port into MIDI messages that could then be sent to a MIDI keyboard.

I used a Parallax Basic Stamp to read serial data on one pin and send MIDI data on another pin. Stamp Basic provides some nice functions for reading and writing serial data. The code on the Stamp looks like this:

note var byte
velocity var byte
MIDINOTEON con 144
MIDINOTEOFF CON 128
MIDICHANNEL CON 0
MIDIVELOCITY CON 127
MAINLOOP:
SERIN 3, 167, 16780, [note, velocity]
SEROUT 4, 12, [MIDINOTEON + MIDICHANNEL, note, velocity]
GOTO MAINLOOP

Nothing too special here. We read the data in on pin 3, and write out on pin 4. The incoming serial data needs to be coming in at 2400 baud. Also, the incoming message only specifies the note and velocity. The output should go through a MIDI output circuit.

I wrote some code on the calculator that takes keystrokes and turns them into MIDI noteon messages. The code is broken into two functions. The first is called FLIP. It takes a list and an index into the list, and returns the list with a “not” applied to the value at the given index, as well as the original index and the new value. I use this function along with a list to keep track of whether a note is on or off, so that when the key is pressed the corresponding note can be turned on or off. Here’s the code for FLIP:

<< -> L P << L P GET NOT DUP L SWAP P SWAP PUT P ROT >> >>

You caught all that, right? And now, here’s the code that watches for a keypress and sends the appropriate message:

<< '0*X' 'X' 0 127 1 SEQ
WHILE 1 REPEAT
IF KEY THEN
1 - DUP 10 / FLOOR 6 * 40 + SWAP 10 MOD + FLIP 64 * MIDIOUT
END
END >>

Ah, right, and the MIDIOUT function:


<< CHR SWAP CHR SWAP XMIT DROP >>

All of this is really just a fancy way to use the built-in XMIT function to send two bytes out the serial port.

So, after the coding and the circuit building, here’s what I got.

Powered by WordPress

On this site: