Help with J2ME Streaming

Hi,

My name is Constantinos Loizou and I am a student and currently developing a project for my Master's degree.

I need to stream audio and/or video to a PDA device. There is a trick here which is:

The PDA must receive the stream from a multicast address. For this I have implemented a Bridge application which joins the multicast group on behalf of the PDA and receives the Multicast RTP packets (which are sent from JMStudio) and Unicasts them to the PDA.(HP iPAQ) I had no problem implementing this. The streaming is done using JMStudio player which encodes the streaming audio data into a number of encodings (DVI/RTP in my case). I choose DVI/RTP and stream a .wav audio file.

Now I have to accept the packets and play the stream on the PDA.

The j2me application receives all the RTP packets successfully and I can extract usefull information from the packets such as: Timestamp, sequence number, payload type. The payload type is 5 which means it is a DVI4 encoding therefor the packets are accepted without any problem. I then save the data of the packet into a byte[] array and in regular intervals (50 000 bytes) I load them into a new ByteArrayInputStream(buffer); When I try to load the BytearrayInputStream and open it with a player I get the following error message:

javax.microedition.media.MediaException: Failed to realize Player: Malformed wave media: expected 'RIFF'

at com.sun.mmedia.WavPlayer.doRealize(+160)

at com.sun.mmedia.BasicPlayer.realize(+84)

at src.ViewVideoCanvas.run(ViewVideoCanvas.java:112)

The command I run is: player = Manager.createPlayer(input, "audio/x-wav");//create new player

And the error occurs on player.realize();

I believe that this happens beacause the data is encoded to DVI/rtp. I have searched a lot and found the algorithm of decompressing the DVI data but again I get the same error

Anyway, this is a brief description of my problem and I hope you can help me.

Contact me for any more details or help you can provide (code sammples, decoding algorithms and implementations in java)

Thank you

Constantinos Loizou

[2172 byte] By [cs02lk1a] at [2007-11-27 9:21:47]
# 1
did you have a look on this article... http://today.java.net/pub/a/today/2006/08/22/experiments-in-streaming-java-me.html
suparenoa at 2007-7-12 22:15:49 > top of Java-index,Java Mobility Forums,Java ME Technologies...
# 2

thanks for your reply

I did look into this article but it does not help me because writing your custom datasource is not really helpfull in my situation.

What I realized last night is that when I decode the DVI samples into PCM data I get an array without the headers of a WAV file and that's why the player trhows an exception

I am reading now regarding wav headers and I will try appending the header at the beginning of the byte array and try and play it.

if you hava anything about that subject please tell me

Thanks

cs02lk1a at 2007-7-12 22:15:49 > top of Java-index,Java Mobility Forums,Java ME Technologies...
# 3

I have managed to surpass the error of the player. I just needed to insert to my byte array a 44byte WAVE PCM header.

The player now initializes ok without any problem but I can only hear a meesed up sound rather than the original. So now I strongly believe that the problem is in the decoding of the samples of the DVI/RTP codec.

I use the following method to decode the samples:

public int decode(Object state, byte[] input, int inp, int len, short[] output, int outp) {

int sign;

int delta;

int vpdiff;

//int valprev = audio.Convert.byte2short(input, inp);

//int index = input[inp + 2];

int valprev=0,index=0;

int inputbuffer = 0;

int bufferstep = 0;

////////////////////////////////////

valprev = input[0] <<8;

valprev |= input[1] &0xff;

index = input[2] &0xff;

//////////////////////////////////////////

if ( index < 0 ) index = 0;

else if ( index > 88 ) index = 88;

int step = stepsizeTable[index];

inp += 4;

len = (len - 4) * 2;

int count = len;

while(count-- > 0) {

if ( 0 == bufferstep ) {

inputbuffer = input[inp++];

delta = (inputbuffer >> 4) & 0xf;

bufferstep = 1;

} else {

delta = inputbuffer & 0xf;

bufferstep = 0;

}

index += indexTable[delta];

if ( index < 0 ) index = 0;

else if ( index > 88 ) index = 88;

sign = delta & 8;

delta = delta & 7;

vpdiff = step >> 1;

if ( (delta & 4) == 4 ) vpdiff += (step << 2);

if ( (delta & 2) == 2 ) vpdiff += (step << 1);

if ( (delta & 1) == 1 ) vpdiff += step;

vpdiff >>= 2;

if ( 0 != sign )

valprev -= vpdiff;

else

valprev += vpdiff;

if ( valprev > 32767 )

valprev = 32767;

else if ( valprev < -32768 )

valprev = -32768;

step = stepsizeTable[index];

output[outp++] = (short) valprev;

}

((AdpcmState)state).valprev = valprev;

((AdpcmState)state).index = index;

return len;

}

which stores the result into a short[] array.

I then convert this short[] array into a byte[] array with the following way:

s is the short[] array

adp is the byte array

for(int g=0,k=0;g<s.length;g++,k=k+2){

audio.Convert.short2byte(s[g],adp,k);

}

public static void short2byte(short ival, byte b[], int offset) {

int i;

int bits = 16;

for(i = 0; i >< 2; i++) {

bits -= 8;

b[offset + i] = (byte) ((ival >> bits) & 0xff);

}

}

The final result is loaded to the player as follows:

ByteArrayInputStream input1 = new ByteArrayInputStream(adp);

player = Manager.createPlayer(input1, "audio/x-wav");//create new player

player.addPlayerListener(this);

player.prefetch();

player.realize();

player.start();

The player begins to play but I only get horrible sounds instead of the original wave file

Please help

Thanks

cs02lk1a at 2007-7-12 22:15:49 > top of Java-index,Java Mobility Forums,Java ME Technologies...