Adding support for pitch changes of the synthesized text in Text-To-Speech.
diff --git a/core/java/android/speech/tts/ITts.aidl b/core/java/android/speech/tts/ITts.aidl
index 02211fd4..75c3b30 100755
--- a/core/java/android/speech/tts/ITts.aidl
+++ b/core/java/android/speech/tts/ITts.aidl
@@ -29,6 +29,8 @@
 interface ITts {

     void setSpeechRate(in int speechRate);

 

+    void setPitch(in int pitch);

+

     void speak(in String text, in int queueMode, in String[] params);

 

     boolean isSpeaking();

diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 9fc143d..c064284 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -450,7 +450,6 @@
     }
 
 
-
     /**
      * Sets the speech rate for the TTS engine.
      *
@@ -483,6 +482,37 @@
 
 
     /**
+     * Sets the speech pitch for the TTS engine.
+     *
+     * Note that the pitch is not universally supported by all engines and
+     * will be treated as a hint. The TTS library will try to use the specified
+     * pitch, but there is no guarantee.
+     * This has no effect on any pre-recorded speech.
+     *
+     * @param pitch
+     *            The pitch for the TTS engine. 1 is the normal pitch,
+     *            lower values lower the tone of the synthesized voice,
+     *            greater values increase it.
+     */
+    public void setPitch(float pitch) {
+        synchronized (mStartLock) {
+            if (!mStarted) {
+                return;
+            }
+            try {
+                if (pitch > 0) {
+                    mITts.setPitch((int)(pitch*100));
+                }
+            } catch (RemoteException e) {
+                // TTS died; restart it.
+                mStarted = false;
+                initTts();
+            }
+        }
+    }
+
+
+    /**
      * Sets the language for the TTS engine.
      *
      * Note that the language is not universally supported by all engines and
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 54d038a..0aa4fa5 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -296,7 +296,7 @@
 
 static void
 android_tts_SynthProxy_setSpeechRate(JNIEnv *env, jobject thiz, jint jniData,
-        int speechRate)
+        jint speechRate)
 {
     if (jniData == 0) {
         LOGE("android_tts_SynthProxy_setSpeechRate(): invalid JNI data");
@@ -316,6 +316,28 @@
 }
 
 
+static void
+android_tts_SynthProxy_setPitch(JNIEnv *env, jobject thiz, jint jniData,
+        jint pitch)
+{
+    if (jniData == 0) {
+        LOGE("android_tts_SynthProxy_setPitch(): invalid JNI data");
+        return;
+    }
+
+    int bufSize = 10;
+    char buffer [bufSize];
+    sprintf(buffer, "%d", pitch);
+
+    SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
+    LOGI("setting pitch to %d", pitch);
+    // TODO check return codes
+    if (pSynthData->mNativeSynthInterface) {
+        pSynthData->mNativeSynthInterface->setProperty("pitch", buffer, bufSize);
+    }
+}
+
+
 // TODO: Refactor this to get rid of any assumptions about sample rate, etc.
 static void
 android_tts_SynthProxy_synthesizeToFile(JNIEnv *env, jobject thiz, jint jniData,
@@ -541,6 +563,10 @@
         "(II)V",
         (void*)android_tts_SynthProxy_setSpeechRate
     },
+    {   "native_setPitch",
+        "(II)V",
+        (void*)android_tts_SynthProxy_setPitch
+    },
     {   "native_playAudioBuffer",
         "(III)V",
         (void*)android_tts_SynthProxy_playAudioBuffer
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index 364dc58..3bdff37 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -81,6 +81,12 @@
         native_setSpeechRate(mJniData, speechRate);
     }
 
+    /**
+     * Sets the pitch of the synthesized voice
+     */
+    public final void setPitch(int pitch) {
+        native_setPitch(mJniData, pitch);
+    }
 
     /**
      * Plays the given audio buffer
@@ -145,6 +151,8 @@
             String variant);
 
     private native final void native_setSpeechRate(int jniData, int speechRate);
+    
+    private native final void native_setPitch(int jniData, int speechRate);
 
     // TODO add buffer format
     private native final void native_playAudioBuffer(int jniData, int bufferPointer, int bufferSize);
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index e9c4ab7..21f56f8 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -152,7 +152,6 @@
         // speech rate
         setSpeechRate(getDefaultRate());
 
-        // TODO handle default pitch
     }
 
 
@@ -179,6 +178,12 @@
         }
     }
 
+
+    private void setPitch(int pitch) {
+        nativeSynth.setPitch(pitch);
+    }
+
+
     private void setLanguage(String lang, String country, String variant) {
         Log.v("TTS", "TtsService.setLanguage("+lang+", "+country+", "+variant+")");
         if (isDefaultEnforced()) {
@@ -706,6 +711,17 @@
         }
 
         /**
+         * Sets the pitch for the TTS. Note that this will only have an
+         * effect on synthesized speech; it will not affect pre-recorded speech.
+         *
+         * @param pitch
+         *            The pitch that should be used for the synthesized voice
+         */
+        public void setPitch(int pitch) {
+            mSelf.setPitch(pitch);
+        }
+
+        /**
          * Sets the speech rate for the TTS, which affects the synthesized voice.
          *
          * @param lang  the three letter ISO language code.