| /* |
| * Copyright (C) 2009 Google Inc. |
| * |
| * 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.tts; |
| |
| import android.media.AudioManager; |
| import android.media.AudioSystem; |
| import android.util.Log; |
| import java.lang.ref.WeakReference; |
| |
| /** |
| * @hide |
| * |
| * The SpeechSynthesis class provides a high-level api to create and play |
| * synthesized speech. This class is used internally to talk to a native |
| * TTS library that implements the interface defined in |
| * frameworks/base/include/tts/TtsEngine.h |
| * |
| */ |
| @SuppressWarnings("unused") |
| public class SynthProxy { |
| |
| // Default parameters of a filter to be applied when using the Pico engine. |
| // Such a huge filter gain is justified by how much energy in the low frequencies is "wasted" at |
| // the output of the synthesis. The low shelving filter removes it, leaving room for |
| // amplification. |
| private final static float PICO_FILTER_GAIN = 5.0f; // linear gain |
| private final static float PICO_FILTER_LOWSHELF_ATTENUATION = -18.0f; // in dB |
| private final static float PICO_FILTER_TRANSITION_FREQ = 1100.0f; // in Hz |
| private final static float PICO_FILTER_SHELF_SLOPE = 1.0f; // Q |
| |
| // |
| // External API |
| // |
| |
| /** |
| * Constructor; pass the location of the native TTS .so to use. |
| */ |
| public SynthProxy(String nativeSoLib, String engineConfig) { |
| boolean applyFilter = nativeSoLib.toLowerCase().contains("pico"); |
| Log.v(TtsService.SERVICE_TAG, "About to load "+ nativeSoLib + ", applyFilter="+applyFilter); |
| native_setup(new WeakReference<SynthProxy>(this), nativeSoLib, engineConfig); |
| native_setLowShelf(applyFilter, PICO_FILTER_GAIN, PICO_FILTER_LOWSHELF_ATTENUATION, |
| PICO_FILTER_TRANSITION_FREQ, PICO_FILTER_SHELF_SLOPE); |
| } |
| |
| /** |
| * Stops and clears the AudioTrack. |
| */ |
| public int stop() { |
| return native_stop(mJniData); |
| } |
| |
| /** |
| * Synchronous stop of the synthesizer. This method returns when the synth |
| * has completed the stop procedure and doesn't use any of the resources it |
| * was using while synthesizing. |
| * |
| * @return {@link android.speech.tts.TextToSpeech.SUCCESS} or |
| * {@link android.speech.tts.TextToSpeech.ERROR} |
| */ |
| public int stopSync() { |
| return native_stopSync(mJniData); |
| } |
| |
| /** |
| * Synthesize speech and speak it directly using AudioTrack. |
| */ |
| public int speak(String text, int streamType, float volume, float pan) { |
| Log.i(TAG, "speak() on stream "+ streamType); |
| if ((streamType > -1) && (streamType < AudioSystem.getNumStreamTypes())) { |
| return native_speak(mJniData, text, streamType, volume, pan); |
| } else { |
| Log.e("SynthProxy", "Trying to speak with invalid stream type " + streamType); |
| return native_speak(mJniData, text, AudioManager.STREAM_MUSIC, volume, pan); |
| } |
| } |
| |
| /** |
| * Synthesize speech to a file. The current implementation writes a valid |
| * WAV file to the given path, assuming it is writable. Something like |
| * "/sdcard/???.wav" is recommended. |
| */ |
| public int synthesizeToFile(String text, String filename) { |
| Log.i(TAG, "synthesizeToFile() to file "+ filename); |
| return native_synthesizeToFile(mJniData, text, filename); |
| } |
| |
| /** |
| * Queries for language support. |
| * Return codes are defined in android.speech.tts.TextToSpeech |
| */ |
| public int isLanguageAvailable(String language, String country, String variant) { |
| return native_isLanguageAvailable(mJniData, language, country, variant); |
| } |
| |
| /** |
| * Updates the engine configuration. |
| */ |
| public int setConfig(String engineConfig) { |
| return native_setConfig(mJniData, engineConfig); |
| } |
| |
| /** |
| * Sets the language. |
| */ |
| public int setLanguage(String language, String country, String variant) { |
| return native_setLanguage(mJniData, language, country, variant); |
| } |
| |
| /** |
| * Loads the language: it's not set, but prepared for use later. |
| */ |
| public int loadLanguage(String language, String country, String variant) { |
| return native_loadLanguage(mJniData, language, country, variant); |
| } |
| |
| /** |
| * Sets the speech rate. |
| */ |
| public final int setSpeechRate(int speechRate) { |
| return native_setSpeechRate(mJniData, speechRate); |
| } |
| |
| /** |
| * Sets the pitch of the synthesized voice. |
| */ |
| public final int setPitch(int pitch) { |
| return native_setPitch(mJniData, pitch); |
| } |
| |
| /** |
| * Returns the currently set language, country and variant information. |
| */ |
| public String[] getLanguage() { |
| return native_getLanguage(mJniData); |
| } |
| |
| /** |
| * Gets the currently set rate. |
| */ |
| public int getRate() { |
| return native_getRate(mJniData); |
| } |
| |
| /** |
| * Shuts down the native synthesizer. |
| */ |
| public void shutdown() { |
| native_shutdown(mJniData); |
| } |
| |
| // |
| // Internal |
| // |
| |
| protected void finalize() { |
| native_finalize(mJniData); |
| mJniData = 0; |
| } |
| |
| static { |
| System.loadLibrary("ttssynthproxy"); |
| } |
| |
| private final static String TAG = "SynthProxy"; |
| |
| /** |
| * Accessed by native methods |
| */ |
| private int mJniData = 0; |
| |
| private native final int native_setup(Object weak_this, String nativeSoLib, |
| String engineConfig); |
| |
| private native final int native_setLowShelf(boolean applyFilter, float filterGain, |
| float attenuationInDb, float freqInHz, float slope); |
| |
| private native final void native_finalize(int jniData); |
| |
| private native final int native_stop(int jniData); |
| |
| private native final int native_stopSync(int jniData); |
| |
| private native final int native_speak(int jniData, String text, int streamType, float volume, |
| float pan); |
| |
| private native final int native_synthesizeToFile(int jniData, String text, String filename); |
| |
| private native final int native_isLanguageAvailable(int jniData, String language, |
| String country, String variant); |
| |
| private native final int native_setLanguage(int jniData, String language, String country, |
| String variant); |
| |
| private native final int native_loadLanguage(int jniData, String language, String country, |
| String variant); |
| |
| private native final int native_setConfig(int jniData, String engineConfig); |
| |
| private native final int native_setSpeechRate(int jniData, int speechRate); |
| |
| private native final int native_setPitch(int jniData, int speechRate); |
| |
| private native final String[] native_getLanguage(int jniData); |
| |
| private native final int native_getRate(int jniData); |
| |
| private native final void native_shutdown(int jniData); |
| |
| |
| /** |
| * Callback from the C layer |
| */ |
| @SuppressWarnings("unused") |
| private static void postNativeSpeechSynthesizedInJava(Object tts_ref, |
| int bufferPointer, int bufferSize) { |
| |
| Log.i("TTS plugin debug", "bufferPointer: " + bufferPointer |
| + " bufferSize: " + bufferSize); |
| |
| SynthProxy nativeTTS = (SynthProxy)((WeakReference)tts_ref).get(); |
| // TODO notify TTS service of synthesis/playback completion, |
| // method definition to be changed. |
| } |
| } |