0

I am currently working with AudioTrack. I am loading an mp3 file and playing it. However, depending on devices, the music plays either at half the rate or normal rate.

My code:

AudioTrack track= new AudioTrack( AudioManager.STREAM_MUSIC,
    sampleRate,
    AudioFormat.CHANNEL_CONFIGURATION_MONO,
    AudioFormat.ENCODING_PCM_16BIT,
    initBuffer,
    AudioTrack.MODE_STREAM);

sampleRate is the sample rate return by AudioFormat and initBuffer the buffer size from AudioTrack.getMinBufferSize().

I have tried to change the sample rate but no difference. Buffer size also has no impact.

In fact, switching to CHANNEL_CONFIGURATION_STEREO does make the music play at normal rate on the devices that were slow, but it also makes the ones working fine playing at twice the normal speed. My problem is that I want all devices to play at the normal speed.

Any suggestions?

I have read this thread:Android AudioTrack slow playback, but it doesn't tell me how to find out which devices should play in mono or stereo.

Devices at normal speed: Urbano 4.2.2, Galaxy S4 4.3

Devices at half the speed, Galaxy S4 4.2.2, Experia Z 4.2.2

BTW, I cannot use MediaPlayer for playback. The AudioTrack is included in a custom player and I need to write audio data as I extract it. MediaPlayer won't do the trick.

Thanks.

Community
  • 1
  • 1
Herve
  • 36
  • 7
  • If you haven't already, you might benefit by subscribing to [andraudio](http://music.columbia.edu/mailman/listinfo/andraudio) and asking there. – Reed Sep 06 '14 at 18:13
  • Thanks! I will check there too – Herve Sep 06 '14 at 18:21

4 Answers4

2

I experienced it when trying to decode mono file using MediaCodec. On some devices,the codec would output stereo stream while mono on other. When setting up the audio track I used media format returned by MediaExtractor, which was mono. On devices where the codec would produce stereo stream, the audio track would be fed with twice as many samples. The solution is to listen for MediaFormatChanged event from MediaCodec and adjust the MediaFormat of the AudioTrack.

Maciej Grzyb
  • 543
  • 2
  • 10
0

AudioTrack only allows PCM audio data, you cannot play mp3 wit AudioTrack directly, you have to convert your mp3 to PCM or use something else (e.g. MediaPlayer) than AudioTrack.

Aladin Q
  • 550
  • 5
  • 12
0

I finally solved my problem. Not the best fix but it works at least.

For those who are interested, I am reading the BufferInfo size and based on it, decide at which playback rate I should play. Basically when playback is slow the size is twice bigger than for normal speed playback. Just a guess, but the MediaCodec might duplicate data for stereo configuration.

Herve
  • 36
  • 7
0

This one is a little tricky but here is what you can do using adb and ALSA.
Android internally uses ALSA.

Your device should have ALSA, try :

root@user:/$ adb shell cat /proc/asound/version
Advanced Linux Sound Architecture Driver Version 1.0.25.

Just take a look at Reading ALSA Device names.
Every device (subdivision of a card) has a capture and a playback component.

Like /proc/asound/card0/pcm1p and /proc/asound/card0/pcm1p where card is 0 device is 1 pcm1p is your playback and pcm1c is capture (for recording).

  1. Access your device using adb:

    root@user:/$ adb shell
    shell@android:/$:  
    
  2. Identifying your device:

    So you see /proc/asound/pcm will give you a long list.

    shell@android:/$: cat /proc/asound/pcm                                     
    00-00: MultiMedia1 (*) :  : playback 1 : capture 1
    00-01: MultiMedia2 (*) :  : playback 1 : capture 1
    00-02: CS-Voice (*) :  : playback 1 : capture 1
    

    From the above I find 00-00: MultiMedia1 (*) as card0 and device0 is for Multimedia playback.

  3. Getting Playback Parameter:

    Play your loaded mp3 file using your standard music player Application.
    While the song is playing.
    Issue the following commands for card0, device0(p - playback), and subdevice0

    shell@android:/$: cat /proc/asound/card0/pcm0p/sub0/hw_params              
    access: RW_INTERLEAVED
    format: S16_LE
    subformat: STD
    channels: 2
    rate: 44100 (44100/1)
    period_size: 1920
    buffer_size: 3840
    

    So try using the same values when you call AudioTrack track= new AudioTrack(...); The above value will only be visible when the device is in open (Playing some audio).

    If you issue this to a wrong device (like say pcm1p), you will see the following:

    shell@android:/$: cat /proc/asound/card0/pcm1p/sub0/hw_params    
    closed
    

Note :
Step 1 doesn't require phone to be rooted, How to Setup ADB.

Alternatives:

  1. Have you tried the AudioTrack APIs like getChannelConfiguration() or getChannelCount() from here - Just Asking.
  2. Have you tried looking at the MP3 file properties, the metadata has information on the audio parameters.
Saurabh Meshram
  • 8,106
  • 3
  • 23
  • 32