S7uXN37 S7uXN37 - 1 month ago 8x
Android Question

Android: Read audio data from file uri

I want to analyse an audio file (mp3 in particular) which the user can select and determine what notes are played, when they're player and with what frequency.

I already have some working code for my computer, but I want to be able to use this on my phone as well.

In order to do this however, I need access to the bytes of the audio file. On my PC I could just open a stream and use AudioFormat to decode it and then read() the bytes frame by frame.

Looking at the Android Developer Forums I can only find classes and examples for playing a file (without access to the bytes) or recording to a file (I want to read from a file).

I'm pretty confident that I can set up a file chooser, but once I have the Uri from that, I don't know how to get a stream or the bytes.

Any help would be much appreciated :)

Edit: Is a similar solution to this possible? Android - Read a File
I don't know if I could decode the audio file that way or if there would be any problems with the Android API...


So I solved it in the following way:

Get an InputStream with

final InputStream inputStream = getContentResolver().openInputStream(selectedUri);

Then pass it in this function and decode it using classes from JLayer:

private synchronized void decode(InputStream in)
        throws BitstreamException, DecoderException {

    ArrayList<Short> output = new ArrayList<>(1024);

    Bitstream bitstream = new Bitstream(in);
    Decoder decoder = new Decoder();

    float total_ms = 0f;
    float nextNotify = -1f;

    boolean done = false;
    while (! done) {
        Header frameHeader = bitstream.readFrame();

        if (total_ms > nextNotify) {
            mListener.OnDecodeUpdate((int) total_ms);
            nextNotify += 500f;

        if (frameHeader == null) {
            done = true;
        } else {
            total_ms += frameHeader.ms_per_frame();

            SampleBuffer buffer = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream); // CPU intense

            if (buffer.getSampleFrequency() != 44100 || buffer.getChannelCount() != 2) {
                throw new DecoderException("mono or non-44100 MP3 not supported", null);

            short[] pcm = buffer.getBuffer();
            for (int i = 0; i < pcm.length-1; i += 2) {
                short l = pcm[i];
                short r = pcm[i+1];

                short mono = (short) ((l + r) / 2f);

                output.add(mono); // RAM intense



The full project (in case you want to look up the particulars) can be found here: https://github.com/S7uXN37/MusicInterpreterStudio/