keston
keston

Reputation: 121

Seamless Looping with SoundPool on Android?

I am trying to loop short (20kb), gapless ogg files with the SoundPool class and cannot get consistent results while testing on hardware. It always plays back perfectly using the emulator but when I test on a Nexus 1, or on a Samsumg Galaxy Tab 10.1 there are audible pops or clicks at every loop point. What is very strange is that while consistent once the application has started, the clicks are slightly different every time I restart the app and on rare occasions (more frequently on the tablet) the loop plays correctly.

The results are no better using MediaPlayer. Is it unreasonable to expect gapless playback of audio loops on android? Surely someone has similar functionality working properly? If so I would love to see an example of how it works.

Thanks!

Upvotes: 12

Views: 3015

Answers (3)

yaircarreno
yaircarreno

Reputation: 4257

I found other solution:

afd = assetManager.openFd(nameSound);

player.setDataSource(afd.getFileDescriptor(),
                     afd.getStartOffset(), afd.getLength() - 1000);
afd.close();
player.prepare();
player.setLooping(true);
player.start();

You only need to define the duration 1000(1ms) less instead that the total duration. Y eso es todo, problema resuelto!!!!

Upvotes: 1

SARose
SARose

Reputation: 3725

This might sound like a cop out but there are a 2 things you can try, the first of which worked for me.

  1. Make you audio files ogg format at 48kHz sample rate and 48Kbit/s (This worked for me)

  2. You can create 2 MediaPlayer Objects and (just like the @Beowulf Bjornson 's answer) approximately <= 100ms start MediaPlayer #2 just before MediaPlayer #1 ends and alternate between the entire time.

Hope people that come here tries what I've said because I've wasted about 3 days trying to figure this out only to be amazed that there isn't an out of the box way to do this flawlessly.

Upvotes: 0

Beowulf Bjornson
Beowulf Bjornson

Reputation: 1626

I used a hack that works fine for single files:

HACK_loopTimer = new Timer();
HACK_loopTask = new TimerTask() {               
    @Override public void run() {
        mMediaPlayer.seekTo(0);
    }
};
long waitingTime = mMediaPlayer.getDuration()-mHackLoopingPreview;
HACK_loopTimer.schedule(HACK_loopTask, waitingTime, waitingTime);

Just set mHackLoopingPreview to a reasonable amount; I'm using 100ms and it is working fine. I have to agree that this is a less than ideal and ugly solution, but at least it does its job.

Upvotes: 4

Related Questions