OSDN Git Service

Restrict audioformat to 8bit, 16bit or float PCM with an annotation and
authorNiels Egberts <nielse@google.com>
Fri, 20 Nov 2015 14:47:31 +0000 (14:47 +0000)
committerNiels Egberts <nielse@google.com>
Mon, 23 Nov 2015 10:15:39 +0000 (10:15 +0000)
a warning.

TextToSpeech.synthesizeToFile has only ever worked with 8bit and 16bit
PCM. In case of float PCM an invalid file would be generated and in case
of other encodings the TTS engine would crash.

Also add more annotations to SynthesisCallback.

Change-Id: I1c44a44509e9b53bb2e1b0f2044b1a5919875e1c

core/java/android/speech/tts/FileSynthesisCallback.java
core/java/android/speech/tts/PlaybackSynthesisCallback.java
core/java/android/speech/tts/SynthesisCallback.java
core/java/android/speech/tts/TextToSpeech.java

index a88eead..2b882d3 100644 (file)
@@ -107,6 +107,14 @@ class FileSynthesisCallback extends AbstractSynthesisCallback {
             Log.d(TAG, "FileSynthesisRequest.start(" + sampleRateInHz + "," + audioFormat
                     + "," + channelCount + ")");
         }
+        if (audioFormat != AudioFormat.ENCODING_PCM_8BIT ||
+            audioFormat != AudioFormat.ENCODING_PCM_16BIT ||
+            audioFormat != AudioFormat.ENCODING_PCM_FLOAT) {
+            Log.e(TAG, "Audio format encoding " + audioFormat + " not supported. Please use one " +
+                       "of AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT or " +
+                       "AudioFormat.ENCODING_PCM_FLOAT");
+        }
+
         FileChannel fileChannel = null;
         synchronized (mStateLock) {
             if (mStatusCode == TextToSpeech.STOPPED) {
index f850f10..a6fb543 100644 (file)
@@ -15,6 +15,7 @@
  */
 package android.speech.tts;
 
+import android.media.AudioFormat;
 import android.speech.tts.TextToSpeechService.AudioOutputParams;
 import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
 import android.util.Log;
@@ -122,6 +123,13 @@ class PlaybackSynthesisCallback extends AbstractSynthesisCallback {
     public int start(int sampleRateInHz, int audioFormat, int channelCount) {
         if (DBG) Log.d(TAG, "start(" + sampleRateInHz + "," + audioFormat + "," + channelCount
                 + ")");
+        if (audioFormat != AudioFormat.ENCODING_PCM_8BIT ||
+            audioFormat != AudioFormat.ENCODING_PCM_16BIT ||
+            audioFormat != AudioFormat.ENCODING_PCM_FLOAT) {
+            Log.w(TAG, "Audio format encoding " + audioFormat + " not supported. Please use one " +
+                       "of AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT or " +
+                       "AudioFormat.ENCODING_PCM_FLOAT");
+        }
 
         int channelConfig = BlockingAudioTrack.getChannelConfig(channelCount);
 
index e32438b..aad0d87 100644 (file)
  */
 package android.speech.tts;
 
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.media.AudioFormat;
+import android.speech.tts.TextToSpeech;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A callback to return speech data synthesized by a text to speech engine.
  *
@@ -31,6 +39,13 @@ package android.speech.tts;
  * All methods can be only called on the synthesis thread.
  */
 public interface SynthesisCallback {
+
+     /** @hide */
+     @Retention(RetentionPolicy.SOURCE)
+     @IntDef({AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT,
+              AudioFormat.ENCODING_PCM_FLOAT})
+     public @interface SupportedAudioFormat {};
+
     /**
      * @return the maximum number of bytes that the TTS engine can pass in a single call of
      *         {@link #audioAvailable}. Calls to {@link #audioAvailable} with data lengths
@@ -38,6 +53,7 @@ public interface SynthesisCallback {
      */
     public int getMaxBufferSize();
 
+    // TODO: Replace reference to Android N to an API level when the API level for N is decided.
     /**
      * The service should call this when it starts to synthesize audio for this
      * request.
@@ -47,12 +63,16 @@ public interface SynthesisCallback {
      *
      * @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}.
+     *         {@link android.media.AudioFormat.ENCODING_PCM_8BIT} or
+     *         {@link android.media.AudioFormat.ENCODING_PCM_16BIT}. Or
+     *         {@link android.media.AudioFormat.ENCODING_PCM_FLOAT} when targetting Android N and
+     *         above.
      * @param channelCount The number of channels. Must be {@code 1} or {@code 2}.
      * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR} or
      *          {@link TextToSpeech#STOPPED}.
      */
-    public int start(int sampleRateInHz, int audioFormat, int channelCount);
+    public int start(int sampleRateInHz, @SupportedAudioFormat int audioFormat,
+                     @IntRange(from=1,to=2) int channelCount);
 
     /**
      * The service should call this method when synthesized audio is ready for consumption.
@@ -102,7 +122,7 @@ public interface SynthesisCallback {
      * @param errorCode Error code to pass to the client. One of the ERROR_ values from
      *      {@link TextToSpeech}
      */
-    public void error(int errorCode);
+    public void error(@TextToSpeech.Error int errorCode);
 
     /**
      * Check if {@link #start} was called or not.
index eae4329..61c33ff 100644 (file)
@@ -15,6 +15,7 @@
  */
 package android.speech.tts;
 
+import android.annotation.IntDef;
 import android.annotation.RawRes;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -38,6 +39,8 @@ import android.util.Log;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -75,6 +78,12 @@ public class TextToSpeech {
      */
     public static final int STOPPED = -2;
 
+    /** @hide */
+    @IntDef({ERROR_SYNTHESIS, ERROR_SERVICE, ERROR_OUTPUT, ERROR_NETWORK, ERROR_NETWORK_TIMEOUT,
+             ERROR_INVALID_REQUEST, ERROR_NOT_INSTALLED_YET})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Error {}
+
     /**
      * Denotes a failure of a TTS engine to synthesize the given input.
      */