November 21st, 2011

Sending MIDI system exclusive messages from Scala console

Apple OS X gets updated once a while, and I hope the problem with sending system exclusive message will be fixed. In the previous article I’ve shown how to send a MIDI note using Scala console. Here I’ll show how to send system exclusive messages, to ensure the bug I’ve reported is still present.

Tools I’ll use:

Now start the Scala console, and import the MIDI libraries first.

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

Enumerate the output devices:

scala> MidiSystem.getMidiDeviceInfo.map(MidiSystem.getMidiDevice).filter(_.getMaxReceivers != 0)
res0: Array[javax.sound.midi.MidiDevice] = Array(de.humatic.mmj.spi.CoreMidiDeviceImpl@65d174f, com.sun.media.sound.MidiOutDevice@53281264, com.sun.media.sound.RealTimeSequencer@49a546cc, com.sun.media.sound.MixerSynth@1cb20da)

Separate the MMJ and Apple drivers. I just get the first output device which is Bus 1 loopback device.

scala> val mmj = res0.filter(_.isInstanceOf[de.humatic.mmj.spi.CoreMidiDeviceImpl]).head
mmj: javax.sound.midi.MidiDevice = de.humatic.mmj.spi.CoreMidiDeviceImpl@65d174f

scala> val osx = res0.filter(_.getClass.toString.endsWith("MidiOutDevice")).head
osx: javax.sound.midi.MidiDevice = com.sun.media.sound.MidiOutDevice@53281264

Note that class com.sun.media.sound.MidiOutDevice cannot be accessed here, so we need to kludge the driver out using class string.

Open the drivers:

scala> mmj.open; osx.open

Now connect the MIDI Monitor to listen the MIDI loopback device. Test it out by sending some notes:

scala> val note = new ShortMessage() 
note: javax.sound.midi.ShortMessage = javax.sound.midi.ShortMessage@52dce479

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

scala> osx.getReceiver.send(note, -1)

scala> mmj.getReceiver.send(note, -1)

Lines should appear in MIDI Monitor. Now send some system exclusive messages:

scala> val sysex = new SysexMessage
sysex: javax.sound.midi.SysexMessage = javax.sound.midi.SysexMessage@410e4a33

scala> val bytes = Array(0xF0, 0x00, 0x01, 0x60, 0x01, 0x00, 0xF7).map(_.toByte).toArray
bytes: Array[Byte] = Array(-16, 0, 1, 96, 1, 0, -9)

scala> sysex.setMessage(bytes, bytes.size)

scala> osx.getReceiver.send(sysex, -1)                                                 

scala> mmj.getReceiver.send(sysex, -1)

By looking MIDI Monitor you should now see that only messages sent using MMJ driver are getting through. We still hope that Apple can get the thing fixed.

Finally, close the devices.

scala> mmj.close; osx.close

October 21st, 2011

Java MIDI driver for OS X

The Java MIDI driver for Apple OS X is getting shape. Now the driver can:

  • Register itself as a MIDI driver
  • Enumerate endpoints from Apple CoreMidi
  • Separate inputs from outputs

It still can not send or receive messages. The driver project is open sourced (MIT license) and shared on the Github page. As this is the first project where I used Java Native Interface, Objective C or Apple Core Foundation classes, I’m more than happy to get any feedback and suggestions how to improve any part of the code.

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.

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.

August 24th, 2011

Programming MIDI with Scala

I’ve got a pair of Stanton SCS.3d DaScratch controllers and a Native Instruments Traktor Pro DJ software. They are connected using DaRouter software which is based on Bome Midi Translator. It runs pretty well, but there’s one small issue. Traktor has four decks, and there is no way to control more than two decks using the two DaScratches with this setup. There is “deck” button on the controller, but it is only used to change between two decks if there’s only one DaScratch. The button has no effect with a pair of controllers. I believe Stanton SCS.3m mixer would solve this, but I don’t have one.

I could buy SCS.3m mixer, but it doesn’t offer a lot of value. To be honest, I’d rather use my iPad with TouchOSC for the controls outside the DaScratches. Not owning SCS.3m mixer I’m pretty much forced to use DaRouter. I could also buy a Bome Midi Translator and try to make a patch for four decks. As no-one has done it, I suppose it may be impossible to do with Bome. So, it is time to start a programming project. However, even if I develop software as my job, my MIDI programming skills are dated 10 years ago. Back then I used Windows low level MIDI API with Delphi.

For DJ’ing I use MacBook, so the first option came in to my mind was to use Xcode and Objective-C, but after looking examples, it really didn’t felt my thing. It is pretty verbose, and OOP paradigm is not too interesting for me. More interesting Haskell isn’t too mature to use with Xcode yet, and the learning curve is still pretty high. So, I turned to trusty Scala running on Java Virtual Machine. After my experience with Windows API and Delphi, I immediately noticed the following advantages:

  • Comparing to Xcode, the project is not cluttered with numerous files
  • With REPL, it is very easy to prototype any code
  • Scala is very productive when enumerating lists

I can admit the following disadvantages

  • Java Virtual Machine doesn’t start too fast – although it doesn’t matter now
  • Fading support of Java on Macintosh – but it is still supported
  • Performance – the application is not too hungry for that, and the performance decrease is not actually very high
  • Java UI tools are slightly out-fashioned – let’s see if this application is getting any user interface

December 14th, 2009

Fedora 12 and Nokia E55 bluetooth dial-up-networking

The good news with Fedora 12 is an extremely easy dial-up-networking connection with bluetooth devices. The sad thing is, Nokia E55 doesn’t have PAN type connection via bluetooth. The good thing is, DUN type connection is almost that easy.

Create connection to your mobile through System > Preferences > Bluetooth > Set up a new device wizard. Also create connection using NetworkManagers Edit connections > Mobile Broadband > Add wizard. This should be enough for PAN, but not for DUN connection used in Nokia devices.

For dial-up-networking, you need to install Blueman application, for example by using terminal.

sudo yum install blueman

Then open System > Preferences > Bluetooth Manager, select your phone and choose Device > Serial ports > Dialup service. Now Blueman tells, there’s a connection available on NetworkManager. It’s as easy as that.

December 14th, 2009

Upgrading to Fedora 12

This site seems to be about upgrading Fedora, so we’ll make no exception here. Fedora 12 is in our doorsteps. The following different upgrade options were used with mixed results:

  • preupgrade-command. Used three times, failed once because of too small /boot partition.
  • YUM upgrade. Used once, failed once. Made complete reinstall to survive.
  • DVD image on USB. Used once, failed once. Problem installing rpm package causing rpm to fail.

YUM upgrade has been the most successful method until Fedora 12, but now the recommended preupgrade route has been used. However, if you have systems to upgrade, you’ll probably have too small /boot partition. Well, I have not too good track record for other methods.

Again, if you have ATI, and you want to use catalyst (fglrx) driver, you can’t. X is in too new version for it.

June 12th, 2009

Upgrading to Fedora 11

Well, it’s again the time of the year, when we’ll all upgrade our Fedoras. Again, I’d recommend not to, unless you don’t have to worry about the following issues:

  • ATI Radeon drivers wouldn’t work. There’s no support yet for the kernel 2.6.29/2.6.30 used in Fedora 11.
  • Firefox 3.5 is in beta stage and the following add-ons don’t work yet: Google Gears, Google Notebook, Html Validator, Mouse Gestures Redox.
  • Thunderbird 3.0 is in beta stage and some of the add-ons don’t work yet.

I’ll keep this post updated, when the situation changes.

Edit: Mouse Gestures Redox need to be changed to Firefox 3.5 compatible FireGestures.
Edit: Added Google Notebook and Html Validator, usable add-ons both.
Edit: Added Thunderbird note.
Edit: Google Notebook is discontinued.
Edit: ATI drivers became available when Ubuntu 9.10 was released with 2.6.30 kernel.

February 24th, 2009

Upgrading to Fedora 10

Upgrading to Fedora 10 was a smooth job probably because of RPM Fusion.

To get the most of the new graphical bootup screen, add the vga-parameter in your boot config (/etc/grub.conf):

kernel /vmlinuz-2.6.27.[---8<---] rhgb quiet vga=0x31

The 0x31B is a Kernel VESA graphics mode in 1280×1024 resolution and in 16M colours. If it is not available in your case, check a VGA modes list. And don’t worry, you can change or remove the parameter from GRUB bootup screen.

December 3rd, 2008

Playing videos on Nokia S60

It is hard to find a decent information which videos Nokia E51 RealPlayer can play. Even the articles on the dedicated sites can be misleading.

So, I tried a little while the article above as a starting point. I compared the video I’ve taken with the phone, and another recorded with MythTV. The clip I used was only couple of seconds long to make the trying as fast-paced as possible.

The first thing I noticed from the article above, the ffmpeg supplied with Fedora can’t regocnise aac audio, but there’s a libfaac codec instead. So, that must be replaced.

Also the RealPlayer was completely confused if the video size was anything else than 320×240 and if the aspect wasn’t set. That makes 16:9 videos a little bit funny looking, but you can clip them or make letterbox stripes if you want to.

And here’s the result:

ffmpeg -i video.mpg2 -f mp4 -vcodec mpeg4 -b 250000 -r 15 -s 320x240 -aspect 4:3 \
   -acodec libfaac -ar 24000 -ab 64 -ac 2 video.mp4

If you are using MythTV output, remember to do the following:

mythtranscode --mpeg2 --infile video.mpg  --outfile video.mpg2