summaryrefslogtreecommitdiffstats
path: root/core/java/android/speech
diff options
context:
space:
mode:
authorPrzemyslaw Szczepaniak <pszczepaniak@google.com>2014-06-26 11:52:20 +0100
committerPrzemyslaw Szczepaniak <pszczepaniak@google.com>2014-06-30 11:25:12 +0100
commitfc4b2890378eb1b6e0b11d60d703eb6854268064 (patch)
tree181cd577565b415446beb75cbf7bf0c30ee0bf1c /core/java/android/speech
parent1422c5f6856a98464690a433da2c38205e70146e (diff)
downloadframeworks_base-fc4b2890378eb1b6e0b11d60d703eb6854268064.zip
frameworks_base-fc4b2890378eb1b6e0b11d60d703eb6854268064.tar.gz
frameworks_base-fc4b2890378eb1b6e0b11d60d703eb6854268064.tar.bz2
Remove TextToSpeechClient API.
Removed all of TTS V2 api with exception of error codes. Bug: 15834470 Change-Id: I9d9d2aad01811af9b86bf7a3fd018a8d4e5c2f33
Diffstat (limited to 'core/java/android/speech')
-rw-r--r--core/java/android/speech/tts/AbstractEventLogger.java2
-rw-r--r--core/java/android/speech/tts/AbstractSynthesisCallback.java2
-rw-r--r--core/java/android/speech/tts/AudioPlaybackHandler.java2
-rw-r--r--core/java/android/speech/tts/AudioPlaybackQueueItem.java2
-rw-r--r--core/java/android/speech/tts/EventLoggerV1.java2
-rw-r--r--core/java/android/speech/tts/EventLoggerV2.java73
-rw-r--r--core/java/android/speech/tts/FileSynthesisCallback.java41
-rw-r--r--core/java/android/speech/tts/ITextToSpeechCallback.aidl8
-rw-r--r--core/java/android/speech/tts/ITextToSpeechService.aidl43
-rw-r--r--core/java/android/speech/tts/PlaybackQueueItem.java4
-rw-r--r--core/java/android/speech/tts/PlaybackSynthesisCallback.java45
-rw-r--r--core/java/android/speech/tts/RequestConfig.java228
-rw-r--r--core/java/android/speech/tts/RequestConfigHelper.java187
-rw-r--r--core/java/android/speech/tts/SynthesisCallback.java55
-rw-r--r--core/java/android/speech/tts/SynthesisPlaybackQueueItem.java8
-rw-r--r--core/java/android/speech/tts/SynthesisRequestV2.aidl20
-rw-r--r--core/java/android/speech/tts/SynthesisRequestV2.java175
-rw-r--r--core/java/android/speech/tts/TextToSpeech.java44
-rw-r--r--core/java/android/speech/tts/TextToSpeechClient.java1192
-rw-r--r--core/java/android/speech/tts/TextToSpeechService.java547
-rw-r--r--core/java/android/speech/tts/UtteranceProgressListener.java16
-rw-r--r--core/java/android/speech/tts/VoiceInfo.aidl20
-rw-r--r--core/java/android/speech/tts/VoiceInfo.java340
23 files changed, 109 insertions, 2947 deletions
diff --git a/core/java/android/speech/tts/AbstractEventLogger.java b/core/java/android/speech/tts/AbstractEventLogger.java
index 37f8656..6d27d8c 100644
--- a/core/java/android/speech/tts/AbstractEventLogger.java
+++ b/core/java/android/speech/tts/AbstractEventLogger.java
@@ -104,7 +104,7 @@ abstract class AbstractEventLogger {
// onAudioDataWritten() should normally always be called, and hence mPlaybackStartTime
// should be set, if an error does not occur.
- if (statusCode != TextToSpeechClient.Status.SUCCESS
+ if (statusCode != TextToSpeech.SUCCESS
|| mPlaybackStartTime == -1 || mEngineCompleteTime == -1) {
logFailure(statusCode);
return;
diff --git a/core/java/android/speech/tts/AbstractSynthesisCallback.java b/core/java/android/speech/tts/AbstractSynthesisCallback.java
index 91e119b..67f7431 100644
--- a/core/java/android/speech/tts/AbstractSynthesisCallback.java
+++ b/core/java/android/speech/tts/AbstractSynthesisCallback.java
@@ -54,6 +54,6 @@ abstract class AbstractSynthesisCallback implements SynthesisCallback {
* while in {@link TextToSpeechService#onSynthesizeText}.
*/
int errorCodeOnStop() {
- return mClientIsUsingV2 ? TextToSpeechClient.Status.STOPPED : TextToSpeech.ERROR;
+ return mClientIsUsingV2 ? TextToSpeech.STOPPED : TextToSpeech.ERROR;
}
}
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index dcf49b0..1f1863c 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -43,7 +43,7 @@ class AudioPlaybackHandler {
return;
}
- item.stop(TextToSpeechClient.Status.STOPPED);
+ item.stop(TextToSpeech.STOPPED);
}
public void enqueue(PlaybackQueueItem item) {
diff --git a/core/java/android/speech/tts/AudioPlaybackQueueItem.java b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
index c514639..03e53ec 100644
--- a/core/java/android/speech/tts/AudioPlaybackQueueItem.java
+++ b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
@@ -53,7 +53,7 @@ class AudioPlaybackQueueItem extends PlaybackQueueItem {
dispatcher.dispatchOnStart();
mPlayer = MediaPlayer.create(mContext, mUri);
if (mPlayer == null) {
- dispatcher.dispatchOnError(TextToSpeechClient.Status.ERROR_OUTPUT);
+ dispatcher.dispatchOnError(TextToSpeech.ERROR_OUTPUT);
return;
}
diff --git a/core/java/android/speech/tts/EventLoggerV1.java b/core/java/android/speech/tts/EventLoggerV1.java
index f484347..2b02b43 100644
--- a/core/java/android/speech/tts/EventLoggerV1.java
+++ b/core/java/android/speech/tts/EventLoggerV1.java
@@ -35,7 +35,7 @@ class EventLoggerV1 extends AbstractEventLogger {
// We don't report stopped syntheses because their overall
// total time spent will be inaccurate (will not correlate with
// the length of the utterance).
- if (statusCode != TextToSpeechClient.Status.STOPPED) {
+ if (statusCode != TextToSpeech.STOPPED) {
EventLogTags.writeTtsSpeakFailure(mServiceApp, mCallerUid, mCallerPid,
getUtteranceLength(), getLocaleString(),
mRequest.getSpeechRate(), mRequest.getPitch());
diff --git a/core/java/android/speech/tts/EventLoggerV2.java b/core/java/android/speech/tts/EventLoggerV2.java
deleted file mode 100644
index b8e4dae..0000000
--- a/core/java/android/speech/tts/EventLoggerV2.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-
-
-/**
- * Writes data about a given speech synthesis request for V2 API to the event logs.
- * The data that is logged includes the calling app, length of the utterance,
- * synthesis request configuration and the latency and overall time taken.
- */
-class EventLoggerV2 extends AbstractEventLogger {
- private final SynthesisRequestV2 mRequest;
-
- EventLoggerV2(SynthesisRequestV2 request, int callerUid, int callerPid, String serviceApp) {
- super(callerUid, callerPid, serviceApp);
- mRequest = request;
- }
-
- @Override
- protected void logFailure(int statusCode) {
- // We don't report stopped syntheses because their overall
- // total time spent will be inaccurate (will not correlate with
- // the length of the utterance).
- if (statusCode != TextToSpeechClient.Status.STOPPED) {
- EventLogTags.writeTtsV2SpeakFailure(mServiceApp,
- mCallerUid, mCallerPid, getUtteranceLength(), getRequestConfigString(), statusCode);
- }
- }
-
- @Override
- protected void logSuccess(long audioLatency, long engineLatency, long engineTotal) {
- EventLogTags.writeTtsV2SpeakSuccess(mServiceApp,
- mCallerUid, mCallerPid, getUtteranceLength(), getRequestConfigString(),
- engineLatency, engineTotal, audioLatency);
- }
-
- /**
- * @return the length of the utterance for the given synthesis, 0
- * if the utterance was {@code null}.
- */
- private int getUtteranceLength() {
- final String utterance = mRequest.getText();
- return utterance == null ? 0 : utterance.length();
- }
-
- /**
- * Returns a string representation of the synthesis request configuration.
- */
- private String getRequestConfigString() {
- // Ensure the bundles are unparceled.
- mRequest.getVoiceParams().size();
- mRequest.getAudioParams().size();
-
- return new StringBuilder(64).append("VoiceName: ").append(mRequest.getVoiceName())
- .append(" ,VoiceParams: ").append(mRequest.getVoiceParams())
- .append(" ,SystemParams: ").append(mRequest.getAudioParams())
- .append("]").toString();
- }
-}
diff --git a/core/java/android/speech/tts/FileSynthesisCallback.java b/core/java/android/speech/tts/FileSynthesisCallback.java
index d84f7f0..a88eead 100644
--- a/core/java/android/speech/tts/FileSynthesisCallback.java
+++ b/core/java/android/speech/tts/FileSynthesisCallback.java
@@ -60,7 +60,7 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
mFileChannel = fileChannel;
mDispatcher = dispatcher;
mCallerIdentity = callerIdentity;
- mStatusCode = TextToSpeechClient.Status.SUCCESS;
+ mStatusCode = TextToSpeech.SUCCESS;
}
@Override
@@ -69,11 +69,11 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
if (mDone) {
return;
}
- if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ if (mStatusCode == TextToSpeech.STOPPED) {
return;
}
- mStatusCode = TextToSpeechClient.Status.STOPPED;
+ mStatusCode = TextToSpeech.STOPPED;
cleanUp();
if (mDispatcher != null) {
mDispatcher.dispatchOnStop();
@@ -109,11 +109,11 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
}
FileChannel fileChannel = null;
synchronized (mStateLock) {
- if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ if (mStatusCode == TextToSpeech.STOPPED) {
if (DBG) Log.d(TAG, "Request has been aborted.");
return errorCodeOnStop();
}
- if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+ if (mStatusCode != TextToSpeech.SUCCESS) {
if (DBG) Log.d(TAG, "Error was raised");
return TextToSpeech.ERROR;
}
@@ -139,7 +139,7 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
Log.e(TAG, "Failed to write wav header to output file descriptor", ex);
synchronized (mStateLock) {
cleanUp();
- mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+ mStatusCode = TextToSpeech.ERROR_OUTPUT;
}
return TextToSpeech.ERROR;
}
@@ -153,17 +153,17 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
}
FileChannel fileChannel = null;
synchronized (mStateLock) {
- if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ if (mStatusCode == TextToSpeech.STOPPED) {
if (DBG) Log.d(TAG, "Request has been aborted.");
return errorCodeOnStop();
}
- if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+ if (mStatusCode != TextToSpeech.SUCCESS) {
if (DBG) Log.d(TAG, "Error was raised");
return TextToSpeech.ERROR;
}
if (mFileChannel == null) {
Log.e(TAG, "File not open");
- mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+ mStatusCode = TextToSpeech.ERROR_OUTPUT;
return TextToSpeech.ERROR;
}
if (!mStarted) {
@@ -180,7 +180,7 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
Log.e(TAG, "Failed to write to output file descriptor", ex);
synchronized (mStateLock) {
cleanUp();
- mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+ mStatusCode = TextToSpeech.ERROR_OUTPUT;
}
return TextToSpeech.ERROR;
}
@@ -202,12 +202,12 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
// setStatusCode is set.
return TextToSpeech.ERROR;
}
- if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ if (mStatusCode == TextToSpeech.STOPPED) {
if (DBG) Log.d(TAG, "Request has been aborted.");
return errorCodeOnStop();
}
- if (mDispatcher != null && mStatusCode != TextToSpeechClient.Status.SUCCESS &&
- mStatusCode != TextToSpeechClient.Status.STOPPED) {
+ if (mDispatcher != null && mStatusCode != TextToSpeech.SUCCESS &&
+ mStatusCode != TextToSpeech.STOPPED) {
mDispatcher.dispatchOnError(mStatusCode);
return TextToSpeech.ERROR;
}
@@ -247,7 +247,7 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
@Override
public void error() {
- error(TextToSpeechClient.Status.ERROR_SYNTHESIS);
+ error(TextToSpeech.ERROR_SYNTHESIS);
}
@Override
@@ -304,17 +304,4 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
return header;
}
-
- @Override
- public int fallback() {
- synchronized (mStateLock) {
- if (hasStarted() || hasFinished()) {
- return TextToSpeech.ERROR;
- }
-
- mDispatcher.dispatchOnFallback();
- mStatusCode = TextToSpeechClient.Status.SUCCESS;
- return TextToSpeechClient.Status.SUCCESS;
- }
- }
}
diff --git a/core/java/android/speech/tts/ITextToSpeechCallback.aidl b/core/java/android/speech/tts/ITextToSpeechCallback.aidl
index 3c808ff..96f7e0e 100644
--- a/core/java/android/speech/tts/ITextToSpeechCallback.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechCallback.aidl
@@ -15,8 +15,6 @@
*/
package android.speech.tts;
-import android.speech.tts.VoiceInfo;
-
/**
* Interface for callbacks from TextToSpeechService
*
@@ -56,12 +54,8 @@ oneway interface ITextToSpeechCallback {
*
* @param utteranceId Unique id identifying synthesis request.
* @param errorCode One of the values from
- * {@link android.speech.tts.v2.TextToSpeechClient.Status}.
+ * {@link android.speech.tts.v2.TextToSpeech}.
*/
void onError(String utteranceId, int errorCode);
- /**
- * Inform the client that set of available voices changed.
- */
- void onVoicesInfoChange(in List<VoiceInfo> voices);
}
diff --git a/core/java/android/speech/tts/ITextToSpeechService.aidl b/core/java/android/speech/tts/ITextToSpeechService.aidl
index 9cf49ff..4d322df 100644
--- a/core/java/android/speech/tts/ITextToSpeechService.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechService.aidl
@@ -20,8 +20,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.speech.tts.ITextToSpeechCallback;
-import android.speech.tts.VoiceInfo;
-import android.speech.tts.SynthesisRequestV2;
/**
* Interface for TextToSpeech to talk to TextToSpeechService.
@@ -170,45 +168,4 @@ interface ITextToSpeechService {
* @param cb The callback.
*/
void setCallback(in IBinder caller, ITextToSpeechCallback cb);
-
- /**
- * Tells the engine to synthesize some speech and play it back.
- *
- * @param callingInstance a binder representing the identity of the calling
- * TextToSpeech object.
- * @param text The text to synthesize.
- * @param queueMode Determines what to do to requests already in the queue.
- * @param request Request parameters.
- */
- int speakV2(in IBinder callingInstance, in SynthesisRequestV2 request);
-
- /**
- * Tells the engine to synthesize some speech and write it to a file.
- *
- * @param callingInstance a binder representing the identity of the calling
- * TextToSpeech object.
- * @param text The text to synthesize.
- * @param fileDescriptor The file descriptor to write the synthesized audio to. Has to be
- writable.
- * @param request Request parameters.
- */
- int synthesizeToFileDescriptorV2(in IBinder callingInstance,
- in ParcelFileDescriptor fileDescriptor, in SynthesisRequestV2 request);
-
- /**
- * Plays an existing audio resource. V2 version
- *
- * @param callingInstance a binder representing the identity of the calling
- * TextToSpeech object.
- * @param audioUri URI for the audio resource (a file or android.resource URI)
- * @param utteranceId Unique identifier.
- * @param audioParameters Parameters for audio playback (from {@link SynthesisRequestV2}).
- */
- int playAudioV2(in IBinder callingInstance, in Uri audioUri, in String utteranceId,
- in Bundle audioParameters);
-
- /**
- * Request the list of available voices from the service.
- */
- List<VoiceInfo> getVoicesInfo();
}
diff --git a/core/java/android/speech/tts/PlaybackQueueItem.java b/core/java/android/speech/tts/PlaybackQueueItem.java
index b2e323e..0e54c33 100644
--- a/core/java/android/speech/tts/PlaybackQueueItem.java
+++ b/core/java/android/speech/tts/PlaybackQueueItem.java
@@ -29,8 +29,8 @@ abstract class PlaybackQueueItem implements Runnable {
* Stop the playback.
*
* @param errorCode Cause of the stop. Can be either one of the error codes from
- * {@link android.speech.tts.TextToSpeechClient.Status} or
- * {@link android.speech.tts.TextToSpeechClient.Status#STOPPED}
+ * {@link android.speech.tts.TextToSpeech} or
+ * {@link android.speech.tts.TextToSpeech#STOPPED}
* if stopped on a client request.
*/
abstract void stop(int errorCode);
diff --git a/core/java/android/speech/tts/PlaybackSynthesisCallback.java b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
index e345e89..7e68d27 100644
--- a/core/java/android/speech/tts/PlaybackSynthesisCallback.java
+++ b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
@@ -76,7 +76,7 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
mDispatcher = dispatcher;
mCallerIdentity = callerIdentity;
mLogger = logger;
- mStatusCode = TextToSpeechClient.Status.SUCCESS;
+ mStatusCode = TextToSpeech.SUCCESS;
}
@Override
@@ -88,13 +88,13 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
if (mDone) {
return;
}
- if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ if (mStatusCode == TextToSpeech.STOPPED) {
Log.w(TAG, "stop() called twice");
return;
}
item = mItem;
- mStatusCode = TextToSpeechClient.Status.STOPPED;
+ mStatusCode = TextToSpeech.STOPPED;
}
if (item != null) {
@@ -102,14 +102,14 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
// point it will write an additional buffer to the item - but we
// won't worry about that because the audio playback queue will be cleared
// soon after (see SynthHandler#stop(String).
- item.stop(TextToSpeechClient.Status.STOPPED);
+ item.stop(TextToSpeech.STOPPED);
} else {
// This happens when stop() or error() were called before start() was.
// In all other cases, mAudioTrackHandler.stop() will
// result in onSynthesisDone being called, and we will
// write data there.
- mLogger.onCompleted(TextToSpeechClient.Status.STOPPED);
+ mLogger.onCompleted(TextToSpeech.STOPPED);
mDispatcher.dispatchOnStop();
}
}
@@ -145,14 +145,14 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
synchronized (mStateLock) {
if (channelConfig == 0) {
Log.e(TAG, "Unsupported number of channels :" + channelCount);
- mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+ mStatusCode = TextToSpeech.ERROR_OUTPUT;
return TextToSpeech.ERROR;
}
- if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ if (mStatusCode == TextToSpeech.STOPPED) {
if (DBG) Log.d(TAG, "stop() called before start(), returning.");
return errorCodeOnStop();
}
- if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+ if (mStatusCode != TextToSpeech.SUCCESS) {
if (DBG) Log.d(TAG, "Error was raised");
return TextToSpeech.ERROR;
}
@@ -183,14 +183,14 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
SynthesisPlaybackQueueItem item = null;
synchronized (mStateLock) {
if (mItem == null) {
- mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+ mStatusCode = TextToSpeech.ERROR_OUTPUT;
return TextToSpeech.ERROR;
}
- if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+ if (mStatusCode != TextToSpeech.SUCCESS) {
if (DBG) Log.d(TAG, "Error was raised");
return TextToSpeech.ERROR;
}
- if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ if (mStatusCode == TextToSpeech.STOPPED) {
return errorCodeOnStop();
}
item = mItem;
@@ -206,7 +206,7 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
item.put(bufferCopy);
} catch (InterruptedException ie) {
synchronized (mStateLock) {
- mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+ mStatusCode = TextToSpeech.ERROR_OUTPUT;
return TextToSpeech.ERROR;
}
}
@@ -228,7 +228,7 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
// setStatusCode
return TextToSpeech.ERROR;
}
- if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ if (mStatusCode == TextToSpeech.STOPPED) {
if (DBG) Log.d(TAG, "Request has been aborted.");
return errorCodeOnStop();
}
@@ -238,7 +238,7 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
// .done() was called before .start. Treat it as successful synthesis
// for a client, despite service bad implementation.
Log.w(TAG, "done() was called before start() call");
- if (mStatusCode == TextToSpeechClient.Status.SUCCESS) {
+ if (mStatusCode == TextToSpeech.SUCCESS) {
mDispatcher.dispatchOnSuccess();
} else {
mDispatcher.dispatchOnError(mStatusCode);
@@ -252,7 +252,7 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
}
// Signal done or error to item
- if (statusCode == TextToSpeechClient.Status.SUCCESS) {
+ if (statusCode == TextToSpeech.SUCCESS) {
item.done();
} else {
item.stop(statusCode);
@@ -263,7 +263,7 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
@Override
public void error() {
- error(TextToSpeechClient.Status.ERROR_SYNTHESIS);
+ error(TextToSpeech.ERROR_SYNTHESIS);
}
@Override
@@ -276,17 +276,4 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
mStatusCode = errorCode;
}
}
-
- @Override
- public int fallback() {
- synchronized (mStateLock) {
- if (hasStarted() || hasFinished()) {
- return TextToSpeech.ERROR;
- }
-
- mDispatcher.dispatchOnFallback();
- mStatusCode = TextToSpeechClient.Status.SUCCESS;
- return TextToSpeechClient.Status.SUCCESS;
- }
- }
}
diff --git a/core/java/android/speech/tts/RequestConfig.java b/core/java/android/speech/tts/RequestConfig.java
deleted file mode 100644
index 84880c0..0000000
--- a/core/java/android/speech/tts/RequestConfig.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2014 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.media.AudioManager;
-import android.os.Bundle;
-
-/**
- * Synthesis request configuration.
- *
- * This class is immutable, and can only be constructed using
- * {@link RequestConfig.Builder}.
- */
-public final class RequestConfig {
-
- /** Builder for constructing RequestConfig objects. */
- public static final class Builder {
- private VoiceInfo mCurrentVoiceInfo;
- private Bundle mVoiceParams;
- private Bundle mAudioParams;
-
- Builder(VoiceInfo currentVoiceInfo, Bundle voiceParams, Bundle audioParams) {
- mCurrentVoiceInfo = currentVoiceInfo;
- mVoiceParams = voiceParams;
- mAudioParams = audioParams;
- }
-
- /**
- * Create new RequestConfig builder.
- */
- public static Builder newBuilder() {
- return new Builder(null, new Bundle(), new Bundle());
- }
-
- /**
- * Create new RequestConfig builder.
- * @param prototype
- * Prototype of new RequestConfig. Copies all fields of the
- * prototype to the constructed object.
- */
- public static Builder newBuilder(RequestConfig prototype) {
- return new Builder(prototype.mCurrentVoiceInfo,
- (Bundle)prototype.mVoiceParams.clone(),
- (Bundle)prototype.mAudioParams.clone());
- }
-
- /** Set voice for request. Will reset voice parameters to the defaults. */
- public Builder setVoice(VoiceInfo voice) {
- mCurrentVoiceInfo = voice;
- mVoiceParams = (Bundle)voice.getParamsWithDefaults().clone();
- return this;
- }
-
- /**
- * Set request voice parameter.
- *
- * @param paramName
- * The name of the parameter. It has to be one of the keys
- * from {@link VoiceInfo#getParamsWithDefaults()}
- * @param value
- * Value of the parameter. Its type can be one of: Integer, Float,
- * Boolean, String, VoiceInfo (will be set as a String, result of a call to
- * the {@link VoiceInfo#getName()}) or byte[]. It has to be of the same type
- * as the default value from {@link VoiceInfo#getParamsWithDefaults()}
- * for that parameter.
- * @throws IllegalArgumentException
- * If paramName is not a valid parameter name or its value is of a wrong
- * type.
- * @throws IllegalStateException
- * If no voice is set.
- */
- public Builder setVoiceParam(String paramName, Object value){
- if (mCurrentVoiceInfo == null) {
- throw new IllegalStateException(
- "Couldn't set voice parameter, no voice is set");
- }
- Object defaultValue = mCurrentVoiceInfo.getParamsWithDefaults().get(paramName);
- if (defaultValue == null) {
- throw new IllegalArgumentException(
- "Parameter \"" + paramName + "\" is not available in set voice with " +
- "name: " + mCurrentVoiceInfo.getName());
- }
-
- // If it's VoiceInfo, get its name
- if (value instanceof VoiceInfo) {
- value = ((VoiceInfo)value).getName();
- }
-
- // Check type information
- if (!defaultValue.getClass().equals(value.getClass())) {
- throw new IllegalArgumentException(
- "Parameter \"" + paramName +"\" is of different type. Value passed has " +
- "type " + value.getClass().getSimpleName() + " but should have " +
- "type " + defaultValue.getClass().getSimpleName());
- }
-
- setParam(mVoiceParams, paramName, value);
- return this;
- }
-
- /**
- * Set request audio parameter.
- *
- * Doesn't requires a set voice.
- *
- * @param paramName
- * Name of parameter.
- * @param value
- * Value of parameter. Its type can be one of: Integer, Float, Boolean, String
- * or byte[].
- */
- public Builder setAudioParam(String paramName, Object value) {
- setParam(mAudioParams, paramName, value);
- return this;
- }
-
- /**
- * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_STREAM} audio parameter.
- *
- * @param streamId One of the STREAM_ constants defined in {@link AudioManager}.
- */
- public void setAudioParamStream(int streamId) {
- setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_STREAM, streamId);
- }
-
- /**
- * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_VOLUME} audio parameter.
- *
- * @param volume Float in range of 0.0 to 1.0.
- */
- public void setAudioParamVolume(float volume) {
- setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_VOLUME, volume);
- }
-
- /**
- * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_PAN} audio parameter.
- *
- * @param pan Float in range of -1.0 to +1.0.
- */
- public void setAudioParamPan(float pan) {
- setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_PAN, pan);
- }
-
- private void setParam(Bundle bundle, String featureName, Object value) {
- if (value instanceof String) {
- bundle.putString(featureName, (String)value);
- } else if(value instanceof byte[]) {
- bundle.putByteArray(featureName, (byte[])value);
- } else if(value instanceof Integer) {
- bundle.putInt(featureName, (Integer)value);
- } else if(value instanceof Float) {
- bundle.putFloat(featureName, (Float)value);
- } else if(value instanceof Double) {
- bundle.putFloat(featureName, (Float)value);
- } else if(value instanceof Boolean) {
- bundle.putBoolean(featureName, (Boolean)value);
- } else {
- throw new IllegalArgumentException("Illegal type of object");
- }
- return;
- }
-
- /**
- * Build new RequestConfig instance.
- */
- public RequestConfig build() {
- RequestConfig config =
- new RequestConfig(mCurrentVoiceInfo, mVoiceParams, mAudioParams);
- return config;
- }
- }
-
- private RequestConfig(VoiceInfo voiceInfo, Bundle voiceParams, Bundle audioParams) {
- mCurrentVoiceInfo = voiceInfo;
- mVoiceParams = voiceParams;
- mAudioParams = audioParams;
- }
-
- /**
- * Currently set voice.
- */
- private final VoiceInfo mCurrentVoiceInfo;
-
- /**
- * Voice parameters bundle.
- */
- private final Bundle mVoiceParams;
-
- /**
- * Audio parameters bundle.
- */
- private final Bundle mAudioParams;
-
- /**
- * @return Currently set request voice.
- */
- public VoiceInfo getVoice() {
- return mCurrentVoiceInfo;
- }
-
- /**
- * @return Request audio parameters.
- */
- public Bundle getAudioParams() {
- return mAudioParams;
- }
-
- /**
- * @return Request voice parameters.
- */
- public Bundle getVoiceParams() {
- return mVoiceParams;
- }
-
-}
diff --git a/core/java/android/speech/tts/RequestConfigHelper.java b/core/java/android/speech/tts/RequestConfigHelper.java
deleted file mode 100644
index bc65280..0000000
--- a/core/java/android/speech/tts/RequestConfigHelper.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2014 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.speech.tts.TextToSpeechClient.EngineStatus;
-
-import java.util.Locale;
-
-/**
- * Set of common heuristics for selecting {@link VoiceInfo} from
- * {@link TextToSpeechClient#getEngineStatus()} output.
- */
-public final class RequestConfigHelper {
- private RequestConfigHelper() {}
-
- /**
- * Interface for scoring VoiceInfo object.
- */
- public static interface VoiceScorer {
- /**
- * Score VoiceInfo. If the score is less than or equal to zero, that voice is discarded.
- * If two voices have same desired primary characteristics (highest quality, lowest
- * latency or others), the one with the higher score is selected.
- */
- public int scoreVoice(VoiceInfo voiceInfo);
- }
-
- /**
- * Score positively voices that exactly match the locale supplied to the constructor.
- */
- public static final class ExactLocaleMatcher implements VoiceScorer {
- private final Locale mLocale;
-
- /**
- * Score positively voices that exactly match the given locale
- * @param locale Reference locale. If null, the system default locale for the
- * current user will be used ({@link Locale#getDefault()}).
- */
- public ExactLocaleMatcher(Locale locale) {
- if (locale == null) {
- mLocale = Locale.getDefault();
- } else {
- mLocale = locale;
- }
- }
- @Override
- public int scoreVoice(VoiceInfo voiceInfo) {
- return mLocale.equals(voiceInfo.getLocale()) ? 1 : 0;
- }
- }
-
- /**
- * Score positively voices that match exactly the given locale (score 3)
- * or that share same language and country (score 2), or that share just a language (score 1).
- */
- public static final class LanguageMatcher implements VoiceScorer {
- private final Locale mLocale;
-
- /**
- * Score positively voices with similar locale.
- * @param locale Reference locale. If null, the system default locale for the
- * current user will be used ({@link Locale#getDefault()}).
- */
- public LanguageMatcher(Locale locale) {
- if (locale == null) {
- mLocale = Locale.getDefault();
- } else {
- mLocale = locale;
- }
- }
-
- @Override
- public int scoreVoice(VoiceInfo voiceInfo) {
- final Locale voiceLocale = voiceInfo.getLocale();
- if (mLocale.equals(voiceLocale)) {
- return 3;
- } else {
- if (mLocale.getLanguage().equals(voiceLocale.getLanguage())) {
- if (mLocale.getCountry().equals(voiceLocale.getCountry())) {
- return 2;
- }
- return 1;
- }
- return 0;
- }
- }
- }
-
- /**
- * Get the highest quality voice from voices that score more than zero from the passed scorer.
- * If there is more than one voice with the same highest quality, then this method returns one
- * with the highest score. If they share same score as well, one with the lower index in the
- * voices list is returned.
- *
- * @param engineStatus
- * Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
- * @param voiceScorer
- * Used to discard unsuitable voices and help settle cases where more than
- * one voice has the desired characteristic.
- * @param hasToBeEmbedded
- * If true, require the voice to be an embedded voice (no network
- * access will be required for synthesis).
- */
- private static VoiceInfo getHighestQualityVoice(EngineStatus engineStatus,
- VoiceScorer voiceScorer, boolean hasToBeEmbedded) {
- VoiceInfo bestVoice = null;
- int bestScoreMatch = 1;
- int bestVoiceQuality = 0;
-
- for (VoiceInfo voice : engineStatus.getVoices()) {
- int score = voiceScorer.scoreVoice(voice);
- if (score <= 0 || hasToBeEmbedded && voice.getRequiresNetworkConnection()
- || voice.getQuality() < bestVoiceQuality) {
- continue;
- }
-
- if (bestVoice == null ||
- voice.getQuality() > bestVoiceQuality ||
- score > bestScoreMatch) {
- bestVoice = voice;
- bestScoreMatch = score;
- bestVoiceQuality = voice.getQuality();
- }
- }
- return bestVoice;
- }
-
- /**
- * Get highest quality voice.
- *
- * Highest quality voice is selected from voices that score more than zero from the passed
- * scorer. If there is more than one voice with the same highest quality, then this method
- * will return one with the highest score. If they share same score as well, one with the lower
- * index in the voices list is returned.
-
- * @param engineStatus
- * Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
- * @param hasToBeEmbedded
- * If true, require the voice to be an embedded voice (no network
- * access will be required for synthesis).
- * @param voiceScorer
- * Scorer is used to discard unsuitable voices and help settle cases where more than
- * one voice has highest quality.
- * @return RequestConfig with selected voice or null if suitable voice was not found.
- */
- public static RequestConfig highestQuality(EngineStatus engineStatus,
- boolean hasToBeEmbedded, VoiceScorer voiceScorer) {
- VoiceInfo voice = getHighestQualityVoice(engineStatus, voiceScorer, hasToBeEmbedded);
- if (voice == null) {
- return null;
- }
- return RequestConfig.Builder.newBuilder().setVoice(voice).build();
- }
-
- /**
- * Get highest quality voice for the TTS default locale.
- *
- * Call {@link #highestQuality(EngineStatus, boolean, VoiceScorer)} with
- * {@link LanguageMatcher} set to the {@link EngineStatus#getDefaultLocale()}.
- *
- * @param engineStatus
- * Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
- * @param hasToBeEmbedded
- * If true, require the voice to be an embedded voice (no network
- * access will be required for synthesis).
- * @return RequestConfig with selected voice or null if suitable voice was not found.
- */
- public static RequestConfig highestQuality(EngineStatus engineStatus,
- boolean hasToBeEmbedded) {
- return highestQuality(engineStatus, hasToBeEmbedded,
- new LanguageMatcher(engineStatus.getDefaultLocale()));
- }
-
-}
diff --git a/core/java/android/speech/tts/SynthesisCallback.java b/core/java/android/speech/tts/SynthesisCallback.java
index bc2f239..e32438b 100644
--- a/core/java/android/speech/tts/SynthesisCallback.java
+++ b/core/java/android/speech/tts/SynthesisCallback.java
@@ -43,16 +43,14 @@ public interface SynthesisCallback {
* request.
*
* This method should only be called on the synthesis thread,
- * while in {@link TextToSpeechService#onSynthesizeText} or
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * while in {@link TextToSpeechService#onSynthesizeText}.
*
* @param sampleRateInHz Sample rate in HZ of the generated audio.
* @param audioFormat Audio format of the generated audio. Must be one of
* the ENCODING_ constants defined in {@link android.media.AudioFormat}.
* @param channelCount The number of channels. Must be {@code 1} or {@code 2}.
- * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR}.
- * {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR} or
+ * {@link TextToSpeech#STOPPED}.
*/
public int start(int sampleRateInHz, int audioFormat, int channelCount);
@@ -60,17 +58,15 @@ public interface SynthesisCallback {
* The service should call this method when synthesized audio is ready for consumption.
*
* This method should only be called on the synthesis thread,
- * while in {@link TextToSpeechService#onSynthesizeText} or
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * while in {@link TextToSpeechService#onSynthesizeText}.
*
* @param buffer The generated audio data. This method will not hold on to {@code buffer},
* so the caller is free to modify it after this method returns.
* @param offset The offset into {@code buffer} where the audio data starts.
* @param length The number of bytes of audio data in {@code buffer}. This must be
* less than or equal to the return value of {@link #getMaxBufferSize}.
- * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
- * {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR} or
+ * {@link TextToSpeech#STOPPED}.
*/
public int audioAvailable(byte[] buffer, int offset, int length);
@@ -79,14 +75,12 @@ public interface SynthesisCallback {
* been passed to {@link #audioAvailable}.
*
* This method should only be called on the synthesis thread,
- * while in {@link TextToSpeechService#onSynthesizeText} or
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * while in {@link TextToSpeechService#onSynthesizeText}.
*
* This method has to be called if {@link #start} and/or {@link #error} was called.
*
- * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
- * {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR} or
+ * {@link TextToSpeech#STOPPED}.
*/
public int done();
@@ -103,40 +97,18 @@ public interface SynthesisCallback {
* The service should call this method if the speech synthesis fails.
*
* This method should only be called on the synthesis thread,
- * while in {@link TextToSpeechService#onSynthesizeText} or
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * while in {@link TextToSpeechService#onSynthesizeText}.
*
* @param errorCode Error code to pass to the client. One of the ERROR_ values from
- * {@link TextToSpeechClient.Status}
+ * {@link TextToSpeech}
*/
public void error(int errorCode);
/**
- * Communicate to client that the original request can't be done and client-requested
- * fallback is happening.
- *
- * Fallback can be requested by the client by setting
- * {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter with a id of
- * the voice that is expected to be used for the fallback.
- *
- * This method will fail if user called {@link #start(int, int, int)} and/or
- * {@link #done()}.
- *
- * This method should only be called on the synthesis thread,
- * while in {@link TextToSpeechService#onSynthesizeTextV2}.
- *
- * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR} if client already
- * called {@link #start(int, int, int)}, {@link TextToSpeechClient.Status#STOPPED}
- * if stop was requested.
- */
- public int fallback();
-
- /**
* Check if {@link #start} was called or not.
*
* This method should only be called on the synthesis thread,
- * while in {@link TextToSpeechService#onSynthesizeText} or
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * while in {@link TextToSpeechService#onSynthesizeText}.
*
* Useful for checking if a fallback from network request is possible.
*/
@@ -146,8 +118,7 @@ public interface SynthesisCallback {
* Check if {@link #done} was called or not.
*
* This method should only be called on the synthesis thread,
- * while in {@link TextToSpeechService#onSynthesizeText} or
- * {@link TextToSpeechService#onSynthesizeTextV2}.
+ * while in {@link TextToSpeechService#onSynthesizeText}.
*
* Useful for checking if a fallback from network request is possible.
*/
diff --git a/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java b/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
index b424356..104f486 100644
--- a/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
+++ b/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
@@ -72,7 +72,7 @@ final class SynthesisPlaybackQueueItem extends PlaybackQueueItem {
mStopped = false;
mDone = false;
- mStatusCode = TextToSpeechClient.Status.SUCCESS;
+ mStatusCode = TextToSpeech.SUCCESS;
mAudioTrack = new BlockingAudioTrack(streamType, sampleRate, audioFormat,
channelCount, volume, pan);
@@ -86,7 +86,7 @@ final class SynthesisPlaybackQueueItem extends PlaybackQueueItem {
dispatcher.dispatchOnStart();
if (!mAudioTrack.init()) {
- dispatcher.dispatchOnError(TextToSpeechClient.Status.ERROR_OUTPUT);
+ dispatcher.dispatchOnError(TextToSpeech.ERROR_OUTPUT);
return;
}
@@ -110,9 +110,9 @@ final class SynthesisPlaybackQueueItem extends PlaybackQueueItem {
mAudioTrack.waitAndRelease();
- if (mStatusCode == TextToSpeechClient.Status.SUCCESS) {
+ if (mStatusCode == TextToSpeech.SUCCESS) {
dispatcher.dispatchOnSuccess();
- } else if(mStatusCode == TextToSpeechClient.Status.STOPPED) {
+ } else if(mStatusCode == TextToSpeech.STOPPED) {
dispatcher.dispatchOnStop();
} else {
dispatcher.dispatchOnError(mStatusCode);
diff --git a/core/java/android/speech/tts/SynthesisRequestV2.aidl b/core/java/android/speech/tts/SynthesisRequestV2.aidl
deleted file mode 100644
index 2ac7da6..0000000
--- a/core/java/android/speech/tts/SynthesisRequestV2.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-**
-** Copyright 2013, 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;
-
-parcelable SynthesisRequestV2; \ No newline at end of file
diff --git a/core/java/android/speech/tts/SynthesisRequestV2.java b/core/java/android/speech/tts/SynthesisRequestV2.java
deleted file mode 100644
index 938458c..0000000
--- a/core/java/android/speech/tts/SynthesisRequestV2.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2014 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.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.speech.tts.TextToSpeechClient.UtteranceId;
-import android.util.Log;
-
-/**
- * Service-side representation of a synthesis request from a V2 API client. Contains:
- * <ul>
- * <li>The markup object to synthesize containing the utterance.</li>
- * <li>The id of the utterance (String, result of {@link UtteranceId#toUniqueString()}</li>
- * <li>The synthesis voice name (String, result of {@link VoiceInfo#getName()})</li>
- * <li>Voice parameters (Bundle of parameters)</li>
- * <li>Audio parameters (Bundle of parameters)</li>
- * </ul>
- */
-public final class SynthesisRequestV2 implements Parcelable {
-
- private static final String TAG = "SynthesisRequestV2";
-
- /** Synthesis markup */
- private final Markup mMarkup;
-
- /** Synthesis id. */
- private final String mUtteranceId;
-
- /** Voice ID. */
- private final String mVoiceName;
-
- /** Voice Parameters. */
- private final Bundle mVoiceParams;
-
- /** Audio Parameters. */
- private final Bundle mAudioParams;
-
- /**
- * Constructor for test purposes.
- */
- public SynthesisRequestV2(Markup markup, String utteranceId, String voiceName,
- Bundle voiceParams, Bundle audioParams) {
- this.mMarkup = markup;
- this.mUtteranceId = utteranceId;
- this.mVoiceName = voiceName;
- this.mVoiceParams = voiceParams;
- this.mAudioParams = audioParams;
- }
-
- /**
- * Parcel based constructor.
- *
- * @hide
- */
- public SynthesisRequestV2(Parcel in) {
- this.mMarkup = (Markup) in.readValue(Markup.class.getClassLoader());
- this.mUtteranceId = in.readString();
- this.mVoiceName = in.readString();
- this.mVoiceParams = in.readBundle();
- this.mAudioParams = in.readBundle();
- }
-
- /**
- * Constructor to request the synthesis of a sentence.
- */
- SynthesisRequestV2(Markup markup, String utteranceId, RequestConfig rconfig) {
- this.mMarkup = markup;
- this.mUtteranceId = utteranceId;
- this.mVoiceName = rconfig.getVoice().getName();
- this.mVoiceParams = rconfig.getVoiceParams();
- this.mAudioParams = rconfig.getAudioParams();
- }
-
- /**
- * Write to parcel.
- *
- * @hide
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeValue(mMarkup);
- dest.writeString(mUtteranceId);
- dest.writeString(mVoiceName);
- dest.writeBundle(mVoiceParams);
- dest.writeBundle(mAudioParams);
- }
-
- /**
- * @return the text which should be synthesized.
- */
- public String getText() {
- if (mMarkup.getPlainText() == null) {
- Log.e(TAG, "Plaintext of markup is null.");
- return "";
- }
- return mMarkup.getPlainText();
- }
-
- /**
- * @return the markup which should be synthesized.
- */
- public Markup getMarkup() {
- return mMarkup;
- }
-
- /**
- * @return the id of the synthesis request. It's an output of a call to the
- * {@link UtteranceId#toUniqueString()} method of the {@link UtteranceId} associated with
- * this request.
- */
- public String getUtteranceId() {
- return mUtteranceId;
- }
-
- /**
- * @return the name of the voice to use for this synthesis request. Result of a call to
- * the {@link VoiceInfo#getName()} method.
- */
- public String getVoiceName() {
- return mVoiceName;
- }
-
- /**
- * @return bundle of voice parameters.
- */
- public Bundle getVoiceParams() {
- return mVoiceParams;
- }
-
- /**
- * @return bundle of audio parameters.
- */
- public Bundle getAudioParams() {
- return mAudioParams;
- }
-
- /**
- * Parcel creators.
- *
- * @hide
- */
- public static final Parcelable.Creator<SynthesisRequestV2> CREATOR =
- new Parcelable.Creator<SynthesisRequestV2>() {
- @Override
- public SynthesisRequestV2 createFromParcel(Parcel source) {
- return new SynthesisRequestV2(source);
- }
-
- @Override
- public SynthesisRequestV2[] newArray(int size) {
- return new SynthesisRequestV2[size];
- }
- };
-
- /** @hide */
- @Override
- public int describeContents() {
- return 0;
- }
-}
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index c527acf..a338c19 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -53,10 +53,7 @@ import java.util.Set;
* notified of the completion of the initialization.<br>
* When you are done using the TextToSpeech instance, call the {@link #shutdown()} method
* to release the native resources used by the TextToSpeech engine.
- *
- * @deprecated Use {@link TextToSpeechClient} instead
*/
-@Deprecated
public class TextToSpeech {
private static final String TAG = "TextToSpeech";
@@ -71,6 +68,42 @@ public class TextToSpeech {
public static final int ERROR = -1;
/**
+ * Denotes a stop requested by a client. It's used only on the service side of the API,
+ * client should never expect to see this result code.
+ */
+ public static final int STOPPED = -2;
+
+ /**
+ * Denotes a failure of a TTS engine to synthesize the given input.
+ */
+ public static final int ERROR_SYNTHESIS = -3;
+
+ /**
+ * Denotes a failure of a TTS service.
+ */
+ public static final int ERROR_SERVICE = -4;
+
+ /**
+ * Denotes a failure related to the output (audio device or a file).
+ */
+ public static final int ERROR_OUTPUT = -5;
+
+ /**
+ * Denotes a failure caused by a network connectivity problems.
+ */
+ public static final int ERROR_NETWORK = -6;
+
+ /**
+ * Denotes a failure caused by network timeout.
+ */
+ public static final int ERROR_NETWORK_TIMEOUT = -7;
+
+ /**
+ * Denotes a failure caused by an invalid request.
+ */
+ public static final int ERROR_INVALID_REQUEST = -8;
+
+ /**
* Queue mode where all entries in the playback queue (media to be played
* and text to be synthesized) are dropped and replaced by the new entry.
* Queues are flushed with respect to a given calling app. Entries in the queue
@@ -1478,11 +1511,6 @@ public class TextToSpeech {
listener.onStart(utteranceId);
}
}
-
- @Override
- public void onVoicesInfoChange(List<VoiceInfo> voicesInfo) throws RemoteException {
- // Ignore it
- }
};
private class SetupConnectionAsyncTask extends AsyncTask<Void, Void, Integer> {
diff --git a/core/java/android/speech/tts/TextToSpeechClient.java b/core/java/android/speech/tts/TextToSpeechClient.java
deleted file mode 100644
index f726743..0000000
--- a/core/java/android/speech/tts/TextToSpeechClient.java
+++ /dev/null
@@ -1,1192 +0,0 @@
-/*
- * Copyright (C) 2013 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.app.Activity;
-import android.app.Application;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.speech.tts.ITextToSpeechCallback;
-import android.speech.tts.ITextToSpeechService;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Synthesizes speech from text for immediate playback or to create a sound
- * file.
- * <p>
- * This is an updated version of the speech synthesis client that supersedes
- * {@link android.speech.tts.TextToSpeech}.
- * <p>
- * A TextToSpeechClient instance can only be used to synthesize text once it has
- * connected to the service. The TextToSpeechClient instance will start establishing
- * the connection after a call to the {@link #connect()} method. This is usually done in
- * {@link Application#onCreate()} or {@link Activity#onCreate}. When the connection
- * is established, the instance will call back using the
- * {@link TextToSpeechClient.ConnectionCallbacks} interface. Only after a
- * successful callback is the client usable.
- * <p>
- * After successful connection, the list of all available voices can be obtained
- * by calling the {@link TextToSpeechClient#getEngineStatus()} method. The client can
- * choose a voice using some custom heuristic and build a {@link RequestConfig} object
- * using {@link RequestConfig.Builder}, or can use one of the common heuristics found
- * in ({@link RequestConfigHelper}.
- * <p>
- * When you are done using the TextToSpeechClient instance, call the
- * {@link #disconnect()} method to release the connection.
- * <p>
- * In the rare case of a change to the set of available voices, the service will call to the
- * {@link ConnectionCallbacks#onEngineStatusChange} with new set of available voices as argument.
- * In response, the client HAVE to recreate all {@link RequestConfig} instances in use.
- */
-public class TextToSpeechClient {
- private static final String TAG = TextToSpeechClient.class.getSimpleName();
-
- private final Object mLock = new Object();
- private final TtsEngines mEnginesHelper;
- private final Context mContext;
-
- // Guarded by mLock
- private Connection mServiceConnection;
- private final RequestCallbacks mDefaultRequestCallbacks;
- private final ConnectionCallbacks mConnectionCallbacks;
- private EngineStatus mEngineStatus;
- private String mRequestedEngine;
- private boolean mFallbackToDefault;
- private HashMap<String, Pair<UtteranceId, RequestCallbacks>> mCallbacks;
- // Guarded by mLock
-
- private InternalHandler mMainHandler = new InternalHandler();
-
- /** Common voices parameters */
- public static final class Params {
- private Params() {}
-
- /**
- * Maximum allowed time for a single request attempt, in milliseconds, before synthesis
- * fails (or fallback request starts, if requested using
- * {@link #FALLBACK_VOICE_NAME}).
- */
- public static final String NETWORK_TIMEOUT_MS = "networkTimeoutMs";
-
- /**
- * Number of network request retries that are attempted in case of failure
- */
- public static final String NETWORK_RETRIES_COUNT = "networkRetriesCount";
-
- /**
- * Should synthesizer report sub-utterance progress on synthesis. Only applicable
- * for the {@link TextToSpeechClient#queueSpeak} method.
- */
- public static final String TRACK_SUBUTTERANCE_PROGRESS = "trackSubutteranceProgress";
-
- /**
- * If a voice exposes this parameter then it supports the fallback request feature.
- *
- * If it is set to a valid name of some other voice ({@link VoiceInfo#getName()}) then
- * in case of request failure (due to network problems or missing data), fallback request
- * will be attempted. Request will be done using the voice referenced by this parameter.
- * If it is the case, the client will be informed by a callback to the {@link
- * RequestCallbacks#onSynthesisFallback(UtteranceId)}.
- */
- public static final String FALLBACK_VOICE_NAME = "fallbackVoiceName";
-
- /**
- * Audio parameter for specifying a linear multiplier to the speaking speed of the voice.
- * The value is a float. Values below zero decrease speed of the synthesized speech
- * values above one increase it. If the value of this parameter is equal to zero,
- * then it will be replaced by a settings-configurable default before it reaches
- * TTS service.
- */
- public static final String SPEECH_SPEED = "speechSpeed";
-
- /**
- * Audio parameter for controlling the pitch of the output. The Value is a positive float,
- * with default of {@code 1.0}. The value is used to scale the primary frequency linearly.
- * Lower values lower the tone of the synthesized voice, greater values increase it.
- */
- public static final String SPEECH_PITCH = "speechPitch";
-
- /**
- * Audio parameter for controlling output volume. Value is a float with scale of 0 to 1
- */
- public static final String AUDIO_PARAM_VOLUME = TextToSpeech.Engine.KEY_PARAM_VOLUME;
-
- /**
- * Audio parameter for controlling output pan.
- * Value is a float ranging from -1 to +1 where -1 maps to a hard-left pan,
- * 0 to center (the default behavior), and +1 to hard-right.
- */
- public static final String AUDIO_PARAM_PAN = TextToSpeech.Engine.KEY_PARAM_PAN;
-
- /**
- * Audio parameter for specifying the audio stream type to be used when speaking text
- * or playing back a file. The value should be one of the STREAM_ constants
- * defined in {@link AudioManager}.
- */
- public static final String AUDIO_PARAM_STREAM = TextToSpeech.Engine.KEY_PARAM_STREAM;
- }
-
- /**
- * Result codes for TTS operations.
- */
- public static final class Status {
- private Status() {}
-
- /**
- * Denotes a successful operation.
- */
- public static final int SUCCESS = 0;
-
- /**
- * Denotes a stop requested by a client. It's used only on the service side of the API,
- * client should never expect to see this result code.
- */
- public static final int STOPPED = 100;
-
- /**
- * Denotes a generic failure.
- */
- public static final int ERROR_UNKNOWN = -1;
-
- /**
- * Denotes a failure of a TTS engine to synthesize the given input.
- */
- public static final int ERROR_SYNTHESIS = 10;
-
- /**
- * Denotes a failure of a TTS service.
- */
- public static final int ERROR_SERVICE = 11;
-
- /**
- * Denotes a failure related to the output (audio device or a file).
- */
- public static final int ERROR_OUTPUT = 12;
-
- /**
- * Denotes a failure caused by a network connectivity problems.
- */
- public static final int ERROR_NETWORK = 13;
-
- /**
- * Denotes a failure caused by network timeout.
- */
- public static final int ERROR_NETWORK_TIMEOUT = 14;
-
- /**
- * Denotes a failure caused by an invalid request.
- */
- public static final int ERROR_INVALID_REQUEST = 15;
-
- /**
- * Denotes a failure related to passing a non-unique utterance id.
- */
- public static final int ERROR_NON_UNIQUE_UTTERANCE_ID = 16;
-
- /**
- * Denotes a failure related to missing data. The TTS implementation may download
- * the missing data, and if so, request will succeed in future. This error can only happen
- * for voices with {@link VoiceInfo#FEATURE_MAY_AUTOINSTALL} feature.
- * Note: the recommended way to avoid this error is to create a request with the fallback
- * voice.
- */
- public static final int ERROR_DOWNLOADING_ADDITIONAL_DATA = 17;
- }
-
- /**
- * Set of callbacks for the events related to the progress of a synthesis request
- * through the synthesis queue. Each synthesis request is associated with a call to
- * {@link #queueSpeak} or {@link #queueSynthesizeToFile}.
- *
- * The callbacks specified in this method will NOT be called on UI thread.
- */
- public static abstract class RequestCallbacks {
- /**
- * Called after synthesis of utterance successfully starts.
- */
- public void onSynthesisStart(UtteranceId utteranceId) {}
-
- /**
- * Called after synthesis successfully finishes.
- * @param utteranceId
- * Unique identifier of synthesized utterance.
- */
- public void onSynthesisSuccess(UtteranceId utteranceId) {}
-
- /**
- * Called after synthesis was stopped in middle of synthesis process.
- * @param utteranceId
- * Unique identifier of synthesized utterance.
- */
- public void onSynthesisStop(UtteranceId utteranceId) {}
-
- /**
- * Called when requested synthesis failed and fallback synthesis is about to be attempted.
- *
- * Requires voice with available {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME}
- * parameter, and request with this parameter enabled.
- *
- * This callback will be followed by callback to the {@link #onSynthesisStart},
- * {@link #onSynthesisFailure} or {@link #onSynthesisSuccess} that depends on the
- * fallback outcome.
- *
- * For more fallback feature reference, look at the
- * {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME}.
- *
- * @param utteranceId
- * Unique identifier of synthesized utterance.
- */
- public void onSynthesisFallback(UtteranceId utteranceId) {}
-
- /**
- * Called after synthesis of utterance fails.
- *
- * It may be called instead or after a {@link #onSynthesisStart} callback.
- *
- * @param utteranceId
- * Unique identifier of synthesized utterance.
- * @param errorCode
- * One of the values from {@link Status}.
- */
- public void onSynthesisFailure(UtteranceId utteranceId, int errorCode) {}
-
- /**
- * Called during synthesis to mark synthesis progress.
- *
- * Requires voice with available
- * {@link TextToSpeechClient.Params#TRACK_SUBUTTERANCE_PROGRESS} parameter, and
- * request with this parameter enabled.
- *
- * @param utteranceId
- * Unique identifier of synthesized utterance.
- * @param charIndex
- * String index (java char offset) of recently synthesized character.
- * @param msFromStart
- * Miliseconds from the start of the synthesis.
- */
- public void onSynthesisProgress(UtteranceId utteranceId, int charIndex,
- int msFromStart) {}
- }
-
- /**
- * Interface definition of callbacks that are called when the client is
- * connected or disconnected from the TTS service.
- *
- * The callbacks specified in this method will be called on the UI thread.
- */
- public static interface ConnectionCallbacks {
- /**
- * After calling {@link TextToSpeechClient#connect()}, this method will be invoked
- * asynchronously when the connect request has successfully completed.
- *
- * Clients are strongly encouraged to call {@link TextToSpeechClient#getEngineStatus()}
- * and create {@link RequestConfig} objects used in subsequent synthesis requests.
- */
- public void onConnectionSuccess();
-
- /**
- * After calling {@link TextToSpeechClient#connect()}, this method may be invoked
- * asynchronously when the connect request has failed to complete.
- *
- * It may be also invoked synchronously, from the body of
- * {@link TextToSpeechClient#connect()} method.
- */
- public void onConnectionFailure();
-
- /**
- * Called when the connection to the service is lost. This can happen if there is a problem
- * with the speech service (e.g. a crash or resource problem causes it to be killed by the
- * system). When called, all requests have been canceled and no outstanding listeners will
- * be executed. Applications should disable UI components that require the service.
- *
- * When the service is working again, the client will receive a callback to the
- * {@link #onConnectionSuccess()} method.
- */
- public void onServiceDisconnected();
-
- /**
- * After receiving {@link #onConnectionSuccess()} callback, this method may be invoked
- * if engine status obtained from {@link TextToSpeechClient#getEngineStatus()}) changes.
- * It usually means that some voices were removed, changed or added.
- *
- * Clients are required to recreate {@link RequestConfig} objects used in subsequent
- * synthesis requests.
- */
- public void onEngineStatusChange(EngineStatus newEngineStatus);
- }
-
- /** State of voices as provided by engine and user. */
- public static final class EngineStatus {
- /** All available voices. */
- private final List<VoiceInfo> mVoices;
-
- /** Name of the TTS engine package */
- private final String mPackageName;
-
- /** Engine default locale */
- private final Locale mDefaultLocale;
-
- private EngineStatus(String packageName, List<VoiceInfo> voices, Locale defaultLocale) {
- this.mVoices = Collections.unmodifiableList(voices);
- this.mPackageName = packageName;
- this.mDefaultLocale = defaultLocale;
- }
-
- /**
- * Get an immutable list of all Voices exposed by the TTS engine.
- */
- public List<VoiceInfo> getVoices() {
- return mVoices;
- }
-
- /**
- * Get name of the TTS engine package currently in use.
- */
- public String getEnginePackage() {
- return mPackageName;
- }
-
- /**
- * Get the default locale to use for TTS with this TTS engine.
- * Unless the user changed the TTS settings for this engine, the value returned should be
- * the same as the system default locale for the current user
- * ({@link Locale#getDefault()}).
- */
- public Locale getDefaultLocale() {
- return mDefaultLocale;
- }
- }
-
- /** Unique synthesis request identifier. */
- public static class UtteranceId {
- /** Unique identifier */
- private final int id;
-
- /** Unique identifier generator */
- private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
-
- /**
- * Create new, unique UtteranceId instance.
- */
- public UtteranceId() {
- id = ID_GENERATOR.getAndIncrement();
- }
-
- /**
- * Returns a unique string associated with an instance of this object.
- *
- * This string will be used to identify the synthesis request/utterance inside the
- * TTS service.
- */
- public final String toUniqueString() {
- return "UID" + id;
- }
- }
-
- /**
- * Create TextToSpeech service client.
- *
- * Will connect to the default TTS service. In order to be usable, {@link #connect()} need
- * to be called first and successful connection callback need to be received.
- *
- * @param context
- * The context this instance is running in.
- * @param engine
- * Package name of requested TTS engine. If it's null, then default engine will
- * be selected regardless of {@code fallbackToDefaultEngine} parameter value.
- * @param fallbackToDefaultEngine
- * If requested engine is not available, should we fallback to the default engine?
- * @param defaultRequestCallbacks
- * Default request callbacks, it will be used for all synthesis requests without
- * supplied RequestCallbacks instance. Can't be null.
- * @param connectionCallbacks
- * Callbacks for connecting and disconnecting from the service. Can't be null.
- */
- public TextToSpeechClient(Context context,
- String engine, boolean fallbackToDefaultEngine,
- RequestCallbacks defaultRequestCallbacks,
- ConnectionCallbacks connectionCallbacks) {
- if (context == null)
- throw new IllegalArgumentException("context can't be null");
- if (defaultRequestCallbacks == null)
- throw new IllegalArgumentException("defaultRequestCallbacks can't be null");
- if (connectionCallbacks == null)
- throw new IllegalArgumentException("connectionCallbacks can't be null");
- mContext = context;
- mEnginesHelper = new TtsEngines(mContext);
- mCallbacks = new HashMap<String, Pair<UtteranceId, RequestCallbacks>>();
- mDefaultRequestCallbacks = defaultRequestCallbacks;
- mConnectionCallbacks = connectionCallbacks;
-
- mRequestedEngine = engine;
- mFallbackToDefault = fallbackToDefaultEngine;
- }
-
- /**
- * Create TextToSpeech service client. Will connect to the default TTS
- * service. In order to be usable, {@link #connect()} need to be called
- * first and successful connection callback need to be received.
- *
- * @param context Context this instance is running in.
- * @param defaultRequestCallbacks Default request callbacks, it
- * will be used for all synthesis requests without supplied
- * RequestCallbacks instance. Can't be null.
- * @param connectionCallbacks Callbacks for connecting and disconnecting
- * from the service. Can't be null.
- */
- public TextToSpeechClient(Context context, RequestCallbacks defaultRequestCallbacks,
- ConnectionCallbacks connectionCallbacks) {
- this(context, null, true, defaultRequestCallbacks, connectionCallbacks);
- }
-
-
- private boolean initTts(String requestedEngine, boolean fallbackToDefaultEngine) {
- // Step 1: Try connecting to the engine that was requested.
- if (requestedEngine != null) {
- if (mEnginesHelper.isEngineInstalled(requestedEngine)) {
- if ((mServiceConnection = connectToEngine(requestedEngine)) != null) {
- return true;
- } else if (!fallbackToDefaultEngine) {
- Log.w(TAG, "Couldn't connect to requested engine: " + requestedEngine);
- return false;
- }
- } else if (!fallbackToDefaultEngine) {
- Log.w(TAG, "Requested engine not installed: " + requestedEngine);
- return false;
- }
- }
-
- // Step 2: Try connecting to the user's default engine.
- final String defaultEngine = mEnginesHelper.getDefaultEngine();
- if (defaultEngine != null && !defaultEngine.equals(requestedEngine)) {
- if ((mServiceConnection = connectToEngine(defaultEngine)) != null) {
- return true;
- }
- }
-
- // Step 3: Try connecting to the highest ranked engine in the
- // system.
- final String highestRanked = mEnginesHelper.getHighestRankedEngineName();
- if (highestRanked != null && !highestRanked.equals(requestedEngine) &&
- !highestRanked.equals(defaultEngine)) {
- if ((mServiceConnection = connectToEngine(highestRanked)) != null) {
- return true;
- }
- }
-
- Log.w(TAG, "Couldn't find working TTS engine");
- return false;
- }
-
- private Connection connectToEngine(String engine) {
- Connection connection = new Connection(engine);
- Intent intent = new Intent(TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE);
- intent.setPackage(engine);
- boolean bound = mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
- if (!bound) {
- Log.e(TAG, "Failed to bind to " + engine);
- return null;
- } else {
- Log.i(TAG, "Successfully bound to " + engine);
- return connection;
- }
- }
-
- /**
- * Connects the client to TTS service. This method returns immediately, and connects to the
- * service in the background.
- *
- * After connection initializes successfully, {@link ConnectionCallbacks#onConnectionSuccess()}
- * is called. On a failure {@link ConnectionCallbacks#onConnectionFailure} is called.
- *
- * Both of those callback may be called asynchronously on the main thread,
- * {@link ConnectionCallbacks#onConnectionFailure} may be called synchronously, before
- * this method returns.
- */
- public void connect() {
- synchronized (mLock) {
- if (mServiceConnection != null) {
- return;
- }
- if(!initTts(mRequestedEngine, mFallbackToDefault)) {
- mConnectionCallbacks.onConnectionFailure();
- }
- }
- }
-
- /**
- * Checks if the client is currently connected to the service, so that
- * requests to other methods will succeed.
- */
- public boolean isConnected() {
- synchronized (mLock) {
- return mServiceConnection != null && mServiceConnection.isEstablished();
- }
- }
-
- /**
- * Closes the connection to TextToSpeech service. No calls can be made on this object after
- * calling this method.
- * It is good practice to call this method in the onDestroy() method of an Activity
- * so the TextToSpeech engine can be cleanly stopped.
- */
- public void disconnect() {
- synchronized (mLock) {
- if (mServiceConnection != null) {
- mServiceConnection.disconnect();
- mServiceConnection = null;
- mCallbacks.clear();
- }
- }
- }
-
- /**
- * Register callback.
- *
- * @param utteranceId Non-null UtteranceId instance.
- * @param callback Non-null callbacks for the request
- * @return Status.SUCCESS or error code in case of invalid arguments.
- */
- private int addCallback(UtteranceId utteranceId, RequestCallbacks callback) {
- synchronized (mLock) {
- if (utteranceId == null || callback == null) {
- return Status.ERROR_INVALID_REQUEST;
- }
- if (mCallbacks.put(utteranceId.toUniqueString(),
- new Pair<UtteranceId, RequestCallbacks>(utteranceId, callback)) != null) {
- return Status.ERROR_NON_UNIQUE_UTTERANCE_ID;
- }
- return Status.SUCCESS;
- }
- }
-
- /**
- * Remove and return callback.
- *
- * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
- */
- private Pair<UtteranceId, RequestCallbacks> removeCallback(String utteranceIdStr) {
- synchronized (mLock) {
- return mCallbacks.remove(utteranceIdStr);
- }
- }
-
- /**
- * Get callback and utterance id.
- *
- * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
- */
- private Pair<UtteranceId, RequestCallbacks> getCallback(String utteranceIdStr) {
- synchronized (mLock) {
- return mCallbacks.get(utteranceIdStr);
- }
- }
-
- /**
- * Remove callback and call {@link RequestCallbacks#onSynthesisFailure} with passed
- * error code.
- *
- * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
- * @param errorCode argument to {@link RequestCallbacks#onSynthesisFailure} call.
- */
- private void removeCallbackAndErr(String utteranceIdStr, int errorCode) {
- synchronized (mLock) {
- Pair<UtteranceId, RequestCallbacks> c = mCallbacks.remove(utteranceIdStr);
- c.second.onSynthesisFailure(c.first, errorCode);
- }
- }
-
- /**
- * Retrieve TTS engine status {@link EngineStatus}. Requires connected client.
- */
- public EngineStatus getEngineStatus() {
- synchronized (mLock) {
- return mEngineStatus;
- }
- }
-
- /**
- * Query TTS engine about available voices and defaults.
- *
- * @return EngineStatus is connected or null if client is disconnected.
- */
- private EngineStatus requestEngineStatus(ITextToSpeechService service)
- throws RemoteException {
- List<VoiceInfo> voices = service.getVoicesInfo();
- if (voices == null) {
- Log.e(TAG, "Requested engine doesn't support TTS V2 API");
- return null;
- }
-
- return new EngineStatus(mServiceConnection.getEngineName(), voices,
- mEnginesHelper.getLocalePrefForEngine(
- mServiceConnection.getEngineName()));
- }
-
- private class Connection implements ServiceConnection {
- private final String mEngineName;
-
- private ITextToSpeechService mService;
-
- private boolean mEstablished;
-
- private PrepareConnectionAsyncTask mSetupConnectionAsyncTask;
-
- public Connection(String engineName) {
- this.mEngineName = engineName;
- }
-
- private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
-
- @Override
- public void onStart(String utteranceIdStr) {
- synchronized (mLock) {
- Pair<UtteranceId, RequestCallbacks> callbacks = getCallback(utteranceIdStr);
- callbacks.second.onSynthesisStart(callbacks.first);
- }
- }
-
- public void onStop(String utteranceIdStr) {
- synchronized (mLock) {
- Pair<UtteranceId, RequestCallbacks> callbacks = removeCallback(utteranceIdStr);
- callbacks.second.onSynthesisStop(callbacks.first);
- }
- }
-
- @Override
- public void onSuccess(String utteranceIdStr) {
- synchronized (mLock) {
- Pair<UtteranceId, RequestCallbacks> callbacks = removeCallback(utteranceIdStr);
- callbacks.second.onSynthesisSuccess(callbacks.first);
- }
- }
-
- public void onFallback(String utteranceIdStr) {
- synchronized (mLock) {
- Pair<UtteranceId, RequestCallbacks> callbacks = getCallback(
- utteranceIdStr);
- callbacks.second.onSynthesisFallback(callbacks.first);
- }
- };
-
- @Override
- public void onError(String utteranceIdStr, int errorCode) {
- removeCallbackAndErr(utteranceIdStr, errorCode);
- }
-
- @Override
- public void onVoicesInfoChange(List<VoiceInfo> voicesInfo) {
- synchronized (mLock) {
- mEngineStatus = new EngineStatus(mServiceConnection.getEngineName(),
- voicesInfo,
- mEnginesHelper.getLocalePrefForEngine(
- mServiceConnection.getEngineName()));
- mMainHandler.obtainMessage(InternalHandler.WHAT_ENGINE_STATUS_CHANGED,
- mEngineStatus).sendToTarget();
- }
- }
- };
-
- private class PrepareConnectionAsyncTask extends AsyncTask<Void, Void, EngineStatus> {
-
- private final ComponentName mName;
-
- public PrepareConnectionAsyncTask(ComponentName name) {
- mName = name;
- }
-
- @Override
- protected EngineStatus doInBackground(Void... params) {
- synchronized(mLock) {
- if (isCancelled()) {
- return null;
- }
- try {
- mService.setCallback(getCallerIdentity(), mCallback);
- return requestEngineStatus(mService);
- } catch (RemoteException re) {
- Log.e(TAG, "Error setting up the TTS service");
- return null;
- }
- }
- }
-
- @Override
- protected void onPostExecute(EngineStatus result) {
- synchronized(mLock) {
- if (mSetupConnectionAsyncTask == this) {
- mSetupConnectionAsyncTask = null;
- }
- if (result == null) {
- Log.e(TAG, "Setup task failed");
- disconnect();
- mConnectionCallbacks.onConnectionFailure();
- return;
- }
-
- mEngineStatus = result;
- mEstablished = true;
- }
- mConnectionCallbacks.onConnectionSuccess();
- }
- }
-
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Log.i(TAG, "Connected to " + name);
-
- synchronized(mLock) {
- mEstablished = false;
- mService = ITextToSpeechService.Stub.asInterface(service);
- startSetupConnectionTask(name);
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Log.i(TAG, "Asked to disconnect from " + name);
-
- synchronized(mLock) {
- mEstablished = false;
- mService = null;
- stopSetupConnectionTask();
- }
- mMainHandler.obtainMessage(InternalHandler.WHAT_SERVICE_DISCONNECTED).sendToTarget();
- }
-
- private void startSetupConnectionTask(ComponentName name) {
- stopSetupConnectionTask();
- mSetupConnectionAsyncTask = new PrepareConnectionAsyncTask(name);
- mSetupConnectionAsyncTask.execute();
- }
-
- private boolean stopSetupConnectionTask() {
- boolean result = false;
- if (mSetupConnectionAsyncTask != null) {
- result = mSetupConnectionAsyncTask.cancel(false);
- mSetupConnectionAsyncTask = null;
- }
- return result;
- }
-
- IBinder getCallerIdentity() {
- return mCallback;
- }
-
- boolean isEstablished() {
- return mService != null && mEstablished;
- }
-
- <T> ActionResult<T> runAction(Action<T> action) {
- synchronized (mLock) {
- try {
- return new ActionResult<T>(true, action.run(mService));
- } catch (Exception ex) {
- Log.e(TAG, action.getName() + " failed", ex);
- disconnect();
- return new ActionResult<T>(false);
- }
- }
- }
-
- void disconnect() {
- mContext.unbindService(this);
- stopSetupConnectionTask();
- mService = null;
- mEstablished = false;
- if (mServiceConnection == this) {
- mServiceConnection = null;
- }
- }
-
- String getEngineName() {
- return mEngineName;
- }
- }
-
- private abstract class Action<T> {
- private final String mName;
-
- public Action(String name) {
- mName = name;
- }
-
- public String getName() {return mName;}
- abstract T run(ITextToSpeechService service) throws RemoteException;
- }
-
- private class ActionResult<T> {
- boolean mSuccess;
- T mResult;
-
- ActionResult(boolean success) {
- mSuccess = success;
- }
-
- ActionResult(boolean success, T result) {
- mSuccess = success;
- mResult = result;
- }
- }
-
- private IBinder getCallerIdentity() {
- if (mServiceConnection != null) {
- return mServiceConnection.getCallerIdentity();
- }
- return null;
- }
-
- private <T> ActionResult<T> runAction(Action<T> action) {
- synchronized (mLock) {
- if (mServiceConnection == null) {
- Log.w(TAG, action.getName() + " failed: not bound to TTS engine");
- return new ActionResult<T>(false);
- }
- if (!mServiceConnection.isEstablished()) {
- Log.w(TAG, action.getName() + " failed: not fully bound to TTS engine");
- return new ActionResult<T>(false);
- }
- return mServiceConnection.runAction(action);
- }
- }
-
- private static final String ACTION_STOP_NAME = "stop";
-
- /**
- * Interrupts the current utterance spoken (whether played or rendered to file) and discards
- * other utterances in the queue.
- */
- public void stop() {
- runAction(new Action<Void>(ACTION_STOP_NAME) {
- @Override
- public Void run(ITextToSpeechService service) throws RemoteException {
- if (service.stop(getCallerIdentity()) != Status.SUCCESS) {
- Log.e(TAG, "Stop failed");
- }
- mCallbacks.clear();
- return null;
- }
- });
- }
-
- private static final String ACTION_QUEUE_SPEAK_NAME = "queueSpeak";
-
- /**
- * Speaks the string using the specified queuing strategy and the current
- * voice. This method is asynchronous, i.e. the method just adds the request
- * to the queue of TTS requests and then returns. The synthesis might not
- * have finished (or even started!) at the time when this method returns.
- *
- * @param utterance The string of text to be spoken. No longer than
- * 1000 characters.
- * @param utteranceId Unique identificator used to track the synthesis progress
- * in {@link RequestCallbacks}.
- * @param config Synthesis request configuration. Can't be null. Has to contain a
- * voice.
- * @param callbacks Synthesis request callbacks. If null, the default request
- * callbacks object will be used.
- */
- public void queueSpeak(final String utterance, final UtteranceId utteranceId,
- final RequestConfig config,
- final RequestCallbacks callbacks) {
- queueSpeak(createMarkupFromString(utterance), utteranceId, config, callbacks);
- }
-
- /**
- * Speaks the {@link Markup} (which can be constructed with {@link Utterance}) using
- * the specified queuing strategy and the current voice. This method is
- * asynchronous, i.e. the method just adds the request to the queue of TTS
- * requests and then returns. The synthesis might not have finished (or even
- * started!) at the time when this method returns.
- *
- * @param markup The Markup to be spoken. The written equivalent of the spoken
- * text should be no longer than 1000 characters.
- * @param utteranceId Unique identificator used to track the synthesis progress
- * in {@link RequestCallbacks}.
- * @param config Synthesis request configuration. Can't be null. Has to contain a
- * voice.
- * @param callbacks Synthesis request callbacks. If null, the default request
- * callbacks object will be used.
- */
- public void queueSpeak(final Markup markup,
- final UtteranceId utteranceId,
- final RequestConfig config,
- final RequestCallbacks callbacks) {
- runAction(new Action<Void>(ACTION_QUEUE_SPEAK_NAME) {
- @Override
- public Void run(ITextToSpeechService service) throws RemoteException {
- RequestCallbacks c = mDefaultRequestCallbacks;
- if (callbacks != null) {
- c = callbacks;
- }
- int addCallbackStatus = addCallback(utteranceId, c);
- if (addCallbackStatus != Status.SUCCESS) {
- c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
- return null;
- }
-
- int queueResult = service.speakV2(
- getCallerIdentity(),
- new SynthesisRequestV2(markup, utteranceId.toUniqueString(), config));
- if (queueResult != Status.SUCCESS) {
- removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
- }
- return null;
- }
- });
- }
-
- private static final String ACTION_QUEUE_SYNTHESIZE_TO_FILE = "queueSynthesizeToFile";
-
- /**
- * Synthesizes the given text to a file using the specified parameters. This
- * method is asynchronous, i.e. the method just adds the request to the
- * queue of TTS requests and then returns. The synthesis might not have
- * finished (or even started!) at the time when this method returns.
- *
- * @param utterance The text that should be synthesized. No longer than
- * 1000 characters.
- * @param utteranceId Unique identificator used to track the synthesis progress
- * in {@link RequestCallbacks}.
- * @param outputFile File to write the generated audio data to.
- * @param config Synthesis request configuration. Can't be null. Have to contain a
- * voice.
- * @param callbacks Synthesis request callbacks. If null, the default request
- * callbacks object will be used.
- */
- public void queueSynthesizeToFile(final String utterance, final UtteranceId utteranceId,
- final File outputFile, final RequestConfig config,
- final RequestCallbacks callbacks) {
- queueSynthesizeToFile(createMarkupFromString(utterance), utteranceId, outputFile, config, callbacks);
- }
-
- /**
- * Synthesizes the given {@link Markup} (can be constructed with {@link Utterance})
- * to a file using the specified parameters. This method is asynchronous, i.e. the
- * method just adds the request to the queue of TTS requests and then returns. The
- * synthesis might not have finished (or even started!) at the time when this method
- * returns.
- *
- * @param markup The Markup that should be synthesized. The written equivalent of
- * the spoken text should be no longer than 1000 characters.
- * @param utteranceId Unique identificator used to track the synthesis progress
- * in {@link RequestCallbacks}.
- * @param outputFile File to write the generated audio data to.
- * @param config Synthesis request configuration. Can't be null. Have to contain a
- * voice.
- * @param callbacks Synthesis request callbacks. If null, the default request
- * callbacks object will be used.
- */
- public void queueSynthesizeToFile(
- final Markup markup,
- final UtteranceId utteranceId,
- final File outputFile, final RequestConfig config,
- final RequestCallbacks callbacks) {
- runAction(new Action<Void>(ACTION_QUEUE_SYNTHESIZE_TO_FILE) {
- @Override
- public Void run(ITextToSpeechService service) throws RemoteException {
- RequestCallbacks c = mDefaultRequestCallbacks;
- if (callbacks != null) {
- c = callbacks;
- }
- int addCallbackStatus = addCallback(utteranceId, c);
- if (addCallbackStatus != Status.SUCCESS) {
- c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
- return null;
- }
-
- ParcelFileDescriptor fileDescriptor = null;
- try {
- if (outputFile.exists() && !outputFile.canWrite()) {
- Log.e(TAG, "No permissions to write to " + outputFile);
- removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
- return null;
- }
- fileDescriptor = ParcelFileDescriptor.open(outputFile,
- ParcelFileDescriptor.MODE_WRITE_ONLY |
- ParcelFileDescriptor.MODE_CREATE |
- ParcelFileDescriptor.MODE_TRUNCATE);
-
- int queueResult = service.synthesizeToFileDescriptorV2(getCallerIdentity(),
- fileDescriptor,
- new SynthesisRequestV2(markup, utteranceId.toUniqueString(), config));
- fileDescriptor.close();
- if (queueResult != Status.SUCCESS) {
- removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
- }
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Opening file " + outputFile + " failed", e);
- removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
- } catch (IOException e) {
- Log.e(TAG, "Closing file " + outputFile + " failed", e);
- removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
- }
- return null;
- }
- });
- }
-
- private static Markup createMarkupFromString(String str) {
- return new Utterance()
- .append(new Utterance.TtsText(str))
- .setNoWarningOnFallback(true)
- .createMarkup();
- }
-
- private static final String ACTION_QUEUE_SILENCE_NAME = "queueSilence";
-
- /**
- * Plays silence for the specified amount of time. This method is asynchronous,
- * i.e. the method just adds the request to the queue of TTS requests and then
- * returns. The synthesis might not have finished (or even started!) at the time
- * when this method returns.
- *
- * @param durationInMs The duration of the silence in milliseconds.
- * @param utteranceId Unique identificator used to track the synthesis progress
- * in {@link RequestCallbacks}.
- * @param callbacks Synthesis request callbacks. If null, default request
- * callbacks object will be used.
- */
- public void queueSilence(final long durationInMs, final UtteranceId utteranceId,
- final RequestCallbacks callbacks) {
- runAction(new Action<Void>(ACTION_QUEUE_SILENCE_NAME) {
- @Override
- public Void run(ITextToSpeechService service) throws RemoteException {
- RequestCallbacks c = mDefaultRequestCallbacks;
- if (callbacks != null) {
- c = callbacks;
- }
- int addCallbackStatus = addCallback(utteranceId, c);
- if (addCallbackStatus != Status.SUCCESS) {
- c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
- }
-
- int queueResult = service.playSilence(getCallerIdentity(), durationInMs,
- TextToSpeech.QUEUE_ADD, utteranceId.toUniqueString());
-
- if (queueResult != Status.SUCCESS) {
- removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
- }
- return null;
- }
- });
- }
-
-
- private static final String ACTION_QUEUE_AUDIO_NAME = "queueAudio";
-
- /**
- * Plays the audio resource using the specified parameters.
- * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
- * requests and then returns. The synthesis might not have finished (or even started!) at the
- * time when this method returns.
- *
- * @param audioUrl The audio resource that should be played
- * @param utteranceId Unique identificator used to track synthesis progress
- * in {@link RequestCallbacks}.
- * @param config Synthesis request configuration. Can't be null. Doesn't have to contain a
- * voice (only system parameters are used).
- * @param callbacks Synthesis request callbacks. If null, default request
- * callbacks object will be used.
- */
- public void queueAudio(final Uri audioUrl, final UtteranceId utteranceId,
- final RequestConfig config, final RequestCallbacks callbacks) {
- runAction(new Action<Void>(ACTION_QUEUE_AUDIO_NAME) {
- @Override
- public Void run(ITextToSpeechService service) throws RemoteException {
- RequestCallbacks c = mDefaultRequestCallbacks;
- if (callbacks != null) {
- c = callbacks;
- }
- int addCallbackStatus = addCallback(utteranceId, c);
- if (addCallbackStatus != Status.SUCCESS) {
- c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
- }
-
- int queueResult = service.playAudioV2(getCallerIdentity(), audioUrl,
- utteranceId.toUniqueString(), config.getVoiceParams());
-
- if (queueResult != Status.SUCCESS) {
- removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
- }
- return null;
- }
- });
- }
-
- private static final String ACTION_IS_SPEAKING_NAME = "isSpeaking";
-
- /**
- * Checks whether the TTS engine is busy speaking. Note that a speech item is
- * considered complete once it's audio data has been sent to the audio mixer, or
- * written to a file. There might be a finite lag between this point, and when
- * the audio hardware completes playback.
- *
- * @return {@code true} if the TTS engine is speaking.
- */
- public boolean isSpeaking() {
- ActionResult<Boolean> result = runAction(new Action<Boolean>(ACTION_IS_SPEAKING_NAME) {
- @Override
- public Boolean run(ITextToSpeechService service) throws RemoteException {
- return service.isSpeaking();
- }
- });
- if (!result.mSuccess) {
- return false; // We can't really say, return false
- }
- return result.mResult;
- }
-
-
- class InternalHandler extends Handler {
- final static int WHAT_ENGINE_STATUS_CHANGED = 1;
- final static int WHAT_SERVICE_DISCONNECTED = 2;
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case WHAT_ENGINE_STATUS_CHANGED:
- mConnectionCallbacks.onEngineStatusChange((EngineStatus) msg.obj);
- return;
- case WHAT_SERVICE_DISCONNECTED:
- mConnectionCallbacks.onServiceDisconnected();
- return;
- }
- }
- }
-}
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 20f3ad7..a53518f 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -74,26 +74,6 @@ import java.util.Set;
*
* {@link #onGetLanguage} is not required as of JELLYBEAN_MR2 (API 18) and later, it is only
* called on earlier versions of Android.
- * <p>
- * In order to fully support the V2 API ({@link TextToSpeechClient}),
- * these methods must be implemented:
- * <ul>
- * <li>{@link #onSynthesizeTextV2}</li>
- * <li>{@link #checkVoicesInfo}</li>
- * <li>{@link #onVoicesInfoChange}</li>
- * <li>{@link #implementsV2API}</li>
- * </ul>
- * In addition {@link #implementsV2API} has to return true.
- * <p>
- * If the service does not implement these methods and {@link #implementsV2API} returns false,
- * then the V2 API will be provided by converting V2 requests ({@link #onSynthesizeTextV2})
- * to V1 requests ({@link #onSynthesizeText}). On service setup, all of the available device
- * locales will be fed to {@link #onIsLanguageAvailable} to check if they are supported.
- * If they are, embedded and/or network voices will be created depending on the result of
- * {@link #onGetFeaturesForLanguage}.
- * <p>
- * Note that a V2 service will still receive requests from V1 clients and has to implement all
- * of the V1 API methods.
*/
public abstract class TextToSpeechService extends Service {
@@ -114,9 +94,6 @@ public abstract class TextToSpeechService extends Service {
private final Object mVoicesInfoLock = new Object();
- private List<VoiceInfo> mVoicesInfoList;
- private Map<String, VoiceInfo> mVoicesInfoLookup;
-
@Override
public void onCreate() {
if (DBG) Log.d(TAG, "onCreate()");
@@ -236,149 +213,6 @@ public abstract class TextToSpeechService extends Service {
SynthesisCallback callback);
/**
- * Check the available voices data and return an immutable list of the available voices.
- * The output of this method will be passed to clients to allow them to configure synthesis
- * requests.
- *
- * Can be called on multiple threads.
- *
- * The result of this method will be saved and served to all TTS clients. If a TTS service wants
- * to update the set of available voices, it should call the {@link #forceVoicesInfoCheck()}
- * method.
- */
- protected List<VoiceInfo> checkVoicesInfo() {
- if (implementsV2API()) {
- throw new IllegalStateException("For proper V2 API implementation this method has to" +
- " be implemented");
- }
-
- // V2 to V1 interface adapter. This allows using V2 client interface on V1-only services.
- Bundle defaultParams = new Bundle();
- defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_PITCH, 1.0f);
- // Speech speed <= 0 makes it use a system wide setting
- defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED, 0.0f);
-
- // Enumerate all locales and check if they are available
- ArrayList<VoiceInfo> voicesInfo = new ArrayList<VoiceInfo>();
- int id = 0;
- for (Locale locale : Locale.getAvailableLocales()) {
- int expectedStatus = TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE;
- if (locale.getVariant().isEmpty()) {
- if (locale.getCountry().isEmpty()) {
- expectedStatus = TextToSpeech.LANG_AVAILABLE;
- } else {
- expectedStatus = TextToSpeech.LANG_COUNTRY_AVAILABLE;
- }
- }
- try {
- int localeStatus = onIsLanguageAvailable(locale.getISO3Language(),
- locale.getISO3Country(), locale.getVariant());
- if (localeStatus != expectedStatus) {
- continue;
- }
- } catch (MissingResourceException e) {
- // Ignore locale without iso 3 codes
- continue;
- }
-
- Set<String> features = onGetFeaturesForLanguage(locale.getISO3Language(),
- locale.getISO3Country(), locale.getVariant());
-
- VoiceInfo.Builder builder = new VoiceInfo.Builder();
- builder.setLatency(VoiceInfo.LATENCY_NORMAL);
- builder.setQuality(VoiceInfo.QUALITY_NORMAL);
- builder.setLocale(locale);
- builder.setParamsWithDefaults(defaultParams);
-
- if (features == null || features.contains(
- TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS)) {
- builder.setName(locale.toString() + "-embedded");
- builder.setRequiresNetworkConnection(false);
- voicesInfo.add(builder.build());
- }
-
- if (features != null && features.contains(
- TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS)) {
- builder.setName(locale.toString() + "-network");
- builder.setRequiresNetworkConnection(true);
- voicesInfo.add(builder.build());
- }
- }
-
- return voicesInfo;
- }
-
- /**
- * Tells the synthesis thread that it should reload voice data.
- * There's a high probability that the underlying set of available voice data has changed.
- * Called only on the synthesis thread.
- */
- protected void onVoicesInfoChange() {
-
- }
-
- /**
- * Tells the service to synthesize speech from the given text. This method
- * should block until the synthesis is finished. Used for requests from V2
- * client {@link android.speech.tts.TextToSpeechClient}. Called on the
- * synthesis thread.
- *
- * @param request The synthesis request.
- * @param callback The callback the the engine must use to make data
- * available for playback or for writing to a file.
- */
- protected void onSynthesizeTextV2(SynthesisRequestV2 request,
- VoiceInfo selectedVoice,
- SynthesisCallback callback) {
- if (implementsV2API()) {
- throw new IllegalStateException("For proper V2 API implementation this method has to" +
- " be implemented");
- }
-
- // Convert to V1 params
- int speechRate = (int) (request.getVoiceParams().getFloat(
- TextToSpeechClient.Params.SPEECH_SPEED, 1.0f) * 100);
- int speechPitch = (int) (request.getVoiceParams().getFloat(
- TextToSpeechClient.Params.SPEECH_PITCH, 1.0f) * 100);
-
- // Provide adapter to V1 API
- Bundle params = new Bundle();
- params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, request.getUtteranceId());
- params.putInt(TextToSpeech.Engine.KEY_PARAM_PITCH, speechPitch);
- params.putInt(TextToSpeech.Engine.KEY_PARAM_RATE, speechRate);
- if (selectedVoice.getRequiresNetworkConnection()) {
- params.putString(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS, "true");
- } else {
- params.putString(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS, "true");
- }
-
- String noWarning = request.getMarkup().getParameter(Utterance.KEY_NO_WARNING_ON_FALLBACK);
- if (noWarning == null || noWarning.equals("false")) {
- Log.w("TextToSpeechService", "The synthesis engine does not support Markup, falling " +
- "back to the given plain text.");
- }
-
- // Build V1 request
- SynthesisRequest requestV1 = new SynthesisRequest(request.getText(), params);
- Locale locale = selectedVoice.getLocale();
- requestV1.setLanguage(locale.getISO3Language(), locale.getISO3Country(),
- locale.getVariant());
- requestV1.setSpeechRate(speechRate);
- requestV1.setPitch(speechPitch);
-
- // Synthesize using V1 interface
- onSynthesizeText(requestV1, callback);
- }
-
- /**
- * If true, this service implements proper V2 TTS API service. If it's false,
- * V2 API will be provided through adapter.
- */
- protected boolean implementsV2API() {
- return false;
- }
-
- /**
* Queries the service for a set of features supported for a given language.
*
* Can be called on multiple threads.
@@ -392,69 +226,6 @@ public abstract class TextToSpeechService extends Service {
return null;
}
- private List<VoiceInfo> getVoicesInfo() {
- synchronized (mVoicesInfoLock) {
- if (mVoicesInfoList == null) {
- // Get voices. Defensive copy to make sure TTS engine won't alter the list.
- mVoicesInfoList = new ArrayList<VoiceInfo>(checkVoicesInfo());
- // Build lookup map
- mVoicesInfoLookup = new HashMap<String, VoiceInfo>((int) (
- mVoicesInfoList.size()*1.5f));
- for (VoiceInfo voiceInfo : mVoicesInfoList) {
- VoiceInfo prev = mVoicesInfoLookup.put(voiceInfo.getName(), voiceInfo);
- if (prev != null) {
- Log.e(TAG, "Duplicate name (" + voiceInfo.getName() + ") of the voice ");
- }
- }
- }
- return mVoicesInfoList;
- }
- }
-
- public VoiceInfo getVoicesInfoWithName(String name) {
- synchronized (mVoicesInfoLock) {
- if (mVoicesInfoLookup != null) {
- return mVoicesInfoLookup.get(name);
- }
- }
- return null;
- }
-
- /**
- * Force TTS service to reevaluate the set of available languages. Will result in
- * a call to {@link #checkVoicesInfo()} on the same thread, {@link #onVoicesInfoChange}
- * on the synthesizer thread and callback to
- * {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange} of all connected
- * TTS clients.
- *
- * Use this method only if you know that set of available languages changed.
- *
- * Can be called on multiple threads.
- */
- public void forceVoicesInfoCheck() {
- synchronized (mVoicesInfoLock) {
- List<VoiceInfo> old = mVoicesInfoList;
-
- mVoicesInfoList = null; // Force recreation of voices info list
- getVoicesInfo();
-
- if (mVoicesInfoList == null) {
- throw new IllegalStateException("This method applies only to services " +
- "supporting V2 TTS API. This services doesn't support V2 TTS API.");
- }
-
- if (old != null) {
- // Flush all existing items, and inform synthesis thread about the change.
- mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_FLUSH,
- new VoicesInfoChangeItem());
- // TODO: Handle items that may be added to queue after SynthesizerRestartItem
- // but before client reconnection
- // Disconnect all of them
- mCallbacks.dispatchVoicesInfoChange(mVoicesInfoList);
- }
- }
- }
-
private int getDefaultSpeechRate() {
return getSecureSettingInt(Settings.Secure.TTS_DEFAULT_RATE, Engine.DEFAULT_RATE);
}
@@ -558,7 +329,7 @@ public abstract class TextToSpeechService extends Service {
if (!speechItem.isValid()) {
if (utterenceProgress != null) {
utterenceProgress.dispatchOnError(
- TextToSpeechClient.Status.ERROR_INVALID_REQUEST);
+ TextToSpeech.ERROR_INVALID_REQUEST);
}
return TextToSpeech.ERROR;
}
@@ -589,7 +360,7 @@ public abstract class TextToSpeechService extends Service {
} else {
Log.w(TAG, "SynthThread has quit");
if (utterenceProgress != null) {
- utterenceProgress.dispatchOnError(TextToSpeechClient.Status.ERROR_SERVICE);
+ utterenceProgress.dispatchOnError(TextToSpeech.ERROR_SERVICE);
}
return TextToSpeech.ERROR;
}
@@ -834,232 +605,6 @@ public abstract class TextToSpeechService extends Service {
}
}
- class SynthesisSpeechItemV2 extends UtteranceSpeechItem {
- private final SynthesisRequestV2 mSynthesisRequest;
- private AbstractSynthesisCallback mSynthesisCallback;
- private final EventLoggerV2 mEventLogger;
-
- public SynthesisSpeechItemV2(Object callerIdentity, int callerUid, int callerPid,
- SynthesisRequestV2 synthesisRequest) {
- super(callerIdentity, callerUid, callerPid);
-
- mSynthesisRequest = synthesisRequest;
- mEventLogger = new EventLoggerV2(synthesisRequest, callerUid, callerPid,
- mPackageName);
-
- updateSpeechSpeedParam(synthesisRequest);
- }
-
- private void updateSpeechSpeedParam(SynthesisRequestV2 synthesisRequest) {
- Bundle voiceParams = mSynthesisRequest.getVoiceParams();
-
- // Inject default speech speed if needed
- if (voiceParams.containsKey(TextToSpeechClient.Params.SPEECH_SPEED)) {
- if (voiceParams.getFloat(TextToSpeechClient.Params.SPEECH_SPEED) <= 0) {
- voiceParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED,
- getDefaultSpeechRate() / 100.0f);
- }
- }
- }
-
- /**
- * Estimate of the character count equivalent of a Markup instance. Calculated
- * by summing the characters of all Markups of type "text". Each other node
- * is counted as a single character, as the character count of other nodes
- * is non-trivial to calculate and we don't want to accept arbitrarily large
- * requests.
- */
- private int estimateSynthesisLengthFromMarkup(Markup m) {
- int size = 0;
- if (m.getType() != null &&
- m.getType().equals("text") &&
- m.getParameter("text") != null) {
- size += m.getParameter("text").length();
- } else if (m.getType() == null ||
- !m.getType().equals("utterance")) {
- size += 1;
- }
- for (Markup nested : m.getNestedMarkups()) {
- size += estimateSynthesisLengthFromMarkup(nested);
- }
- return size;
- }
-
- @Override
- public boolean isValid() {
- if (mSynthesisRequest.getMarkup() == null) {
- Log.e(TAG, "No markup in request.");
- return false;
- }
- String type = mSynthesisRequest.getMarkup().getType();
- if (type == null) {
- Log.w(TAG, "Top level markup node should have type \"utterance\", not null");
- return false;
- } else if (!type.equals("utterance")) {
- Log.w(TAG, "Top level markup node should have type \"utterance\" instead of " +
- "\"" + type + "\"");
- return false;
- }
-
- int estimate = estimateSynthesisLengthFromMarkup(mSynthesisRequest.getMarkup());
- if (estimate >= TextToSpeech.getMaxSpeechInputLength()) {
- Log.w(TAG, "Text too long: estimated size of text was " + estimate + " chars.");
- return false;
- }
-
- if (estimate <= 0) {
- Log.e(TAG, "null synthesis text");
- return false;
- }
-
- return true;
- }
-
- @Override
- protected void playImpl() {
- AbstractSynthesisCallback synthesisCallback;
- if (mEventLogger != null) {
- mEventLogger.onRequestProcessingStart();
- }
- synchronized (this) {
- // stop() might have been called before we enter this
- // synchronized block.
- if (isStopped()) {
- return;
- }
- mSynthesisCallback = createSynthesisCallback();
- synthesisCallback = mSynthesisCallback;
- }
-
- // Get voice info
- VoiceInfo voiceInfo = getVoicesInfoWithName(mSynthesisRequest.getVoiceName());
- if (voiceInfo != null) {
- // Primary voice
- TextToSpeechService.this.onSynthesizeTextV2(mSynthesisRequest, voiceInfo,
- synthesisCallback);
- } else {
- Log.e(TAG, "Unknown voice name:" + mSynthesisRequest.getVoiceName());
- synthesisCallback.error(TextToSpeechClient.Status.ERROR_INVALID_REQUEST);
- }
-
- // Fix for case where client called .start() & .error(), but did not called .done()
- if (!synthesisCallback.hasFinished()) {
- synthesisCallback.done();
- }
- }
-
- @Override
- protected void stopImpl() {
- AbstractSynthesisCallback synthesisCallback;
- synchronized (this) {
- synthesisCallback = mSynthesisCallback;
- }
- if (synthesisCallback != null) {
- // If the synthesis callback is null, it implies that we haven't
- // entered the synchronized(this) block in playImpl which in
- // turn implies that synthesis would not have started.
- synthesisCallback.stop();
- TextToSpeechService.this.onStop();
- }
- }
-
- protected AbstractSynthesisCallback createSynthesisCallback() {
- return new PlaybackSynthesisCallback(getStreamType(), getVolume(), getPan(),
- mAudioPlaybackHandler, this, getCallerIdentity(), mEventLogger,
- implementsV2API());
- }
-
- private int getStreamType() {
- return getIntParam(mSynthesisRequest.getAudioParams(),
- TextToSpeechClient.Params.AUDIO_PARAM_STREAM,
- Engine.DEFAULT_STREAM);
- }
-
- private float getVolume() {
- return getFloatParam(mSynthesisRequest.getAudioParams(),
- TextToSpeechClient.Params.AUDIO_PARAM_VOLUME,
- Engine.DEFAULT_VOLUME);
- }
-
- private float getPan() {
- return getFloatParam(mSynthesisRequest.getAudioParams(),
- TextToSpeechClient.Params.AUDIO_PARAM_PAN,
- Engine.DEFAULT_PAN);
- }
-
- @Override
- public String getUtteranceId() {
- return mSynthesisRequest.getUtteranceId();
- }
- }
-
- private class SynthesisToFileOutputStreamSpeechItemV2 extends SynthesisSpeechItemV2 {
- private final FileOutputStream mFileOutputStream;
-
- public SynthesisToFileOutputStreamSpeechItemV2(Object callerIdentity, int callerUid,
- int callerPid,
- SynthesisRequestV2 synthesisRequest,
- FileOutputStream fileOutputStream) {
- super(callerIdentity, callerUid, callerPid, synthesisRequest);
- mFileOutputStream = fileOutputStream;
- }
-
- @Override
- protected AbstractSynthesisCallback createSynthesisCallback() {
- return new FileSynthesisCallback(mFileOutputStream.getChannel(),
- this, getCallerIdentity(), implementsV2API());
- }
-
- @Override
- protected void playImpl() {
- super.playImpl();
- try {
- mFileOutputStream.close();
- } catch(IOException e) {
- Log.w(TAG, "Failed to close output file", e);
- }
- }
- }
-
- private class AudioSpeechItemV2 extends UtteranceSpeechItem {
- private final AudioPlaybackQueueItem mItem;
- private final Bundle mAudioParams;
- private final String mUtteranceId;
-
- public AudioSpeechItemV2(Object callerIdentity, int callerUid, int callerPid,
- String utteranceId, Bundle audioParams, Uri uri) {
- super(callerIdentity, callerUid, callerPid);
- mUtteranceId = utteranceId;
- mAudioParams = audioParams;
- mItem = new AudioPlaybackQueueItem(this, getCallerIdentity(),
- TextToSpeechService.this, uri, getStreamType());
- }
-
- @Override
- public boolean isValid() {
- return true;
- }
-
- @Override
- protected void playImpl() {
- mAudioPlaybackHandler.enqueue(mItem);
- }
-
- @Override
- protected void stopImpl() {
- // Do nothing.
- }
-
- protected int getStreamType() {
- return mAudioParams.getInt(TextToSpeechClient.Params.AUDIO_PARAM_STREAM);
- }
-
- public String getUtteranceId() {
- return mUtteranceId;
- }
- }
-
-
class SynthesisSpeechItemV1 extends SpeechItemV1 {
// Never null.
private final String mText;
@@ -1256,30 +801,6 @@ public abstract class TextToSpeechService extends Service {
}
/**
- * Call {@link TextToSpeechService#onVoicesInfoChange} on synthesis thread.
- */
- private class VoicesInfoChangeItem extends SpeechItem {
- public VoicesInfoChangeItem() {
- super(null, 0, 0); // It's never initiated by an user
- }
-
- @Override
- public boolean isValid() {
- return true;
- }
-
- @Override
- protected void playImpl() {
- TextToSpeechService.this.onVoicesInfoChange();
- }
-
- @Override
- protected void stopImpl() {
- // No-op
- }
- }
-
- /**
* Call {@link TextToSpeechService#onLoadLanguage} on synth thread.
*/
private class LoadLanguageItem extends SpeechItem {
@@ -1475,58 +996,6 @@ public abstract class TextToSpeechService extends Service {
}
return true;
}
-
- @Override
- public List<VoiceInfo> getVoicesInfo() {
- return TextToSpeechService.this.getVoicesInfo();
- }
-
- @Override
- public int speakV2(IBinder callingInstance,
- SynthesisRequestV2 request) {
- if (!checkNonNull(callingInstance, request)) {
- return TextToSpeech.ERROR;
- }
-
- SpeechItem item = new SynthesisSpeechItemV2(callingInstance,
- Binder.getCallingUid(), Binder.getCallingPid(), request);
- return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
- }
-
- @Override
- public int synthesizeToFileDescriptorV2(IBinder callingInstance,
- ParcelFileDescriptor fileDescriptor,
- SynthesisRequestV2 request) {
- if (!checkNonNull(callingInstance, request, fileDescriptor)) {
- return TextToSpeech.ERROR;
- }
-
- // In test env, ParcelFileDescriptor instance may be EXACTLY the same
- // one that is used by client. And it will be closed by a client, thus
- // preventing us from writing anything to it.
- final ParcelFileDescriptor sameFileDescriptor = ParcelFileDescriptor.adoptFd(
- fileDescriptor.detachFd());
-
- SpeechItem item = new SynthesisToFileOutputStreamSpeechItemV2(callingInstance,
- Binder.getCallingUid(), Binder.getCallingPid(), request,
- new ParcelFileDescriptor.AutoCloseOutputStream(sameFileDescriptor));
- return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
-
- }
-
- @Override
- public int playAudioV2(
- IBinder callingInstance, Uri audioUri, String utteranceId,
- Bundle systemParameters) {
- if (!checkNonNull(callingInstance, audioUri, systemParameters)) {
- return TextToSpeech.ERROR;
- }
-
- SpeechItem item = new AudioSpeechItemV2(callingInstance,
- Binder.getCallingUid(), Binder.getCallingPid(), utteranceId, systemParameters,
- audioUri);
- return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
- }
};
private class CallbackMap extends RemoteCallbackList<ITextToSpeechCallback> {
@@ -1617,18 +1086,6 @@ public abstract class TextToSpeechService extends Service {
}
}
- public void dispatchVoicesInfoChange(List<VoiceInfo> voicesInfo) {
- synchronized (mCallerToCallback) {
- for (ITextToSpeechCallback callback : mCallerToCallback.values()) {
- try {
- callback.onVoicesInfoChange(voicesInfo);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to request reconnect", e);
- }
- }
- }
- }
-
private ITextToSpeechCallback getCallbackFor(Object caller) {
ITextToSpeechCallback cb;
IBinder asBinder = (IBinder) caller;
diff --git a/core/java/android/speech/tts/UtteranceProgressListener.java b/core/java/android/speech/tts/UtteranceProgressListener.java
index cf0d22c..6769794 100644
--- a/core/java/android/speech/tts/UtteranceProgressListener.java
+++ b/core/java/android/speech/tts/UtteranceProgressListener.java
@@ -40,10 +40,26 @@ public abstract class UtteranceProgressListener {
* the same utterance.
*
* @param utteranceId the utterance ID of the utterance.
+ * @deprecated Use {@link #onError(String,int)} instead
*/
+ @Deprecated
public abstract void onError(String utteranceId);
/**
+ * Called when an error has occurred during processing. This can be called
+ * at any point in the synthesis process. Note that there might be calls
+ * to {@link #onStart(String)} for specified utteranceId but there will never
+ * be a call to both {@link #onDone(String)} and {@link #onError(String,int)} for
+ * the same utterance. The default implementation calls {@link #onError(String)}.
+ *
+ * @param utteranceId the utterance ID of the utterance.
+ * @param errorCode one of the ERROR_* codes from {@link TextToSpeech}
+ */
+ public void onError(String utteranceId, int errorCode) {
+ onError(utteranceId);
+ }
+
+ /**
* Wraps an old deprecated OnUtteranceCompletedListener with a shiny new
* progress listener.
*
diff --git a/core/java/android/speech/tts/VoiceInfo.aidl b/core/java/android/speech/tts/VoiceInfo.aidl
deleted file mode 100644
index 4005f8b..0000000
--- a/core/java/android/speech/tts/VoiceInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-**
-** Copyright 2013, 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;
-
-parcelable VoiceInfo; \ No newline at end of file
diff --git a/core/java/android/speech/tts/VoiceInfo.java b/core/java/android/speech/tts/VoiceInfo.java
deleted file mode 100644
index 71629dc..0000000
--- a/core/java/android/speech/tts/VoiceInfo.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2014 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.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Locale;
-
-/**
- * Characteristics and features of a Text-To-Speech Voice. Each TTS Engine can expose
- * multiple voices for multiple locales, with different set of features.
- *
- * Each VoiceInfo has an unique name. This name can be obtained using the {@link #getName()} method
- * and will persist until the client is asked to re-evaluate the list of available voices in the
- * {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
- * callback. The name can be used to reference a VoiceInfo in an instance of {@link RequestConfig};
- * the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter is an example of this.
- * It is recommended that the voice name never change during the TTS service lifetime.
- */
-public final class VoiceInfo implements Parcelable {
- /** Very low, but still intelligible quality of speech synthesis */
- public static final int QUALITY_VERY_LOW = 100;
-
- /** Low, not human-like quality of speech synthesis */
- public static final int QUALITY_LOW = 200;
-
- /** Normal quality of speech synthesis */
- public static final int QUALITY_NORMAL = 300;
-
- /** High, human-like quality of speech synthesis */
- public static final int QUALITY_HIGH = 400;
-
- /** Very high, almost human-indistinguishable quality of speech synthesis */
- public static final int QUALITY_VERY_HIGH = 500;
-
- /** Very low expected synthesizer latency (< 20ms) */
- public static final int LATENCY_VERY_LOW = 100;
-
- /** Low expected synthesizer latency (~20ms) */
- public static final int LATENCY_LOW = 200;
-
- /** Normal expected synthesizer latency (~50ms) */
- public static final int LATENCY_NORMAL = 300;
-
- /** Network based expected synthesizer latency (~200ms) */
- public static final int LATENCY_HIGH = 400;
-
- /** Very slow network based expected synthesizer latency (> 200ms) */
- public static final int LATENCY_VERY_HIGH = 500;
-
- /** Additional feature key, with string value, gender of the speaker */
- public static final String FEATURE_SPEAKER_GENDER = "speakerGender";
-
- /** Additional feature key, with integer value, speaking speed in words per minute
- * when {@link TextToSpeechClient.Params#SPEECH_SPEED} parameter is set to {@code 1.0} */
- public static final String FEATURE_WORDS_PER_MINUTE = "wordsPerMinute";
-
- /**
- * Additional feature key, with boolean value, that indicates that voice may need to
- * download additional data if used for synthesis.
- *
- * Making a request with a voice that has this feature may result in a
- * {@link TextToSpeechClient.Status#ERROR_DOWNLOADING_ADDITIONAL_DATA} error. It's recommended
- * to set the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter to reference
- * a fully installed voice (or network voice) that can serve as replacement.
- *
- * Note: It's a good practice for a TTS engine to provide a sensible fallback voice as the
- * default value for {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} parameter if this
- * feature is present.
- */
- public static final String FEATURE_MAY_AUTOINSTALL = "mayAutoInstall";
-
- private final String mName;
- private final Locale mLocale;
- private final int mQuality;
- private final int mLatency;
- private final boolean mRequiresNetworkConnection;
- private final Bundle mParams;
- private final Bundle mAdditionalFeatures;
-
- private VoiceInfo(Parcel in) {
- this.mName = in.readString();
- String[] localesData = new String[3];
- in.readStringArray(localesData);
- this.mLocale = new Locale(localesData[0], localesData[1], localesData[2]);
-
- this.mQuality = in.readInt();
- this.mLatency = in.readInt();
- this.mRequiresNetworkConnection = (in.readByte() == 1);
-
- this.mParams = in.readBundle();
- this.mAdditionalFeatures = in.readBundle();
- }
-
- private VoiceInfo(String name,
- Locale locale,
- int quality,
- int latency,
- boolean requiresNetworkConnection,
- Bundle params,
- Bundle additionalFeatures) {
- this.mName = name;
- this.mLocale = locale;
- this.mQuality = quality;
- this.mLatency = latency;
- this.mRequiresNetworkConnection = requiresNetworkConnection;
- this.mParams = params;
- this.mAdditionalFeatures = additionalFeatures;
- }
-
- /** Builder, allows TTS engines to create VoiceInfo instances. */
- public static final class Builder {
- private String name;
- private Locale locale;
- private int quality = VoiceInfo.QUALITY_NORMAL;
- private int latency = VoiceInfo.LATENCY_NORMAL;
- private boolean requiresNetworkConnection;
- private Bundle params;
- private Bundle additionalFeatures;
-
- public Builder() {
-
- }
-
- /**
- * Copy fields from given VoiceInfo instance.
- */
- public Builder(VoiceInfo voiceInfo) {
- this.name = voiceInfo.mName;
- this.locale = voiceInfo.mLocale;
- this.quality = voiceInfo.mQuality;
- this.latency = voiceInfo.mLatency;
- this.requiresNetworkConnection = voiceInfo.mRequiresNetworkConnection;
- this.params = (Bundle)voiceInfo.mParams.clone();
- this.additionalFeatures = (Bundle) voiceInfo.mAdditionalFeatures.clone();
- }
-
- /**
- * Sets the voice's unique name. It will be used by clients to reference the voice used by a
- * request.
- *
- * It's recommended that each voice use the same consistent name during the TTS service
- * lifetime.
- */
- public Builder setName(String name) {
- this.name = name;
- return this;
- }
-
- /**
- * Sets voice locale. This has to be a valid locale, built from ISO 639-1 and ISO 3166-1
- * two letter codes.
- */
- public Builder setLocale(Locale locale) {
- this.locale = locale;
- return this;
- }
-
- /**
- * Sets map of all available request parameters with their default values.
- * Some common parameter names can be found in {@link TextToSpeechClient.Params} static
- * members.
- */
- public Builder setParamsWithDefaults(Bundle params) {
- this.params = params;
- return this;
- }
-
- /**
- * Sets map of additional voice features. Some common feature names can be found in
- * {@link VoiceInfo} static members.
- */
- public Builder setAdditionalFeatures(Bundle additionalFeatures) {
- this.additionalFeatures = additionalFeatures;
- return this;
- }
-
- /**
- * Sets the voice quality (higher is better).
- */
- public Builder setQuality(int quality) {
- this.quality = quality;
- return this;
- }
-
- /**
- * Sets the voice latency (lower is better).
- */
- public Builder setLatency(int latency) {
- this.latency = latency;
- return this;
- }
-
- /**
- * Sets whether the voice requires network connection to work properly.
- */
- public Builder setRequiresNetworkConnection(boolean requiresNetworkConnection) {
- this.requiresNetworkConnection = requiresNetworkConnection;
- return this;
- }
-
- /**
- * @return The built VoiceInfo instance.
- */
- public VoiceInfo build() {
- if (name == null || name.isEmpty()) {
- throw new IllegalStateException("Name can't be null or empty");
- }
- if (locale == null) {
- throw new IllegalStateException("Locale can't be null");
- }
-
- return new VoiceInfo(name, locale, quality, latency,
- requiresNetworkConnection,
- ((params == null) ? new Bundle() :
- (Bundle)params.clone()),
- ((additionalFeatures == null) ? new Bundle() :
- (Bundle)additionalFeatures.clone()));
- }
- }
-
- /**
- * @hide
- */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * @hide
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mName);
- String[] localesData = new String[]{mLocale.getLanguage(), mLocale.getCountry(), mLocale.getVariant()};
- dest.writeStringArray(localesData);
- dest.writeInt(mQuality);
- dest.writeInt(mLatency);
- dest.writeByte((byte) (mRequiresNetworkConnection ? 1 : 0));
- dest.writeBundle(mParams);
- dest.writeBundle(mAdditionalFeatures);
- }
-
- /**
- * @hide
- */
- public static final Parcelable.Creator<VoiceInfo> CREATOR = new Parcelable.Creator<VoiceInfo>() {
- @Override
- public VoiceInfo createFromParcel(Parcel in) {
- return new VoiceInfo(in);
- }
-
- @Override
- public VoiceInfo[] newArray(int size) {
- return new VoiceInfo[size];
- }
- };
-
- /**
- * @return The voice's locale
- */
- public Locale getLocale() {
- return mLocale;
- }
-
- /**
- * @return The voice's quality (higher is better)
- */
- public int getQuality() {
- return mQuality;
- }
-
- /**
- * @return The voice's latency (lower is better)
- */
- public int getLatency() {
- return mLatency;
- }
-
- /**
- * @return Does the Voice require a network connection to work.
- */
- public boolean getRequiresNetworkConnection() {
- return mRequiresNetworkConnection;
- }
-
- /**
- * @return Bundle of all available parameters with their default values.
- */
- public Bundle getParamsWithDefaults() {
- return mParams;
- }
-
- /**
- * @return Unique voice name.
- *
- * Each VoiceInfo has an unique name, that persists until client is asked to re-evaluate the
- * set of the available languages in the {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
- * callback (Voice may disappear from the set if voice was removed by the user).
- */
- public String getName() {
- return mName;
- }
-
- /**
- * @return Additional features of the voice.
- */
- public Bundle getAdditionalFeatures() {
- return mAdditionalFeatures;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder(64);
- return builder.append("VoiceInfo[Name: ").append(mName)
- .append(" ,locale: ").append(mLocale)
- .append(" ,quality: ").append(mQuality)
- .append(" ,latency: ").append(mLatency)
- .append(" ,requiresNetwork: ").append(mRequiresNetworkConnection)
- .append(" ,paramsWithDefaults: ").append(mParams.toString())
- .append(" ,additionalFeatures: ").append(mAdditionalFeatures.toString())
- .append("]").toString();
- }
-}