I wrote a simple Clojure framework for playing music (and then some other things) for my Raspberry Pi. The program analyzes the given music catalog for songs, and then starts listening to control commands (such as start, stop, next song) via the TCP interface.
The code is available through GitHub:
https://github.com/jvnn/raspi-framework
The current version works fine on my laptop, it starts playing music (using the JLayer library) when specifying, changing songs, and stops as it should. Ubergar takes a few seconds to get started with a laptop, but when I try to run it on a Raspberry Pi, everything gets insanely slow.
Just run the program so that all classes are loaded and the actual program code starts to run in more than a minute. I tried to launch it using the -verbose: class switch, and it seems that jvm spends all the time loading tons of classes (for Clojure and everything else).
When the program finally starts, it responds to commands, but playback is very backward. There is a short sub-second sound, then a pause for almost a second, then another sound, another pause, etc. So, the program is trying to play something, but simply cannot do it fast enough. CPU usage is somewhere close to 98%.
Now that I have an Android phone and thatβs it, Iβm sure that Java can be executed on such equipment well enough to play some mp3 files without any problems. And I know that JLayer (or parts of it) is used in the gdx game development platform (which also works on Android), so this should not be a problem either.
So, everything indicates that I am a problem. Is there something I can do with leiningen (aot is already included for all files), Raspberry Pi or my code that can speed up execution?
Thank you for your time!
UPDATE:
I did a tiny test case to rule out some possibilities, and problems still exist with the following Clojure code:
(ns test.core
(:import [javazoom.jl.player.advanced AdvancedPlayer])
(:gen-class))
(defn -main
[]
(let [filename "/path/to/a/music/file.mp3"
fis (java.io.FileInputStream. filename)
bis (java.io.BufferedInputStream. fis)
player (AdvancedPlayer. bis)]
(doto player (.play) (.close))))
.Clj project:
(defproject test "0.0.1-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.5.1"]
[javazoom/jlayer "1.0.1"]]
:javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"]
:aot :all
:main test.core)
So there is no core.async and no threads. Playback has become a little smoother, but it's still about 200 ms of music and a pause of 200 m.