How to play audio file using the AudioTrack class?

2

I want to make an app to play drums, but as I'm starting to develop for android, I'm having trouble. I need to play an audio file with the class AudioTrack (because it has the lowest latency), but I did not understand how to use it to play a .mp3 file, for example.

I've already researched, but found only examples of the MediaPlayer class. Could anyone post an example of AudioTrack ?

    
asked by anonymous 28.05.2014 / 05:24

1 answer

2

The only way to play some audio by AudioTrack is a streaming PCM, as seen in documentation :

  

The AudioTrack class manages and plays a single audio resource for Java applications. It allows streaming of PCM audio buffers to the audio sink for playback. This is achieved by "pushing" the date to the AudioTrack object using one of the write(byte[], int, int) and write(short[], int, int) methods .

Free translation:

  

The AudioTrack class manages and plays an audio resource for Java applications. It allows streaming buffers of PCM audio to be the audio source for playback. This can be achieved by loading information into a AudioTrack object using one of the methods: write(byte[], int, int) and wirte(short[], int, int) .

You can use this tutorial to decompress the .mp3 file and upload it as PCM, using the JLayer library and the code below:

public static byte[] decode(String path, int startMs, int maxMs)
  throws IOException, com.mindtherobot.libs.mpg.DecoderException {
  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 com.mindtherobot.libs.mpg.DecoderException("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 com.mindtherobot.libs.mpg.DecoderException(e);
  } finally {
    IOUtils.safeClose(inputStream);    
  }
}

It should be noted that AudioTrack was not designed to load audio files. The ideal for loading compressed audio files (such as mp3 and ogg, for example) would be the MediaPlayer classes a> or SoundPoll , as seen in answers to this question from SOen.

    
28.05.2014 / 16:52