/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package android.speech.tts;
import android.content.Context;
import android.media.AudioSystem;
import android.media.AudioTrack;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.ConditionVariable;
import android.speech.tts.TextToSpeechService.AudioOutputParams;
import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
import android.util.Log;
class AudioPlaybackQueueItem extends PlaybackQueueItem {
private static final String TAG = "TTS.AudioQueueItem";
private final Context mContext;
private final Uri mUri;
private final AudioOutputParams mAudioParams;
private final ConditionVariable mDone;
private MediaPlayer mPlayer;
private volatile boolean mFinished;
AudioPlaybackQueueItem(UtteranceProgressDispatcher dispatcher,
Object callerIdentity,
Context context, Uri uri, AudioOutputParams audioParams) {
super(dispatcher, callerIdentity);
mContext = context;
mUri = uri;
mAudioParams = audioParams;
mDone = new ConditionVariable();
mPlayer = null;
mFinished = false;
}
@Override
public void run() {
final UtteranceProgressDispatcher dispatcher = getDispatcher();
dispatcher.dispatchOnStart();
int sessionId = mAudioParams.mSessionId;
mPlayer = MediaPlayer.create(
mContext, mUri, null, mAudioParams.mAudioAttributes,
sessionId > 0 ? sessionId : AudioSystem.AUDIO_SESSION_ALLOCATE);
if (mPlayer == null) {
dispatcher.dispatchOnError(TextToSpeech.ERROR_OUTPUT);
return;
}
try {
mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.w(TAG, "Audio playback error: " + what + ", " + extra);
mDone.open();
return true;
}
});
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mFinished = true;
mDone.open();
}
});
setupVolume(mPlayer, mAudioParams.mVolume, mAudioParams.mPan);
mPlayer.start();
mDone.block();
finish();
} catch (IllegalArgumentException ex) {
Log.w(TAG, "MediaPlayer failed", ex);
mDone.open();
}
if (mFinished) {
dispatcher.dispatchOnSuccess();
} else {
dispatcher.dispatchOnStop();
}
}
private static void setupVolume(MediaPlayer player, float volume, float pan) {
final float vol = clip(volume, 0.0f, 1.0f);
final float panning = clip(pan, -1.0f, 1.0f);
float volLeft = vol, volRight = vol;
if (panning > 0.0f) {
volLeft *= (1.0f - panning);
} else if (panning < 0.0f) {
volRight *= (1.0f + panning);
}
player.setVolume(volLeft, volRight);
}
private static final float clip(float value, float min, float max) {
return value < min ? min : (value < max ? value : max);
}
private void finish() {
try {
mPlayer.stop();
} catch (IllegalStateException ex) {
// Do nothing, the player is already stopped
}
mPlayer.release();
}
@Override
void stop(int errorCode) {
mDone.open();
}
}
|