MuXM with J2ME/MIDP2 Tutorial

There are two ways to get audio data in the MuXM API:

  • With ModuleInputStream class (see examples below)
  • With getAudio() method of the MuXM class (see MuXM J2SE tutorial)

The three examples below presents the three solutions to play the generated audio data.

  • Solution 1 (buffering): MuXM + MIDP2 media API
  • Solution 2 (buffering): MuXM + MuLine + MIDP2 media API
  • Solution 3 (real-time): MuXM + MuLine + MIDP2 media API

The first example shows the usage of MuXM API to fill an audio buffer which is played next with MIDP2 media API.

// PCM 8000 KHz, 16 bits, 1 channel (mono)
int sampleRate = 8000;
int bitsPerSample = 16;
int channels = 1;

// Create MuXM engine instance.
Module module = Loader.load(fileInputStream);
ModuleEngine engine = new ModuleEngine(module);
engine.setSamplingRate(sampleRate);
engine.setStereo(channels > 1 ? true : false);
Module2WavInputStream wavInputStream = new Module2WavInputStream(engine);

// Fill the output audio buffer (20 seconds)     
int playTime = 20;
int lengthToEnd = playTime * sampleRate * (bitsPerSample / 8) * channels;
int bufferSize = 1000;
byte[] buffer = new byte[bufferSize];
int len = bufferSize;
ByteArrayOutputStream bos = new ByteArrayOutputStream();

while (lengthToEnd > 0) {

    if (len > lengthToEnd) {
        len = lengthToEnd;
    }

    int readBytes = wavInputStream.read(buffer, 0, len);
                    
    if (readBytes != -1) {
        bos.write(buffer, 0, readBytes);
        lengthToEnd -= readBytes;
    } else {
        break;
    }

}

// Now play audio.
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Player player = Manager.createPlayer(bis, "audio/x-wav");
player.start();   

The second example below shows the usage of MuXM API + MuLine API to fill an audio buffer which is played with MIDP2 media APĪ. We achieved the same result than in the first example but MuLine provides a more generic way to build a WAV stream (i.e. not specific to MuXM)

// PCM 8000 KHz, 16 bits, 1 channel (mono), signed, little endian
AudioFormat format = new AudioFormat(8000, 16, 1, true, false);

// Create MuXM engine instance.
Module module = Loader.load(fileInputStream);
ModuleEngine engine = new ModuleEngine(module);
engine.setSamplingRate(format.sampleRate);
engine.setStereo(format.channels > 1 ? true : false);
ModuleInputStream moduleInputStream = new ModuleInputStream(engine);

// Create the WAV file.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
AudioFormatWriter writer = new PCMWavWriter();
writer.initialize(bos, format, format.sampleRate, bufferSize);
writer.writeHeader();

// Fill the output audio buffer (20 seconds)
int playTime = 20;
int lengthToEnd = playTime * format.sampleRate * (format.bitsPerSample / 8) * format.channels;
int bufferSize = 1000;
byte[] buffer = new byte[bufferSize];
int len = bufferSize;

while (lengthToEnd > 0) {

    if (len > lengthToEnd) {
        len = lengthToEnd;
    }

    int readBytes = moduleInputStream.read(buffer, 0, len);
                    
    if (readBytes != -1) {
        writer.writeAudioData(buffer, 0, readBytes);
        lengthToEnd -= readBytes;
    } else {
        break;
    }

}

// Now play audio.
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Player player = Manager.createPlayer(bis, "audio/x-wav");
player.start();   
             

If your MIDP2 device supports streaming you can use MuLine instead of buffering. See the third example below.

// PCM 8000 KHz, 16 bits, 1 channel (mono), signed, little endian
AudioFormat format = new AudioFormat(8000, 16, 1, true, false);

// Get/Generate audio buffer with corresponding size.
Module module = Loader.load(fileInputStream);
ModuleEngine engine = new ModuleEngine(module);
engine.setStereo(format.channels > 1 ? true : false);
engine.setSamplingRate(format.sampleRate);
ModuleInputStream moduleInputStream = new ModuleInputStream(engine);

OutputAudioLine line = new MidpOutputAudioLine();
int bufferSize = 1000;
byte[] buffer;

try {

    // Open the line and configure it to accept audio data with
    // a given format.
    line.open(format, bufferSize);

    line.start();
    
    while(!stopped) {
 
        //Obtains the number of bytes of data that can be written 
        // to the buffer without blocking.
        int available = line.available();

        // Get audio data and write it to the line.
        int readBytes = moduleInputStream.read(buffer, 0, available);
        if (readBytes != -1) {
        	// Write data to the line
            line.write(buffer, 0, readBytes);
        }
        
    }

    // Don't forget to drain the line, i.e push audio data inside
    // the buffer to the line. 
    line.drain();

    // Close line for releasing ressources. 
    line.close();

} catch (IOException e) {
	// ...
}