Archive for September, 2011

Friday, September 9th, 2011

Mac OS X Lion MIDI sysex problems with Java

Happiness of easy MIDI programming with Scala didn’t last too long. Almost everything is fine with my pair of DaScratch controllers. I can switch the led’s and read the touch interfaces easily, but there is one small thing. The mode of round touch interface is switched by using MIDI system exclusive or sysex command. This is easy with javax.sound.midi in theory, but in OS X the sysex command doesn’t get transmitted.

This can be worked around by using mmj drivers. With mmj sending sysex messages from Scala console is a bliss. However, if there’s a pair of identical controllers just like I have, I can not access the second controller because of a bug in mmj.

So, I filed two bugs:

  • to Apple about sysex commands. I’ve got problem ID 10016703, but no response.
  • to Humatic about accessing two similar devices with mmj. Nils from Humatic responded very fast, but he didn’t promise fix soon.

Well, seems that my first project creating router for a pair of DaScratches is spinning off another project creating Java MIDI drivers for OS X.

Sunday, September 4th, 2011

Scala console MIDI hands-on

As Scala console, Interactive Interpreter or REPL was one of my selling points for programming MIDI with Scala, I show what can be done with it. I do not show how to install Scala or how to access console.

First things first: Import Midi libraries to save typing later on.

scala> import javax.sound.midi._
import javax.sound.midi._

Enumerate devices attached.

scala> MidiSystem.getMidiDeviceInfo
res0: Array[javax.sound.midi.MidiDevice.Info] = Array(Bus 1, SCS.3d, SCS.3d, FastTrack Pro, Bus 1, SCS.3d, SCS.3d, FastTrack Pro, Real Time Sequencer, Java Sound Synthesizer)

We are interested in two Stanton SCS.3d DaScratch controllers attached directly to USB ports, so let’s filter them using res0 from previous evaluation.

scala> res0.filter(_.getName == "SCS.3d")
res1: Array[javax.sound.midi.MidiDevice.Info] = Array(SCS.3d, SCS.3d, SCS.3d, SCS.3d)

Now there are four MidiDevice infos: Two inputs and two outputs – one for each physical device.

Let’s map those information blocks to actual devices.

scala> res1.map(MidiSystem.getMidiDevice)
res2: Array[javax.sound.midi.MidiDevice] = Array(com.sun.media.sound.MidiInDevice@503f0b70, com.sun.media.sound.MidiInDevice@5b080f38, com.sun.media.sound.MidiOutDevice@6e1f5438, com.sun.media.sound.MidiOutDevice@4ad26103)

Let’s filter out the inputs and outputs in two separate lists. Again we use result from previous evaluation, but now we are storing the lists to named variables:

scala> val ins = res2.filter(_.getMaxTransmitters != 0)  
ins: Array[javax.sound.midi.MidiDevice] = Array(com.sun.media.sound.MidiInDevice@503f0b70, com.sun.media.sound.MidiInDevice@5b080f38)

scala> val outs = res2.filter(_.getMaxReceivers != 0)
outs: Array[javax.sound.midi.MidiDevice] = Array(com.sun.media.sound.MidiOutDevice@6e1f5438, com.sun.media.sound.MidiOutDevice@4ad26103)

Get the first output device and open it.

scala> val out = outs.head
out: javax.sound.midi.MidiDevice = com.sun.media.sound.MidiOutDevice@6e1f5438

scala> out.open

Send note on message for key number 0×72 on channel 1 with velocity 1 to light a deck indicator on DaScratch.

scala> val m = new ShortMessage()
m: javax.sound.midi.ShortMessage = javax.sound.midi.ShortMessage@7f7ef0a7

scala> m.setMessage(0x90, 0x72, 0x01)

scala> out.getReceiver.send(m, -1)

That’s it. Using Scala REPL is very fast way to check how the MIDI works with JVM.