/**
* Controls the Audio Player and adapts to the quirks of the Android AudioPlayer.
*/
package org.androiddaisyreader.controller;
import java.util.logging.Logger;
import org.androiddaisyreader.AudioPlayer;
import org.androiddaisyreader.player.SegmentTimeInfo;
import org.androiddaisyreader.model.Audio;
import org.androiddaisyreader.model.AudioPlayerState;
/**
* OK, let's go...
*
* @author Julian Harty
*/
public class AudioPlayerController {
private AudioPlayer player;
private Logger log = Logger.getLogger("AudioPlayerController");
@SuppressWarnings("unused")
private AudioPlayerController() {
// Stop people from calling me without providing a player.
}
public AudioPlayerController(AudioPlayer player) {
this.player = player;
}
/**
* Play the audio from part of a file. Starts at the time specified in the
* from parameter. Finishes when the duration has been reached, or at the
* end of the file, whichever's sooner.
*
* Android's MediaPlayer does not include a facility to 'stop' at a
* particular duration. Instead it plays to the end of the file. Therefore
* we want to emulate the behaviour of the Android player in this Mock audio
* player.
*
* @param segment The audio segment to play
*/
public void playFileSegment(Audio audioSegment) {
Audio currentSegment = player.getCurrentSegment();
if (currentSegment == null) {
log.info("Starting to play a new file");
player.setInternalPlayerState(AudioPlayerState.PLAY_NEW_FILE);
player.setCurrentSegment(audioSegment);
player.play();
return;
}
// Note: if we are able to determine the overall duration of the
// fileToPlay
// we could check whether the duration is valid. For now, we'll assume
// it is.
if (currentSegment.getAudioFilename().matches(audioSegment.getAudioFilename())) {
int newClipStartsAt = audioSegment.getClipBegin();
int previousClipEndsAt = currentSegment.getClipEnd();
SegmentTimeInfo interval = SegmentTimeInfo.compareTimesForAudioSegments(
newClipStartsAt, previousClipEndsAt);
// Update the Player with details of the new segment.
player.setCurrentSegment(audioSegment);
switch (interval) {
case CONTIGUOUS:
log.info("The player will continue playing the existing audio, without interruption.");
player.setInternalPlayerState(AudioPlayerState.CONTINUE_PLAYING_EXISTING_FILE);
break;
case GAP:
log.warning(String.format("There is a gap between the audio segments, last "
+ "segment finished at %d, next segment starts at %d", newClipStartsAt,
previousClipEndsAt));
player.setInternalPlayerState(AudioPlayerState.GAP_BETWEEN_CONTENTS);
player.seekTo(audioSegment.getClipBegin());
player.play();
break;
case OVERLAPPING:
log.warning(String.format(
"The player was asked to play earlier in the file than expected."
+ " Generally the next request %d should be contiguous with the"
+ " end of the previous section %d", newClipStartsAt,
previousClipEndsAt));
player.setInternalPlayerState(AudioPlayerState.OVERLAPPING_CONTENTS);
player.seekTo(audioSegment.getClipBegin());
player.play();
break;
}
} else {
log.info(String.format(
"Stop playing the current file %s & start playing the newly specified file %s",
currentSegment.getAudioFilename(), audioSegment.getAudioFilename()));
player.setInternalPlayerState(AudioPlayerState.PLAY_NEW_FILE);
player.setCurrentSegment(audioSegment);
player.play();
log.warning("Why aren't you playing?");
}
currentSegment = audioSegment;
log.info(String.format("Playing %s from %d to %d", currentSegment.getAudioFilename(),
currentSegment.getClipBegin(), currentSegment.getClipEnd()));
}
}