com_svox_picottsengine.cpp revision 39358f0dacad8cece6c2d3ef1055030f57090c79
139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/* com_svox_picottsengine.cpp 239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 3b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland 4b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 5b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Licensed under the Apache License, Version 2.0 (the "License"); 6b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * you may not use this file except in compliance with the License. 7b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * You may obtain a copy of the License at 8b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 9b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * http://www.apache.org/licenses/LICENSE-2.0 10b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 11b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Unless required by applicable law or agreed to in writing, software 12b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * distributed under the License is distributed on an "AS IS" BASIS, 13b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * See the License for the specific language governing permissions and 15b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * limitations under the License. 1639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 1739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi This is the Manager layer. It sits on top of the native Pico engine 1839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi and provides the interface to the defined Google TTS engine API. 1939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi The Google engine API is the boundary to allow a TTS engine to be swapped. 2039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi The Manager layer also provide the SSML tag interpretation. 2139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi The supported SSML tags are mapped to corresponding tags natively supported by Pico. 2239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Native Pico functions always begin with picoXXX. 2339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 2439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi In the Pico engine, the language cannot be changed indpendently of the voice. 2539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If either the voice or locale/language are changed, a new resource is loaded. 2639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 2739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Only a subset of SSML 1.0 tags are supported. 2839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Some SSML tags involve significant complexity. 2939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If the language is changed through an SSML tag, there is a latency for the load. 3039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 3139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi History: 3239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 2009-07-01 -- clean up & documentation 3339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 2009-06-29 -- integrated SSML parser and IPA to XSAMPA conversion 3439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 2009-06-29 -- revised for C90 compliance 3539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 2009-06-04 -- updated for new TtsEngine interface 3639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 2009-05-18 -- initial version 3739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 3839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 3939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ToDo: 4039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi - duplicate 'phoneme ph=' *** 4139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi - normalize IPA strings ** 4239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi - change voice as well as language * 4339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Changing of voice/language is complex due to potentially multiple swaps 4439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi under SSML and the latent effects. This requires storing a history of tags/sets. 45b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */ 46b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdio.h> 48b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <unistd.h> 49b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define LOG_TAG "SVOX Pico Engine" 51b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 52b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <utils/Log.h> 5339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include <utils/String16.h> /* for strlen16 */ 54b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <android_runtime/AndroidRuntime.h> 55b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <tts/TtsEngine.h> 5639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include <cutils/jstring.h> 57b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <picoapi.h> 58b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <picodefs.h> 5939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include "svox_ssml_parser.h" 60b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 61b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenusing namespace android; 62b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 63b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* adaptation layer defines */ 644eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi#define PICO_MEM_SIZE 2500000 6554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking rate */ 6639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_RATE 20 67b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_RATE 500 6839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_DEF_RATE 100 6954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking pitch */ 7039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_PITCH 50 71b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_PITCH 200 7239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_DEF_PITCH 100 7354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking volume */ 7439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_VOLUME 0 75b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_VOLUME 500 7639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_DEF_VOLUME 250 7739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 7854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* string constants */ 79b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define MAX_OUTBUF_SIZE 128 8039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_LINGWARE_PATH = "/sdcard/svox/"; 8139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOICE_NAME = "PicoVoice"; 8239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_SPEED_OPEN_TAG = "<speed level='%d'>"; 8339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_SPEED_CLOSE_TAG = "</speed>"; 8439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PITCH_OPEN_TAG = "<pitch level='%d'>"; 8539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PITCH_CLOSE_TAG = "</pitch>"; 8639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOLUME_OPEN_TAG = "<volume level='%d'>"; 8739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOLUME_CLOSE_TAG = "</volume>"; 8839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PHONEME_OPEN_TAG = "<phoneme ph='"; 8939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 9039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/* supported voices 9139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Pico does not seperately specify the voice and locale. */ 9239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedLangIso3[] = { "eng", "eng", "deu", "spa", "fra", "ita" }; 9339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedCountryIso3[] = { "USA", "GBR", "DEU", "ESP", "FRA", "ITA" }; 9439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedLang[] = { "en-rUS", "en-rGB", "de-rDE", "es-rES", "fr-rFR", "it-rIT" }; 9539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoInternalLang[] = { "en-US", "en-GB", "de-DE", "es-ES", "fr-FR", "it-IT" }; 9639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoInternalTaLingware[] = { "en-US_ta.bin", "en-GB_ta.bin", "de-DE_ta.bin", "es-ES_ta.bin", "fr-FR_ta.bin", "it-IT_ta.bin" }; 9739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoInternalSgLingware[] = { "en-US_lh0_sg.bin", "en-GB_kh0_sg.bin", "de-DE_gl0_sg.bin", "es-ES_zl0_sg.bin", "fr-FR_nk0_sg.bin", "it-IT_cm0_sg.bin" }; 9839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoInternalUtppLingware[] = { "en-US_utpp.bin", "en-GB_utpp.bin", "de-DE_utpp.bin", "es-ES_utpp.bin", "fr-FR_utpp.bin", "it-IT_utpp.bin" }; 9939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst int picoNumSupportedVocs = 6; 100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 10154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* supported properties */ 10239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedProperties[] = { "language", "rate", "pitch", "volume" }; 10339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst int picoNumSupportedProperties = 4; 104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 10554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 10654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* adapation layer global variables */ 10739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TrivisynthDoneCB_t * picoSynthDoneCBPtr; 10839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivivoid * picoMemArea = NULL; 10939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_System picoSystem = NULL; 11039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoTaResource = NULL; 11139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoSgResource = NULL; 11239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoUtppResource = NULL; 11339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Engine picoEngine = NULL; 11439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoTaFileName = NULL; 11539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoSgFileName = NULL; 11639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoUtppFileName = NULL; 11739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoTaResourceName = NULL; 11839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoSgResourceName = NULL; 11939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoUtppResourceName = NULL; 12054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoSynthAbort = 0; 12139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivichar * picoProp_currLang = NULL; /* current language */ 12254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currRate = PICO_DEF_RATE; /* current rate */ 12354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currPitch = PICO_DEF_PITCH; /* current pitch */ 12454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currVolume = PICO_DEF_VOLUME; /* current volume */ 12554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1269b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Triviint picoCurrentLangIndex = -1; 127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* internal helper functions */ 130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 13139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** checkForLocale 13239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Check whether the requested locale is among the supported locales. 13339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @locale - the locale to check, either in xx or xx-rYY format 13439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return index of the locale, or -1 if not supported. 135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 13639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic int checkForLocale( const char * locale ) 137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 13854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi int found = -1; /* language not found */ 13939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int i; 14039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (locale == NULL) { 14139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("checkForLanguage called with NULL language"); 14239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return found; 14339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 14454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 14554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Verify that the requested locale is a locale that we support. */ 14639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) 147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 14839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (strcmp(locale, picoSupportedLang[i]) == 0) /* in array */ 149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen found = i; 151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 15354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi }; 15439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 15539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* The locale was not found. */ 156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (found < 0) 157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 15854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* We didn't find an exact match; it may have been specified with only the first 2 characters. 15939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi This could overmatch ISO 639-3 language codes.%% */ 16039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) 161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 16239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (strncmp(locale, picoSupportedLang[i], 2) == 0) 163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen found = i; 165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (found < 0) 169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 17039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("TtsEngine::set language called with unsupported locale"); 171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 17254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi }; 173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return found; 174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 17654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** cleanResources 17854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Unloads any loaded Pico resources. 179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 18054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivistatic void cleanResources( void ) 181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoEngine) 183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 18454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_disposeEngine( picoSystem, &picoEngine ); 18539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_releaseVoiceDefinition( picoSystem, (pico_Char *) PICO_VOICE_NAME ); 186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoEngine = NULL; 187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoUtppResource) 189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 19054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoUtppResource ); 191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppResource = NULL; 192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoTaResource) 194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 19554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoTaResource ); 196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaResource = NULL; 197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoSgResource) 199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 20054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoSgResource ); 201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgResource = NULL; 202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2039b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi picoCurrentLangIndex = -1; 204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 20654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** cleanFiles 20854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Frees any memory allocated for file and resource strings. 209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 21054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivistatic void cleanFiles( void ) 211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoProp_currLang) 213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 21439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoProp_currLang ); 215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currLang = NULL; 216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2174eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoTaFileName) 219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 22039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoTaFileName ); 221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaFileName = NULL; 222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2234eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoSgFileName) 225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 22639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoSgFileName ); 227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgFileName = NULL; 228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2294eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoUtppFileName) 231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 23239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoUtppFileName ); 233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppFileName = NULL; 234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2354eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoTaResourceName) 237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 23839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoTaResourceName ); 239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaResourceName = NULL; 240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2414eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoSgResourceName) 243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 24439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoSgResourceName ); 245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgResourceName = NULL; 246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2474eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoUtppResourceName) 249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 25039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoUtppResourceName ); 251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppResourceName = NULL; 252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 2559b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi/** hasResourcesForLanguage 2569b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * Check to see if the resources required to load the language at the specified index 2579b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * are properly installed 2589b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @langIndex - the index of the language to check the resources for. The index is valid. 2599b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return true if the required resources are installed, false otherwise 2609b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi */ 2619b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivistatic bool hasResourcesForLanguage(int langIndex) { 2629b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi FILE * pFile; 2639b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi char* fileName = (char*)malloc(PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE); 2649b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 2659b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy((char*)fileName, PICO_LINGWARE_PATH); 2669b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcat((char*)fileName, (const char*)picoInternalTaLingware[langIndex]); 2679b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi pFile = fopen(fileName,"r"); 2689b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (pFile == NULL){ 2699b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2709b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return false; 2719b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 2729b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi fclose (pFile); 2739b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 2749b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 2759b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy((char*)fileName, PICO_LINGWARE_PATH); 2769b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcat((char*)fileName, (const char*)picoInternalSgLingware[langIndex]); 2779b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi pFile = fopen(fileName, "r"); 2789b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (pFile == NULL) { 2799b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2809b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return false; 2819b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 2829b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi fclose(pFile); 2839b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2849b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return true; 2859b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 2869b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi} 2879b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 2884eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi/** doLanguageSwitchFromLangIndex 28939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Switch to the requested locale. 29039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If the locale is already loaded, it returns immediately. 29139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If another locale is already is loaded, it will first be unloaded and the new one then loaded. 29239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If no locale is loaded, the requested locale will be loaded. 29339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @langIndex - the index of the locale/voice to load, which is guaranteed to be supported. 294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return TTS_SUCCESS or TTS_FAILURE 2954eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi */ 29639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic tts_result doLanguageSwitchFromLangIndex( int langIndex ) 297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 29839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int ret; /* function result code */ 29939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 30039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* If we already have a loaded locale, check whether it is the same one as requested. */ 301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoProp_currLang && (strcmp(picoProp_currLang, picoSupportedLang[langIndex]) == 0)) 302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 3034eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGI("Language already loaded (%s == %s)", picoProp_currLang, picoSupportedLang[langIndex]); 304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 30739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* It is not the same locale; unload the current one first. */ 308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 3094eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 31039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Allocate memory for file and resource names. */ 311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 31239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoProp_currLang = (char *) malloc( 10 ); 31339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoTaFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 31439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSgFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 31539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoUtppFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 31639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoTaResourceName = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 31739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSgResourceName = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 31839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoUtppResourceName =(pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 31939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 32039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set the path and file names for resource files. */ 32139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy((char *) picoTaFileName, PICO_LINGWARE_PATH); 32239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoTaFileName, (const char *) picoInternalTaLingware[langIndex]); 32339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy((char *) picoSgFileName, PICO_LINGWARE_PATH); 32439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoSgFileName, (const char *) picoInternalSgLingware[langIndex]); 32539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy((char *) picoUtppFileName, PICO_LINGWARE_PATH); 32639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoUtppFileName, (const char *) picoInternalUtppLingware[langIndex]); 32739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 32839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the text analysis Lingware resource file. */ 32939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoTaFileName, &picoTaResource ); 330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 3324eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load textana resource for %s [%d]", picoSupportedLang[langIndex], ret); 333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 336b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3374eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 33839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the signal generation Lingware resource file. */ 33939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoSgFileName, &picoSgResource ); 340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 341b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 3424eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load siggen resource for %s [%d]", picoSupportedLang[langIndex], ret); 343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3474eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 34839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the utpp Lingware resource file if exists - NOTE: this file is optional 34939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi and is currently not used. Loading is only attempted for future compatibility. 35039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If this file is not present the loading will still succeed. */ 35139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoUtppFileName, &picoUtppResource ); 35239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if ((PICO_OK != ret) && (ret != PICO_EXC_CANT_OPEN_FILE)) 35339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 3544eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load utpp resource for %s [%d]", picoSupportedLang[langIndex], ret); 355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 35839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 3594eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 36039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the text analysis resource name. */ 36139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoTaResource, (char *) picoTaResourceName ); 362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 3644eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get textana resource name for %s [%d]", picoSupportedLang[langIndex], ret); 365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3694eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 37039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the signal generation resource name. */ 37139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoSgResource, (char *) picoSgResourceName ); 372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK == ret && picoUtppResource != NULL) 373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 37439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get utpp resource name - optional: see note above. */ 37539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoUtppResource, (char *) picoUtppResourceName ); 376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 3784eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get utpp resource name for %s [%d]", picoSupportedLang[langIndex], ret); 379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 3864eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get siggen resource name for %s [%d]", picoSupportedLang[langIndex], ret); 387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3914eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 39239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Create a voice definition. */ 39339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_createVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME ); 394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 3964eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to create voice for %s [%d]", picoSupportedLang[langIndex], ret); 397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4014eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 40239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add the text analysis resource to the voice. */ 40339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoTaResourceName ); 404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 4064eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add textana resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4114eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 41239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add the signal generation resource to the voice. */ 41339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoSgResourceName ); 414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK == ret && picoUtppResource != NULL) 415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 41639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add utpp resource to voice - optional: see note above. */ 41739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoUtppResourceName ); 418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 4204eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add utpp resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4264eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 4294eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add siggen resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 43539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_newEngine( picoSystem, (const pico_Char *) PICO_VOICE_NAME, &picoEngine ); 436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 4384eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to create engine for %s [%d]", picoSupportedLang[langIndex], ret); 439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 442b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4434eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 44439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set the current locale/voice. */ 44539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy( picoProp_currLang, picoSupportedLang[langIndex] ); 446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGI("loaded %s successfully", picoProp_currLang); 447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 45039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 4514eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi/** doLanguageSwitch 45239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Switch to the requested locale. 45339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If this locale is already loaded, it returns immediately. 45439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If another locale is already loaded, this will first be unloaded 45539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * and the new one then loaded. 45639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If no locale is loaded, the requested will be loaded. 45739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @locale - the locale to check, either in xx or xx-rYY format (i.e "en" or "en-rUS") 4584eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi * return TTS_SUCCESS or TTS_FAILURE 4594eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi*/ 46039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic tts_result doLanguageSwitch( const char * locale ) 4614eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi{ 46239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int loclIndex; /* locale index */ 4634eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 46439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the new locale. */ 46539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi loclIndex = checkForLocale( locale ); 46639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (loclIndex < 0) 46739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 46839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Tried to swith to non-supported locale %s", locale); 46939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 47039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 47139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGI("Found supported locale %s", picoSupportedLang[loclIndex]); 47239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return doLanguageSwitchFromLangIndex( loclIndex ); 4734eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi} 4744eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 47539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** doAddProperties 47739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Add <speed>, <pitch> and <volume> tags to the text, 47839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * if the properties have been set to non-default values, and return the new string. 47939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The calling function is responsible for freeing the returned string. 480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @str - text to apply tags to 481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return new string with tags applied 482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 48339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic char * doAddProperties( const char * str ) 484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 48539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * data = NULL; 48639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int haspitch, hasspeed, hasvol; /* parameters */ 48739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int textlen; /* property string length */ 4884eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 48939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi haspitch = 0; hasspeed = 0; hasvol = 0; 49039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi textlen = strlen(str) + 1; 49154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi if (picoProp_currPitch != PICO_DEF_PITCH) /* non-default pitch */ 492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_PITCH_OPEN_TAG) + 5; 494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_PITCH_CLOSE_TAG); 495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen haspitch = 1; 496b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 49754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi if (picoProp_currRate != PICO_DEF_RATE) /* non-default rate */ 498b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_SPEED_OPEN_TAG) + 5; 500b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_SPEED_CLOSE_TAG); 501b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hasspeed = 1; 502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 50354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi if (picoProp_currVolume != PICO_DEF_VOLUME) /* non-default volume */ 504b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_VOLUME_OPEN_TAG) + 5; 506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_VOLUME_CLOSE_TAG); 507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hasvol = 1; 508b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5094eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 51039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Compose the property strings. */ 51139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi data = (char *) malloc( textlen ); /* allocate string */ 512b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (!data) 513b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 514b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return NULL; 515b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 51654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi memset(data, 0, textlen); /* clear it */ 517b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (haspitch) 518b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 519b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_PITCH_OPEN_TAG) + strlen(PICO_PITCH_CLOSE_TAG) + 5); 520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_PITCH_OPEN_TAG, picoProp_currPitch); 521b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 522b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 523b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5244eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (hasspeed) 526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 527b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_SPEED_OPEN_TAG) + strlen(PICO_SPEED_CLOSE_TAG) + 5); 528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_SPEED_OPEN_TAG, picoProp_currRate); 529b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 530b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 531b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5324eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 533b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (hasvol) 534b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_VOLUME_OPEN_TAG) + strlen(PICO_VOLUME_CLOSE_TAG) + 5); 536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_VOLUME_OPEN_TAG, picoProp_currVolume); 537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 539b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5404eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, str); 5424eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (hasvol) 544b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 545b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_VOLUME_CLOSE_TAG); 546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5474eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (hasspeed) 549b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 550b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_SPEED_CLOSE_TAG); 551b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5524eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (haspitch) 554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 555b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_PITCH_CLOSE_TAG); 556b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5574eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 558b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return data; 559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 560b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 56154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 56239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** createPhonemeString 56339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Wrap all individual words in <phoneme> tags. 56439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The Pico <phoneme> tag only supports one word in each tag, 56539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * therefore they must be individually wrapped! 56639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @xsampa - text to convert to Pico phomene string 56739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @length - length of the input string 56839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return new string with tags applied 56939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 57039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic char * createPhonemeString( const char * xsampa, int length ) 57139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 57239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * convstring = NULL; 57339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int origStrLen = strlen(xsampa); 57439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int numWords = 1; 57539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int start, totalLength, i, j; 57639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 57739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = 0; i < origStrLen; i ++) 57839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 57939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (xsampa[i] == ' ') 58039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi numWords ++; 58139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 58239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 58339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (numWords == 1) 58439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 58539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi convstring = new char[origStrLen + 17]; 58639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi convstring[0] = '\0'; 58739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(convstring, "<phoneme ph='"); 58839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(convstring, xsampa); 58939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(convstring, "'/>"); 59039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 59139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi else 59239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 59339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * words[numWords]; 59439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi start = 0; totalLength = 0; i = 0; j = 0; 59539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i=0, j=0; i < origStrLen; i ++) 59639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 59739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (xsampa[i] == ' ') 59839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 59939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi words[j] = new char[i+1-start+17]; 60039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi words[j][0] = '\0'; 60139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat( words[j], "<phoneme ph='"); 60239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strncat(words[j], xsampa+start, i-start); 60339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat( words[j], "'/>"); 60439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi start = i + 1; 60539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi j ++; 60639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi totalLength += strlen(words[j-1]); 60739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 60839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 60939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi words[j] = new char[i+1-start+17]; 61039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi words[j][0] = '\0'; 61139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(words[j], "<phoneme ph='"); 61239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(words[j], xsampa+start); 61339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(words[j], "'/>"); 61439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi totalLength += strlen(words[j]); 61539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi convstring = new char[totalLength + 1]; 61639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi convstring[0] = '\0'; 61739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i=0; i < numWords; i ++) 61839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 61939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(convstring, words[i]); 62039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi delete [] words[i]; 62139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 62239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 62339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return convstring; 62439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 62539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 62639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 62739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/* The XSAMPA uses as many as 4 characters to represent a single IPA code. */ 62839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitypedef struct tagPhnArr 62939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 63039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char16_t strIPA; /* IPA Unicode symbol */ 63139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char strXSAMPA[5]; /* SAMPA sequence */ 63239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } PArr; 63339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 63439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define phn_cnt (133) 63539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 63639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TriviPArr PhnAry[phn_cnt] = { 63739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 63839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* XSAMPA conversion table */ 63939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 64039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Vowels (23) complete */ 64139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025B, "E"}, 64239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0251, "A"}, 64339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0254, "O"}, 64439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00F8, "2"}, 64539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0153, "9"}, 64639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0276, "&"}, 64739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0252, "Q"}, 64839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028C, "V"}, 64939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0264, "7"}, 65039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026F, "M"}, 65139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0268, "1"}, 65239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0289, "}"}, 65339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026A, "I"}, 65439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028F, "Y"}, 65539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028A, "U"}, 65639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0259, "@"}, 65739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0275, "8"}, 65839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0250, "6"}, 65939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00E6, "{"}, 66039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025C, "3"}, 66139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025A, "@'"}, 66239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025E, "3\\"}, 66339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0258, "@\\"}, 66439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 66539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Consonants (60) complete */ 66639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0288, "t'"}, 66739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0256, "d'"}, 66839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025F, "J\\"}, 66939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0261, "g"}, 67039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0262, "G\\"}, 67139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0294, "?"}, 67239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0271, "F"}, 67339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0273, "n'"}, 67439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0272, "J"}, 67539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x014B, "N"}, 67639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0274, "N\\"}, 67739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0299, "B\\"}, 67839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0280, "R\\"}, 67939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x027E, "4"}, 68039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x027D, "r'"}, 68139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0278, "p\\"}, 68239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03B2, "B"}, 68339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03B8, "T"}, 68439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00F0, "D"}, 68539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0283, "S"}, 68639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0292, "Z"}, 68739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0282, "s'"}, 68839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0290, "z'"}, 68939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00E7, "C"}, 69039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x029D, "j\\"}, 69139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0263, "G"}, 69239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03C7, "X"}, 69339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0281, "R"}, 69439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0127, "X\\"}, 69539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0295, "?\\"}, 69639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0266, "h\\"}, 69739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026C, "K"}, 69839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026E, "K\\"}, 69939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028B, "P"}, 70039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0279, "r\\"}, 70139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x027B, "r\\'"}, 70239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0270, "M\\"}, 70339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026D, "l'"}, 70439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028E, "L"}, 70539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x029F, "L\\"}, 70639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0253, "b_<"}, 70739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0257, "d_<"}, 70839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0284, "J\\_<"}, 70939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0260, "g_<"}, 71039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x029B, "G\\_<"}, 71139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028D, "W"}, 71239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0265, "H"}, 71339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x029C, "H\\"}, 71439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A1, ">\\"}, 71539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A2, "<\\"}, 71639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0298, "O\\"}, 71739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x01C0, "|\\"}, 71839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x01C3, "!\\"}, 71939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x01C2, "=\\"}, 72039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x01C1, "|\\|\\"}, 72139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x027A, "l\\"}, 72239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0255, "s\\"}, 72339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0291, "z\\"}, 72439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0267, "x\\"}, 72539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026B, "l_G"}, 72639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 72739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Diacritics (34) */ 72839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02BC, "_>"}, 72939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0325, "_0"}, 73039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x030A, "_0"}, 73139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x032C, "_v"}, 73239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B0, "_h"}, 73339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0324, "_t"}, 73439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0330, "_k"}, 73539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033C, "_N"}, 73639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x032A, "_d"}, 73739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033A, "_a"}, 73839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033B, "_m"}, 73939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0339, "_O"}, 74039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031C, "_c"}, 74139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031F, "_+"}, 74239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0320, "_-"}, 74339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0308, "_"}, /* centralized %% */ 74439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033D, "_x"}, 74539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0318, "_A"}, 74639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0319, "_q"}, 74739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02DE, "'"}, 74839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B7, "_w"}, 74939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B2, "_j"}, 75039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02E0, "_G"}, 75139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02E4, "_?\\"}, 75239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0303, "~"}, 75339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x207F, "_n"}, 75439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02E1, "_l"}, 75539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031A, "_}"}, 75639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0334, "_e"}, 75739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031D, "_r"}, 75839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031E, "_o"}, 75939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0329, "="}, 76039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x032F, "_^"}, 76139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02D0, ":"}, 76239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 76339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Others (10) incomplete%% */ 76439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0361, "_"}, 76539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x035C, "_"}, 76639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02C8, ""}, 76739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02CC, "%"}, 76839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02D1, ":\\"}, 76939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0306, "_X"}, 77039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x2016, "||"}, 77139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x203F, "-\\"}, 77239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x2197, "<R>"}, 77339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x2198, "<F>"}, 77439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 77539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Affricates (6) complete */ 77639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A3, "d_z"}, 77739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A4, "d_Z"}, 77839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A5, "d_z\\"}, 77939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A6, "t_s"}, 78039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A7, "t_S"}, 78139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A8, "t_s\\"} 78239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi }; 78339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 78439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 78539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivivoid CnvIPAPnt( const char16_t IPnt, char * XPnt ) 78639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 78739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char16_t ThisPnt = IPnt; /* local copy of single IPA codepoint */ 78839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int idx; /* index into table */ 78939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 79039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Convert an individual IPA codepoint. 79139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi A single IPA code could map to a string. 79239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Search the table. If it is not found, use the same character. 79339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Since most codepoints can be contained within 16 bits, 79439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi they are represented as wide chars. */ 79539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi XPnt[0] = 0; /* clear the result string */ 79639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 79739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Search the table for the conversion. */ 79839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (idx = 0; idx < phn_cnt; idx ++) /* for each item in table */ 79939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (IPnt == PhnAry[idx].strIPA) /* matches IPA code */ 80039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 80139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat( XPnt, (const char *)&(PhnAry[idx].strXSAMPA) ); /* copy the XSAMPA string */ 80239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return; 80339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 80439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(XPnt, (const char *)&ThisPnt); /* just copy it */ 80539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 80639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 80739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 80839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** cnvIpaToXsampa 80939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Convert an IPA character string to an XSAMPA character string. 81039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @ipaString - input IPA string to convert 81139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @outXsampaString - converted XSAMPA string is passed back in this parameter 81239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return size of the new string 81339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 81439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviint cnvIpaToXsampa( const char16_t * ipaString, char ** outXsampaString ) 81539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 81639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi size_t xsize; /* size of result */ 81739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi size_t ilen; /* input length */ 81839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int ipidx; /* index into IPA string */ 81939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * XPnt; /* short XSAMPA char sequence */ 82039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 82139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Convert an IPA string to an XSAMPA string and store the xsampa string in *outXsampaString. 82239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi It is the responsibility of the caller to free the allocated string. 82339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Increment through the string. For each base & combination convert it to the XSAMP equivalent. 82439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Because of the XSAMPA limitations, not all IPA characters will be covered. */ 82539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi XPnt = (char *) malloc(6); 82639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi xsize = (4 * strlen16(ipaString)) + 8; /* assume more than double size */ 82739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 82839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi *outXsampaString = (char *) malloc( xsize ); /* allocate return string */ 82939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi *outXsampaString[0] = 0; 83039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi xsize = 0; /* clear final */ 83139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ilen = strlen16(ipaString); /* length of input UTF-16 */ 83239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (ipidx = 0; ipidx < ilen; ipidx ++) /* for each IPA code */ 83339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 83439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi CnvIPAPnt( ipaString[ipidx], XPnt ); /* get converted string */ 83539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *)*outXsampaString, XPnt ); /* concatenate XSAMPA */ 83639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi }; 83739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free(XPnt); 83839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi xsize = strlen(*outXsampaString); /* get the final length */ 83939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return xsize; 84039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 84139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 84239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 84339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 84439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/* Google Engine API function implementations */ 845b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 846b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** init 84739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Allocates Pico memory block and initializes the Pico system. 848b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * synthDoneCBPtr - Pointer to callback function which will receive generated samples 849b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 850b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 85154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::init( synthDoneCB_t synthDoneCBPtr ) 852b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 853b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (synthDoneCBPtr == NULL) 854b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 855b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Callback pointer is NULL"); 856b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 857b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 8584eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 85939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoMemArea = malloc( PICO_MEM_SIZE ); 860b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (!picoMemArea) 861b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 862b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Failed to allocate memory for Pico system"); 863b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 864b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 8654eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 86639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Status ret = pico_initialize( picoMemArea, PICO_MEM_SIZE, &picoSystem ); 867b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (PICO_OK != ret) 868b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 869b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Failed to initialize Pico system"); 87039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoMemArea ); 871b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoMemArea = NULL; 872b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 873b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 8744eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 875b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthDoneCBPtr = synthDoneCBPtr; 8769b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 8779b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi picoCurrentLangIndex = -1; 8789b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 879b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 880b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 881b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 88254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 883b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** shutdown 88454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Unloads all Pico resources; terminates Pico system and frees Pico memory block. 885b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 886b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 88754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::shutdown( void ) 888b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 889b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 8904eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 891b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoSystem) 892b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 893b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen pico_terminate(&picoSystem); 894b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSystem = NULL; 895b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 896b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoMemArea) 897b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 898b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(picoMemArea); 899b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoMemArea = NULL; 900b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 9014eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 902b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 903b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 904b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 905b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 90639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 90739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** loadLanguage 90839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Load a new language. 90939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @lang - string with ISO 3 letter language code. 91039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @country - string with ISO 3 letter country code . 91139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 91239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return tts_result 91339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 91439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::loadLanguage(const char *lang, const char *country, const char *variant) 91539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 91639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 91739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi //return setProperty("language", value, size); 91839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 91939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 92039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 92139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** setLanguage 92239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Load a new language (locale). Use the ISO 639-3 language codes. 92339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @lang - string with ISO 639-3 language code. 92439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @country - string with ISO 3 letter country code. 92539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 92639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return tts_result 92739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi */ 92839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::setLanguage( const char * lang, const char * country, const char * variant ) 92939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 93039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int langIndex; 93139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int countryIndex; 93239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int i; 93339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 93439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (lang == NULL) 93539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 93639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("TtsEngine::setLanguage called with NULL language"); 93739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 93839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 93939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 94039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We look for a match on the language first 94139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi then we look for a match on the country. 94239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If no match on the language: 94339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return an error. 94439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If match on the language, but no match on the country: 94539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi load the language found for the language match. 94639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If match on the language, and match on the country: 94739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi load the language found for the country match. */ 94839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 94939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Find a match on the language. */ 95039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = -1; /* no match */ 95139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) 95239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 95339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (strcmp(lang, picoSupportedLangIso3[i]) == 0) 95439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 95539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = i; 95639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi break; 95739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 95839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 95939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (langIndex < 0) 96039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 96139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* The language isn't supported. */ 96239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("TtsEngine::setLanguage called with unsupported language"); 96339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 96439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 96539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 96639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Find a match on the country, if there is one. */ 96739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (country != NULL) 96839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 96939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi countryIndex = -1; 97039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = langIndex; i < picoNumSupportedVocs; i ++) 97139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 97239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if ( (strcmp(lang, picoSupportedLangIso3[i]) == 0) 97339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi && (strcmp(country, picoSupportedCountryIso3[i]) == 0)) 97439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 97539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi countryIndex = i; 97639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi break; 97739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 97839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 97939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 98039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (countryIndex < 0) 98139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 98239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We didn't find a match on the country, but we had a match on the language. 98339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Use that language. */ 98439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGI("TtsEngine::setLanguage found matching language(%s) but not matching country(%s).", 98539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi lang, country); 98639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 98739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi else 98839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 98939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We have a match on both the language and the country. */ 99039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = countryIndex; 99139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 99239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 99339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 99439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return doLanguageSwitchFromLangIndex( langIndex ); /* switch the language */ 99539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 99639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 99739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 998b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi/** isLanguageAvailable 999b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * Returns the level of support for a language. 1000b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @lang - string with ISO 3 letter language code. 1001b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @country - string with ISO 3 letter country code . 1002b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 10039b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return tts_support_result 1004b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi*/ 1005b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivitts_support_result TtsEngine::isLanguageAvailable(const char *lang, const char *country, 1006b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi const char *variant) { 10079b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int langIndex = -1; 10089b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int countryIndex = -1; 10099b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi //------------------------- 10109b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // language matching 10119b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // if no language specified 10129b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (lang == NULL) { 10139b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi LOGE("TtsEngine::isLanguageAvailable called with no language"); 10149b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_LANG_NOT_SUPPORTED; 10159b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10169b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 10179b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // find a match on the language 101839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (int i = 0; i < picoNumSupportedVocs; i++) 10199b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi { 10209b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (strcmp(lang, picoSupportedLangIso3[i]) == 0) { 10219b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi langIndex = i; 10229b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi break; 10239b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10249b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10259b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (langIndex < 0) { 10269b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // language isn't supported 10279b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi LOGV("TtsEngine::isLanguageAvailable called with unsupported language"); 10289b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_LANG_NOT_SUPPORTED; 10299b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10309b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 10319b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi //------------------------- 10329b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // country matching 10339b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // if no country specified 10349b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if ((country == NULL) || (strlen(country) == 0)) { 10359b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language 10369b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_AVAILABLE : TTS_LANG_MISSING_DATA); 10379b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 1038b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi 10399b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // find a match on the country 104039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (int i = langIndex; i < picoNumSupportedVocs; i++) { 10419b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if ((strcmp(lang, picoSupportedLangIso3[i]) == 0) 10429b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi && (strcmp(country, picoSupportedCountryIso3[i]) == 0)) { 10439b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi countryIndex = i; 10449b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi break; 10459b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10469b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10479b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (countryIndex < 0) { 10489b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // we didn't find a match on the country, but we had a match on the language 10499b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language 10509b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_AVAILABLE : TTS_LANG_MISSING_DATA); 10519b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 10529b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // we have a match on the language and the country 10539b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi langIndex = countryIndex; 10549b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language + country 10559b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_COUNTRY_AVAILABLE : TTS_LANG_MISSING_DATA); 10569b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10579b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 10589b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // no variants supported in this library, TTS_LANG_COUNTRY_VAR_AVAILABLE cannot be returned. 1059b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi} 1060b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi 10614eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1062b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** getLanguage 106354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Get the currently loaded language - if any. 10649b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @lang - string with current ISO 3 letter language code, empty string if no loaded language. 10659b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @country - string with current ISO 3 letter country code, empty string if no loaded language. 10669b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @variant - string with current language variant, empty string if no loaded language. 1067b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1068b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 10699b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivitts_result TtsEngine::getLanguage(char *language, char *country, char *variant) 10709b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi{ 10719b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (picoCurrentLangIndex == -1) { 10729b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(language, "\0"); 10739b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(country, "\0"); 10749b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(variant, "\0"); 10759b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 10765f6105e73f0c74acd10126175d4952ade10a0b05Jean-Michel Trivi strcpy(language, picoSupportedLangIso3[picoCurrentLangIndex]); 10775f6105e73f0c74acd10126175d4952ade10a0b05Jean-Michel Trivi strcpy(country, picoSupportedCountryIso3[picoCurrentLangIndex]); 10789b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // no variant in this implementation 10799b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(variant, "\0"); 10809b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10819b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_SUCCESS; 10829b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi} 10839b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 10849b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 10859b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi/** setAudioFormat 10869b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * sets the audio format to use for synthesis, returns what is actually used. 10879b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @encoding - reference to encoding format 10889b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @rate - reference to sample rate 10899b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @channels - reference to number of channels 10909b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return tts_result 10919b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * */ 10929b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivitts_result TtsEngine::setAudioFormat(AudioSystem::audio_format& encoding, uint32_t& rate, 10939b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int& channels) 1094b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 10959b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // ignore the input parameters, the enforced audio parameters are fixed here 10969b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi encoding = AudioSystem::PCM_16_BIT; 10979b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi rate = 16000; 10989b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi channels = 1; 10999b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_SUCCESS; 1100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 110254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** setProperty 110454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Set property. The supported properties are: language, rate, pitch and volume. 1105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @property - name of property to set 1106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @value - value to set 1107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @size - size of value 1108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 111054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::setProperty( const char * property, const char * value, const size_t size ) 1111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 111239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int rate; 111339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int pitch; 111439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int volume; 111539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 111639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set a specific property for the engine. 111739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Supported properties include: language (locale), rate, pitch, volume. */ 111854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Sanity check */ 1119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (property == NULL) 112039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("setProperty called with property NULL"); 1122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 112339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 11244eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (value == NULL) 112639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("setProperty called with value NULL"); 1128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 112939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 11304eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (strncmp(property, "language", 8) == 0) 1132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 113339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Verify it's in correct format. */ 113439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (strlen(value) != 2 && strlen(value) != 6) 113539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("change language called with incorrect format"); 1137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 113839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 11394eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 114039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Try to switch to specified language. */ 1141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (doLanguageSwitch(value) == TTS_FAILURE) 114239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("failed to load language"); 1144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 114539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else 114739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 114939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else if (strncmp(property, "rate", 4) == 0) 115239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 115339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = atoi(value); 115439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (rate < PICO_MIN_RATE) 115539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = PICO_MIN_RATE; 115639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (rate > PICO_MAX_RATE) 115739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = PICO_MAX_RATE; 1158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currRate = rate; 1159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 116039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else if (strncmp(property, "pitch", 5) == 0) 116239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 116339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = atoi(value); 116439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (pitch < PICO_MIN_PITCH) 116539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = PICO_MIN_PITCH; 116639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (pitch > PICO_MAX_PITCH) 116739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = PICO_MAX_PITCH; 1168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currPitch = pitch; 1169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 117039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else if (strncmp(property, "volume", 6) == 0) 117239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 117339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = atoi(value); 117439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (volume < PICO_MIN_VOLUME) 117539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = PICO_MIN_VOLUME; 117639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (volume > PICO_MAX_VOLUME) 117739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = PICO_MAX_VOLUME; 1178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currVolume = volume; 1179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 118039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 1183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 118554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** getProperty 118754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Get the property. Supported properties are: language, rate, pitch and volume. 1188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @property - name of property to get 118939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @value - buffer which will receive value of property 119039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @iosize - size of value - if size is too small on return this will contain actual size needed 1191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 119339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::getProperty( const char * property, char * value, size_t * iosize ) 1194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 119539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the property for the engine. 119639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi This property was previously set by setProperty or by default. */ 119754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* sanity check */ 1198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (property == NULL) 119939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("getProperty called with property NULL"); 1201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 120239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 12034eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (value == NULL) 120539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("getProperty called with value NULL"); 1207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 120839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 12094eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (strncmp(property, "language", 8) == 0) 1211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 121239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (picoProp_currLang == NULL) 121339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, ""); 121539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else 1217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 121839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (*iosize < strlen(picoProp_currLang)+1) 121939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(picoProp_currLang) + 1; 1221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 122239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, picoProp_currLang); 122439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 122639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else if (strncmp(property, "rate", 4) == 0) 122839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmprate[4]; 1230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmprate, "%d", picoProp_currRate); 1231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (*iosize < strlen(tmprate)+1) 1232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 1233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmprate) + 1; 1234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 1235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmprate); 1237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 123839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else if (strncmp(property, "pitch", 5) == 0) 124039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmppitch[4]; 1242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmppitch, "%d", picoProp_currPitch); 1243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (*iosize < strlen(tmppitch)+1) 1244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 1245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmppitch) + 1; 1246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 1247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmppitch); 1249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 125039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else if (strncmp(property, "volume", 6) == 0) 125239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmpvol[4]; 1254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmpvol, "%d", picoProp_currVolume); 1255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (*iosize < strlen(tmpvol)+1) 125639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmpvol) + 1; 1258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 125939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmpvol); 1261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 126239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 126339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 126439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Unknown property */ 126539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Unsupported property"); 126639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_PROPERTY_UNSUPPORTED; 1267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 126954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** synthesizeText 127154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Synthesizes a text string. 127239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The text string could be annotated with SSML tags. 127339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @text - text to synthesize 127439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @buffer - buffer which will receive generated samples 1275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @bufferSize - size of buffer 1276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @userdata - pointer to user data which will be passed back to callback function 1277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 127939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::synthesizeText( const char * text, int8_t * buffer, size_t bufferSize, void * userdata ) 1280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 128139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int err; 128239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int cbret; 128339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Char * inp = NULL; 128439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Char * local_text = NULL; 128539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi short outbuf[MAX_OUTBUF_SIZE/2]; 128639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Int16 bytes_sent, bytes_recv, text_remaining, out_data_type; 1287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen pico_Status ret; 128839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi SvoxSsmlParser * parser = NULL; 12894eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 129039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSynthAbort = 0; 1291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (text == NULL) 129239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("synthesizeText called with NULL string"); 1294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 129539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 12964eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (buffer == NULL) 129839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("synthesizeText called with NULL buffer"); 1300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 130139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 13024eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 130339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if ((strncmp(text, "<speak", 6) == 0) || 130439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi (strncmp(text, "<?xml", 5) == 0) ) 130539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 130639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* SSML input */ 130739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi parser = new SvoxSsmlParser(); 130839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (parser && parser->initSuccessful()) 130939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 131039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi err = parser->parseDocument(text, 1); 131139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (err == XML_STATUS_ERROR) 131239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 131339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGI("Warning: SSML document parsed with errors"); 131439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 131539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * parsed_text = parser->getParsedDocument(); 131639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (parsed_text) 131739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 131839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add property tags to the string - if any. */ 131939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi local_text = (pico_Char *) doAddProperties( parsed_text ); 132039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (!local_text) 132139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 132239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Failed to allocate memory for text string"); 132339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi delete parser; 132439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 132539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 132639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * lang = parser->getParsedDocumentLanguage(); 132739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (doLanguageSwitch(lang) == TTS_FAILURE) 132839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 132939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Failed to switch to language specified in SSML document."); 133039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi delete parser; 133139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 133239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 133339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi delete parser; 133439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 133539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi else 133639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 133739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Failed to parse SSML document"); 133839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi delete parser; 133939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 134039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 134139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 134239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi else 134339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 134439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Failed to create SSML parser"); 134539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (parser) delete parser; 134639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 134739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 134839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 134939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi else 1350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 135139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add property tags to the string - if any. */ 135239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi local_text = (pico_Char *) doAddProperties( text ); 135339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (!local_text) 135439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Failed to allocate memory for text string"); 1356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 135739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 13594eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 136039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi text_remaining = strlen((const char *) local_text) + 1; 13614eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 136239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi inp = (pico_Char *) local_text; 13634eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen size_t bufused = 0; 13654eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 136654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* synthesis loop */ 1367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen while (text_remaining) 1368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 1369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoSynthAbort) 137039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 137139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_resetEngine( picoEngine ); 1372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 137339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 13744eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 137554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Feed the text into the engine. */ 137639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_putTextUtf8( picoEngine, inp, text_remaining, &bytes_sent ); 1377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (ret != PICO_OK) 137839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Error synthesizing string '%s': [%d]", text, ret); 138039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (local_text) 138139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( local_text ); 1382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 138339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 13844eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen text_remaining -= bytes_sent; 1386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen inp += bytes_sent; 1387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen do 1388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 1389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (picoSynthAbort) 1390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 1391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 1392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 139354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Retrieve the samples and add them to the buffer. */ 139439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getData( picoEngine, (void *) outbuf, MAX_OUTBUF_SIZE, &bytes_recv, &out_data_type ); 1395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (bytes_recv) 1396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 139739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if ((bufused + bytes_recv) <= bufferSize) 139839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 139939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi memcpy(buffer+bufused, (int8_t *) outbuf, bytes_recv); 1400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen bufused += bytes_recv; 140139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen else 140339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 140454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* The buffer filled; pass this on to the callback function. */ 140539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi cbret = picoSynthDoneCBPtr(userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, TTS_SYNTH_PENDING); 1406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (cbret == TTS_CALLBACK_HALT) 140739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 1408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGI("Halt requested by caller. Halting."); 1409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 1; 1410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 141139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen bufused = 0; 141339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi memcpy(buffer, (int8_t *) outbuf, bytes_recv); 14144eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi bufused += bytes_recv; 141539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } while (PICO_STEP_BUSY == ret); 14184eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 141939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* This chunk of synthesis is finished; pass the remaining samples. 142054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi Use 16 KHz, 16-bit samples. */ 1421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (!picoSynthAbort) 1422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 142339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, TTS_SYNTH_PENDING); 1424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 0; 14264eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (ret != PICO_STEP_IDLE) 1428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen { 1429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Error occurred during synthesis [%d]", ret); 1430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen if (local_text) free(local_text); 143139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGV("Synth loop: sending TTS_SYNTH_DONE after error"); 143239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, TTS_SYNTH_DONE); 1433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 1434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 143639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 143739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Synthesis is done; notify the caller */ 143839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGV("Synth loop: sending TTS_SYNTH_DONE after all done, or was asked to stop"); 143939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, TTS_SYNTH_DONE); 14404eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 144139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (local_text) { 144239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( local_text ); 144339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1444b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 144754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** synthesizeIpa 144954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Synthesizes a phonetic string in IPA format. 145039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi The Pico engine understands only XSAMPA, so the IPA must be converted. 145139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi The string must also be parceled into words since it can only hanlde a word at a time. 145239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Each phonemic word must be wrapped with a tag. 1453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @ipa - phonetic string to synthesize 1454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @buffer - buffer which will receive generated samples 1455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @bufferSize - size of buffer 1456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @userdata - pointer to user data which will be passed back to callback function 1457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 145954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::synthesizeIpa( const char * ipa, int8_t * buffer, size_t bufferSize, void * userdata ) 1460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 146139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi // deprecated call 146239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 146354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1464b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1465b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 146654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** stop 146854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Aborts the running synthesis. 1469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 147139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::stop( void ) 1472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 1; 1474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 147754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus 1479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" { 1480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 1481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 148239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TriviTtsEngine * getTtsEngine( void ) 1483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return new TtsEngine(); 1485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus 1488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 1490b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1491