1

First of all, if not using function decode_path , I can play .wav file with my code , and it works fine I use Jlayer and audio track to play the song.

Second, if I use function decode_path it can decode mp3 to pcm file , and pass the byte[] to function PlayAudioTrack, and let it play.

The quesion is,I don't know where my code is wrong , I use 320Kbps, 44.1Khz stereo type, Layer3 mp3, but the AudioTrack plays noise but no music~!!!!

can anyone ? ???

My code

 public void PlayAudioTrack(String filePath) throws IOException{
    int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
    AudioFormat.ENCODING_PCM_16BIT);

    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
    AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);

    //Reading the file..
    int count = 512 * 1024; // 512 kb
    //        byte[] byteData = null;        
    //        byteData = new byte[(int)count];

    //we can decode correct byte data here
    byte[] byteData = null;
    byteData = decode_path(filePath, 0, 20000);

    File file = null; 
    file = new File(filePath);
    FileInputStream in = null;

    try {
        in = new FileInputStream( file );
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    int bytesread = 0, ret = 0;
    int size = (int) file.length();
    at.play();
    while (bytesread < size) {
        Log.e("devon","write byte array with sizes");
        ret = in.read( byteData,0, count);
        if (ret != -1) {
            Log.e("devon","Write the byte array to the track");
            at.write(byteData,0, ret); 
            bytesread += ret;  
        }else break;
    }
    at.stop(); 
    at.release();
}

public static byte[] decode_path(String path, int startMs, int maxMs) 
        throws IOException{
        ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);

        float totalMs = 0;
        boolean seeking = true;

        File file = new File(path);
        InputStream inputStream = new BufferedInputStream(new FileInputStream(file), 8 * 1024);
        try {
          Bitstream bitstream = new Bitstream(inputStream);
          Decoder decoder = new Decoder();

          boolean done = false;
          while (! done) {
            Header frameHeader = bitstream.readFrame();
            if (frameHeader == null) {
              done = true;
            } else {
              totalMs += frameHeader.ms_per_frame();

              if (totalMs >= startMs) {
                seeking = false;
              }

              if (! seeking) {
                SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);

                if (output.getSampleFrequency() != 44100
                    || output.getChannelCount() != 2) {
                    throw new IllegalArgumentException("mono or non-44100 MP3 not supported");
                }

                short[] pcm = output.getBuffer();
                for (short s : pcm) {
                  outStream.write(s & 0xff);
                  outStream.write((s >> 8 ) & 0xff);
                }
              }

              if (totalMs >= (startMs + maxMs)) {
                done = true;
              }
            }
            bitstream.closeFrame();
          }

          return outStream.toByteArray();
        } catch (BitstreamException e) {
          throw new IOException("Bitstream error: " + e);
        } catch (DecoderException e) {
          Log.w(TAG, "Decoder error", e);
          throw new IOException("Decoder error: " + e);
        }
      }
Ashton
  • 2,425
  • 2
  • 22
  • 26
  • Do you have to use `AudioTrack`? If you used the [MediaPlayer](http://developer.android.com/reference/android/media/MediaPlayer.html) class, it would handle the decoding for you. – Michael Sep 26 '13 at 11:02
  • ya, I know. But I need a to get the PCM from MP3, I just wanna check my decoder is correct or not. – Ashton Sep 26 '13 at 11:04
  • the main purpose is to do a mp3 decoder which can get PCM stream. – Ashton Sep 26 '13 at 11:05
  • Thank you for your typo editing... Thanks – Ashton Sep 26 '13 at 11:07
  • Ok, well, why do you have this in your playback loop: `ret = in.read( byteData,0, count);` ? Isn't `byteData` supposed to come from `decode_path` ? – Michael Sep 26 '13 at 11:09
  • can't get it, not understanding... – Ashton Sep 27 '13 at 01:43
  • Shouldn't you be writing the data that was returned from `decode_path` to the `AudioTrack`? That's supposed to be decoded PCM, isn't it? But what you're doing instead - at least it looks like it - is take _mp3-encoded_ data _directly_ from the mp3 file (with `in.read`) and writing it to the `AudioTrack`. – Michael Sep 27 '13 at 05:45
  • Did you ever figure this out? I'm working on the same problem. – mikejonesguy Mar 26 '14 at 06:47
  • If you find a solution, share it by answering your question on StackOverflow. Also how to you determine the maxMs of a file or is 20000ms the maximum time that your player supports? – xabush Feb 04 '16 at 01:55

1 Answers1

-3
public void PlayAudioTrack(String filePath) throws IOException{
    int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
            AudioFormat.ENCODING_PCM_16BIT);

    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
            AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);

    //Reading the file..
    int count = 512 * 1024; // 512 kb
    //        byte[] byteData = null;
    //        byteData = new byte[(int)count];

    //we can decode correct byte data here
    byte[] byteData = null;
    byteData = decode_path(filePath, 0, 20000);

    int temp =0;
    at.play();
    while (temp<byteData.length)
    {
        at.write(byteData, temp, count);
        temp+= count;
    }
    at.stop();
    at.release();
}
Vardan
  • 9