MuXM with J2SE Tutorial

Basically there are two solutions to play module files with J2SE:

  • In the same way than for J2ME but in using JavaSound instead of MIDP2 media API. (see example below)
  • With MuXM SPI (JavaSound SPI implementaion) : it allows to add MOD/XM support to all Java applications without having to deal with MuXM API. See the dedicated page for more information)

The example below shows how to use MuXM API and JavaSound to play audio from given file names. The class provides an other implementation than in the MIDP2 tutorial: ModuleEngine.getAudio() method is used instead of Module2PcmInputStream class.


public class ModulePlayerExample implements Runnable {
    private final int SAMPLE_RATE = 44100;

    private ModuleEngine engine;
    private boolean songloop, running;

    public ModulePlayerExample(URL modfile) throws IOException {
        InputStream i = modfile.openStream();
        Module m = Loader.load(i);
        i.close();
        engine = new ModuleEngine(m);
        engine.setSamplingRate(SAMPLE_RATE);
        setloop(true);
    }

    /**
     *	Set whether the song is to loop continuously or not.
     *	The default is to loop.
     */
    public void setloop(boolean loop) {
        songloop = loop;
    }

    /**
     *	Begin playback.
     *	This method will return once the song has finished, or stop has been called.
     */
    public void run() {
        running = true;
        int bufframes = 1024;
        byte[] obuf = new byte[bufframes << 2];
        try {
            AudioFormat af = new AudioFormat(SAMPLE_RATE, 16, 2, true, false);
            DataLine.Info lineInfo = new DataLine.Info(SourceDataLine.class, af);
            SourceDataLine line = (SourceDataLine) AudioSystem.getLine(lineInfo);
            line.open();
            line.start();

            System.out.println("Playing...");

            int songlen = engine.getSongLength();
            int remain = songlen;
            while (remain > 0 && running) {
                int count = bufframes;
                if (count > remain)
                    count = remain;
                engine.getAudio(obuf, 0, count, true);
                line.write(obuf, 0, count << 2);
                remain -= count;
                if (remain <= 0 && songloop)
                    remain = songlen;
            }
            line.drain();
            line.close();
        } catch (LineUnavailableException e) {
            e.printStackTrace();
            return;
        }
    }

    /**
     *	Instruct the run() method to finish playing and return.
     */
    public void stop() {
        running = false;
    }

    /**
     *	Plays the module specified on the command line once.
     */
    public static void main(String[] args) throws Exception {
        if (args.length == 0) {
            System.out.println("Please specify a module file to play.");
            return;
        }
        ModulePlayerExample player = new ModulePlayerExample(new File(args[0]).toURL());
        player.setloop(false);

        new Thread(player).start();
    }
}