MP3 streaming from disk using mxj and JLayer

Sep 9, 2009 at 12:00am

MP3 streaming from disk using mxj and JLayer

Hello, after hours of trawling forums and the internet, I still haven’t found an external like sfplay~ that supports mp3 playback from disk. Why, why, why hasn’t this been implemented yet! It seems silly in this age of mp3s that max can’t stream them.

Well cutting to the chase, i’ve been trying to develop an mxj~ class using JLayer (http://www.javazoom.net/javalayer/javalayer.html) that will stream mp3s. I’ve made some progress in that i’ve implemented JLayer into mxj~ and got it decoding mp3 frames, but now i’ve hit a brick wall.
Basically my problem is that the decoder outputs frames of a different size to the max vector size. I’ve tried to make a sort of queueing system, but it was horrendously slow and glitchy.

If I provide the source, is anyone willing help out trying to sort mp3 support in max forever?

To compile the code below you’ll need to download the jLayer 1.01 jar from the link above. The version below just truncates the decoded mp3 frames to the size of the signal vector, resulting in an extremely disgusting but quite cool sound.

Cheers,

Rob

source:

import com.cycling74.max.*;
import com.cycling74.msp.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.decoder.SampleBuffer;

public class mp3stream extends MSPPerformer{
String filename;
Header currFrame;

private Bitstream bitstream;
private Decoder decoder;

private int playing = 0;

private static final String[] INLET_ASSIST = new String[]{
“messages in”
};

private static final String[] OUTLET_ASSIST = new String[]{
“(signal) Channel 1 Output”,”(signal) Channel 2 Output”
};

public mp3stream(){
declareInlets(new int[]{DataTypes.ALL});
declareOutlets(new int[]{SIGNAL,SIGNAL});

setInletAssist(INLET_ASSIST);
setOutletAssist(OUTLET_ASSIST);
}

public void open(String name){
FileInputStream in = null;
filename = name;

try {
in = new FileInputStream(“D:\Program Files\FL Studio 8\Data\Projects\breakz n dubstep\crumbling shuffle_2.mp3″);
} catch (FileNotFoundException e) {
post(“File not found.”);
}

if(in != null){
decoder = new Decoder();
bitstream = new Bitstream(in);
}
}

public void inlet(int i)
{
int inlet = getInlet();
if(inlet == 0){
playing = i;
}
}

public void perform(MSPSignal[] in, MSPSignal[] out){
float[] L = out[0].vec;
float[] R = out[1].vec;

if(playing == 1){
short[] frameData = null;

try {
frameData = decodeFrame();
} catch (JavaLayerException e) {}

if(frameData != null){
for(int i = 0;i
L[i] = frameData[i]/32768f;
R[i] = frameData[i+1]/32768f;
}
}
}
}

protected short[] decodeFrame() throws JavaLayerException{
try{
if(decoder==null)return null;
if(bitstream==null)return null;

currFrame = bitstream.readFrame();
if(currFrame==null)return null;

SampleBuffer output = (SampleBuffer)decoder.decodeFrame(currFrame, bitstream);
short[] samps = output.getBuffer();
bitstream.closeFrame();

return samps;
}
catch (RuntimeException e){
throw new JavaLayerException(“Exception decoding audio frame”, e);
}
}
}

#45390
Sep 9, 2009 at 7:05am

You can also use [jit.qt.movie] with [spigot~]

p

#163592
Sep 9, 2009 at 11:02am

Yeah, i’ve experimented with that, but there was a huge gap before the mp3 started playing unfortunately, and when it did, it played skipped a section from the start – certainly wasn’t true streaming, which is what i’m after.

#163593
Jan 4, 2010 at 9:33pm

Hey there, I’m pretty curious about trying this jlayer stuff – have you gotten anywhere further?

#163594
Jan 9, 2010 at 10:20am

what features are you interested in – play, pause, resume, stop, seek? variable playback speed?
i’ve been poking around in the jlayer code some time ago and got something going with mxj~.
not sure how safe it is to use, but if you feel like trying out some ‘hacky’ code, i could send you something for testing.

#163595
Jan 13, 2010 at 12:17am

I’m interested in basic playback: play, pause, resume, stop to start with. Seek, speed, and looped sections would be cool too. Would love to see what’s involved! There doesn’t seem to be a way to pm people on this forum, so you can get me at pnyboer at slambassador.com

#163596

You must be logged in to reply to this topic.