Merge change 7064 into donut

* changes:
  Implementing utterance ID callbacks for silence and pre-recorded files (both generating and playing).
This commit is contained in:
Android (Google) Code Review
2009-07-14 09:18:46 -07:00

View File

@@ -69,8 +69,9 @@ public class TtsService extends Service implements OnCompletionListener {
mCallingApp = source; mCallingApp = source;
} }
public SpeechItem(String source, long silenceTime) { public SpeechItem(String source, long silenceTime, ArrayList<String> params) {
mDuration = silenceTime; mDuration = silenceTime;
mParams = params;
mType = SILENCE; mType = SILENCE;
mCallingApp = source; mCallingApp = source;
} }
@@ -125,6 +126,7 @@ public class TtsService extends Service implements OnCompletionListener {
private HashMap<String, SoundResource> mEarcons; private HashMap<String, SoundResource> mEarcons;
private HashMap<String, SoundResource> mUtterances; private HashMap<String, SoundResource> mUtterances;
private MediaPlayer mPlayer; private MediaPlayer mPlayer;
private SpeechItem mCurrentSpeechItem;
private TtsService mSelf; private TtsService mSelf;
private ContentResolver mResolver; private ContentResolver mResolver;
@@ -152,6 +154,7 @@ public class TtsService extends Service implements OnCompletionListener {
mSpeechQueue = new ArrayList<SpeechItem>(); mSpeechQueue = new ArrayList<SpeechItem>();
mPlayer = null; mPlayer = null;
mCurrentSpeechItem = null;
setDefaultSettings(); setDefaultSettings();
} }
@@ -401,6 +404,7 @@ public class TtsService extends Service implements OnCompletionListener {
} finally { } finally {
// This check is needed because finally will always run; even if the // This check is needed because finally will always run; even if the
// method returns somewhere in the try block. // method returns somewhere in the try block.
mCurrentSpeechItem = null;
if (speechQueueAvailable) { if (speechQueueAvailable) {
speechQueueLock.unlock(); speechQueueLock.unlock();
} }
@@ -409,6 +413,21 @@ public class TtsService extends Service implements OnCompletionListener {
} }
public void onCompletion(MediaPlayer arg0) { public void onCompletion(MediaPlayer arg0) {
String callingApp = mCurrentSpeechItem.mCallingApp;
ArrayList<String> params = mCurrentSpeechItem.mParams;
String utteranceId = "";
if (params != null){
for (int i = 0; i < params.size() - 1; i = i + 2){
String param = params.get(i);
if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){
utteranceId = params.get(i+1);
}
}
}
if (utteranceId.length() > 0){
dispatchUtteranceCompletedCallback(utteranceId, callingApp);
}
mCurrentSpeechItem = null;
processSpeechQueue(); processSpeechQueue();
} }
@@ -417,21 +436,37 @@ public class TtsService extends Service implements OnCompletionListener {
if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) { if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) {
stop(callingApp); stop(callingApp);
} }
mSpeechQueue.add(new SpeechItem(callingApp, duration)); mSpeechQueue.add(new SpeechItem(callingApp, duration, params));
if (!mIsSpeaking) { if (!mIsSpeaking) {
processSpeechQueue(); processSpeechQueue();
} }
return TextToSpeech.TTS_SUCCESS; return TextToSpeech.TTS_SUCCESS;
} }
private void silence(final long duration) { private void silence(final SpeechItem speechItem) {
class SilenceThread implements Runnable { class SilenceThread implements Runnable {
public void run() { public void run() {
long duration = speechItem.mDuration;
String callingApp = speechItem.mCallingApp;
ArrayList<String> params = speechItem.mParams;
String utteranceId = "";
if (params != null){
for (int i = 0; i < params.size() - 1; i = i + 2){
String param = params.get(i);
if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){
utteranceId = params.get(i+1);
}
}
}
try { try {
Thread.sleep(duration); Thread.sleep(duration);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
if (utteranceId.length() > 0){
dispatchUtteranceCompletedCallback(utteranceId, callingApp);
}
mCurrentSpeechItem = null;
processSpeechQueue(); processSpeechQueue();
} }
} }
@@ -503,6 +538,7 @@ public class TtsService extends Service implements OnCompletionListener {
if (utteranceId.length() > 0){ if (utteranceId.length() > 0){
dispatchUtteranceCompletedCallback(utteranceId, callingApp); dispatchUtteranceCompletedCallback(utteranceId, callingApp);
} }
mCurrentSpeechItem = null;
processSpeechQueue(); processSpeechQueue();
} }
} }
@@ -512,12 +548,16 @@ public class TtsService extends Service implements OnCompletionListener {
synth.start(); synth.start();
} }
private void synthToFileInternalOnly(final String text, private void synthToFileInternalOnly(final SpeechItem speechItem) {
final ArrayList<String> params, final String filename) {
class SynthThread implements Runnable { class SynthThread implements Runnable {
public void run() { public void run() {
Log.i("TTS", "Synthesizing to " + filename); String text = speechItem.mText;
ArrayList<String> params = speechItem.mParams;
String filename = speechItem.mFilename;
String callingApp = speechItem.mCallingApp;
boolean synthAvailable = false; boolean synthAvailable = false;
String utteranceId = "";
Log.i("TTS", "Synthesizing to " + filename);
try { try {
synthAvailable = synthesizerLock.tryLock(); synthAvailable = synthesizerLock.tryLock();
if (!synthAvailable) { if (!synthAvailable) {
@@ -542,6 +582,8 @@ public class TtsService extends Service implements OnCompletionListener {
country = params.get(i+1); country = params.get(i+1);
} else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){ } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){
variant = params.get(i+1); variant = params.get(i+1);
} else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){
utteranceId = params.get(i+1);
} }
} }
} }
@@ -560,6 +602,10 @@ public class TtsService extends Service implements OnCompletionListener {
if (synthAvailable) { if (synthAvailable) {
synthesizerLock.unlock(); synthesizerLock.unlock();
} }
if (utteranceId.length() > 0){
dispatchUtteranceCompletedCallback(utteranceId, callingApp);
}
mCurrentSpeechItem = null;
processSpeechQueue(); processSpeechQueue();
} }
} }
@@ -647,22 +693,21 @@ public class TtsService extends Service implements OnCompletionListener {
return; return;
} }
SpeechItem currentSpeechItem = mSpeechQueue.get(0); mCurrentSpeechItem = mSpeechQueue.get(0);
mIsSpeaking = true; mIsSpeaking = true;
SoundResource sr = getSoundResource(currentSpeechItem); SoundResource sr = getSoundResource(mCurrentSpeechItem);
// Synth speech as needed - synthesizer should call // Synth speech as needed - synthesizer should call
// processSpeechQueue to continue running the queue // processSpeechQueue to continue running the queue
Log.i("TTS processing: ", currentSpeechItem.mText); Log.i("TTS processing: ", mCurrentSpeechItem.mText);
if (sr == null) { if (sr == null) {
if (currentSpeechItem.mType == SpeechItem.TEXT) { if (mCurrentSpeechItem.mType == SpeechItem.TEXT) {
currentSpeechItem = splitCurrentTextIfNeeded(currentSpeechItem); mCurrentSpeechItem = splitCurrentTextIfNeeded(mCurrentSpeechItem);
speakInternalOnly(currentSpeechItem); speakInternalOnly(mCurrentSpeechItem);
} else if (currentSpeechItem.mType == SpeechItem.TEXT_TO_FILE) { } else if (mCurrentSpeechItem.mType == SpeechItem.TEXT_TO_FILE) {
synthToFileInternalOnly(currentSpeechItem.mText, synthToFileInternalOnly(mCurrentSpeechItem);
currentSpeechItem.mParams, currentSpeechItem.mFilename);
} else { } else {
// This is either silence or an earcon that was missing // This is either silence or an earcon that was missing
silence(currentSpeechItem.mDuration); silence(mCurrentSpeechItem);
} }
} else { } else {
cleanUpPlayer(); cleanUpPlayer();
@@ -696,7 +741,7 @@ public class TtsService extends Service implements OnCompletionListener {
} }
mPlayer.setOnCompletionListener(this); mPlayer.setOnCompletionListener(this);
try { try {
mPlayer.setAudioStreamType(getStreamTypeFromParams(currentSpeechItem.mParams)); mPlayer.setAudioStreamType(getStreamTypeFromParams(mCurrentSpeechItem.mParams));
mPlayer.start(); mPlayer.start();
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
mSpeechQueue.clear(); mSpeechQueue.clear();