android - JLayer decoder for mp3 stream and AudioTrack playback -


after trying lort of things play , mp3 server (not using mediaplayer because of latency issues) have come piece of code working.

i stream server async task, feed jlayer's decoder turn pcm data. feed audiotrack instance.

right hear lot of stutter, im positive because @ least hear something.

can me fix stutter or point me in direction on how fix stutter?

much appreciated!

package com.example.mediadecoderexample;  import java.io.bytearrayinputstream; import java.io.ioexception; import java.io.inputstream; import java.net.httpurlconnection; import java.net.url; import java.nio.bytebuffer;  import javazoom.jl.decoder.bitstream; import javazoom.jl.decoder.bitstreamexception; import javazoom.jl.decoder.decoder; import javazoom.jl.decoder.decoderexception; import javazoom.jl.decoder.header; import javazoom.jl.decoder.samplebuffer; import android.app.activity; import android.media.audioformat; import android.media.audiomanager; import android.media.audiotrack; import android.media.mediacodec; import android.media.mediacodec.bufferinfo; import android.media.mediaextractor; import android.media.mediaformat; import android.os.asynctask; import android.os.bundle; import android.util.log; import android.view.menu;  public class mainactivity extends activity {      public final string log_tag = "mediadecoderexample";     mediacodec codec;     mediaextractor extractor;      mediaformat format;     bytebuffer[] codecinputbuffers;     bytebuffer[] codecoutputbuffers;     boolean sawinputeos = false;     boolean sawoutputeos = false;     audiotrack maudiotrack;     bufferinfo info;     string url = "http://82.201.100.9:8000/radio538_web_mp3";      @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);          extractor = new mediaextractor();          try {             extractor.setdatasource(url);         } catch (ioexception e) {         }          format = extractor.gettrackformat(0);         string mime = format.getstring(mediaformat.key_mime);         int samplerate = format.getinteger(mediaformat.key_sample_rate);          log.i(log_tag, "===========================");         log.i(log_tag, "url "+url);         log.i(log_tag, "mime type : "+mime);         log.i(log_tag, "sample rate : "+samplerate);         log.i(log_tag, "===========================");          codec = mediacodec.createdecoderbytype(mime);         codec.configure(format, null , null , 0);         codec.start();          codecinputbuffers = codec.getinputbuffers();         codecoutputbuffers = codec.getoutputbuffers();          extractor.selecttrack(0);           maudiotrack = new audiotrack(                 audiomanager.stream_music,                  samplerate,                  audioformat.channel_out_stereo,                  audioformat.encoding_pcm_16bit,                  audiotrack.getminbuffersize (                         samplerate,                          audioformat.channel_out_stereo,                          audioformat.encoding_pcm_16bit                         ),                  audiotrack.mode_stream                 );          maudiotrack.play();          new longoperation().execute("");     }      @override     public boolean oncreateoptionsmenu(menu menu) {         // inflate menu; adds items action bar if present.         getmenuinflater().inflate(r.menu.main, menu);         return true;     }       public short[] decode(byte[] mp3_data) throws ioexception {              samplebuffer output = null;             inputstream inputstream = new bytearrayinputstream(mp3_data);             short[] pcmout = {};             try {                 bitstream bitstream = new bitstream(inputstream);                 decoder decoder = new decoder();                 boolean done = false;                 int = 0;                 while (! done) {                     header frameheader = bitstream.readframe();                     if (frameheader == null) {                         done = true;                     } else {                         output = (samplebuffer) decoder.decodeframe(frameheader, bitstream);                         short[] next = output.getbuffer();                         pcmout = concatarrays(pcmout, next);                         maudiotrack.write(pcmout, 0, pcmout.length);                     }                      bitstream.closeframe();                     i++;                 }                 return pcmout;              } catch (bitstreamexception e) {                 throw new ioexception("bitstream error: " + e);             } catch (decoderexception e) {                 log.w(log_tag, "decoder error", e);             }             return null;         }           short[] concatarrays(short[] a, short[] b) {              int alen = a.length;             int blen = b.length;             short[] c= new short[alen+blen];              system.arraycopy(a, 0, c, 0, alen);             system.arraycopy(b, 0, c, alen, blen);              return c;         }      private class longoperation extends asynctask<string, void, string> {         @override         protected string doinbackground(string... params) {               url u;             httpurlconnection c;             try {                 u = new url(url);                 c = (httpurlconnection) u.openconnection();                  c.setrequestmethod("get");                 c.setdooutput(false);                 c.connect();                  inputstream in = c.getinputstream();                   byte[] buffer = new byte[1024];                 int len1 = 0;                 while ( (len1 = in.read(buffer)) > 0 ) {                     log.i(log_tag, buffer.length+" bytes input");                      short[] pcmout = mainactivity.this.decode(buffer);                     log.i(log_tag, pcmout.length+" bytes ouput");                  }             } catch (ioexception e) {                 // todo auto-generated catch block                 e.printstacktrace();             }             return null;         }          @override         protected void onpostexecute(string result) {         }          @override         protected void onpreexecute() {         }          @override         protected void onprogressupdate(void... values) {         }     } } 


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -