com_svox_picottsengine.cpp revision f41e1f808fbcf9014c0a5668fba4eff6dd051366
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. 164bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * 174bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * This is the Manager layer. It sits on top of the native Pico engine 184bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * and provides the interface to the defined Google TTS engine API. 194bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * The Google engine API is the boundary to allow a TTS engine to be swapped. 204bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * The Manager layer also provide the SSML tag interpretation. 214bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * The supported SSML tags are mapped to corresponding tags natively supported by Pico. 224bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * Native Pico functions always begin with picoXXX. 234bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * 244bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * In the Pico engine, the language cannot be changed indpendently of the voice. 254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * If either the voice or locale/language are changed, a new resource is loaded. 264bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * 274bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * Only a subset of SSML 1.0 tags are supported. 284bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * Some SSML tags involve significant complexity. 294bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * If the language is changed through an SSML tag, there is a latency for the load. 304bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi * 31b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */ 32070c0460fcdfe276cce9dbf49a883d7c6a02c5c4Jean-Michel Trivi//#define LOG_NDEBUG 0 33b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 34b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdio.h> 35b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <unistd.h> 364bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi#include <stdlib.h> 37b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 38b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define LOG_TAG "SVOX Pico Engine" 39b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 40b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <utils/Log.h> 4139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include <utils/String16.h> /* for strlen16 */ 42b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <android_runtime/AndroidRuntime.h> 43f41e1f808fbcf9014c0a5668fba4eff6dd051366Bjorn Bringert#include <TtsEngine.h> 44f41e1f808fbcf9014c0a5668fba4eff6dd051366Bjorn Bringert 4539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include <cutils/jstring.h> 46b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <picoapi.h> 47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <picodefs.h> 48f41e1f808fbcf9014c0a5668fba4eff6dd051366Bjorn Bringert 4939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include "svox_ssml_parser.h" 50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 51b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenusing namespace android; 52b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 53b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* adaptation layer defines */ 544eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi#define PICO_MEM_SIZE 2500000 5554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking rate */ 5639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_RATE 20 57b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_RATE 500 5839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_DEF_RATE 100 5954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking pitch */ 6039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_PITCH 50 61b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_PITCH 200 6239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_DEF_PITCH 100 6354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking volume */ 6439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_VOLUME 0 65b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_VOLUME 500 662821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi#define PICO_DEF_VOLUME 100 6739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 6854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* string constants */ 69b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define MAX_OUTBUF_SIZE 128 70a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Triviconst char * PICO_SYSTEM_LINGWARE_PATH = "/system/tts/lang_pico/"; 7139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_LINGWARE_PATH = "/sdcard/svox/"; 7239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOICE_NAME = "PicoVoice"; 7339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_SPEED_OPEN_TAG = "<speed level='%d'>"; 7439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_SPEED_CLOSE_TAG = "</speed>"; 7539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PITCH_OPEN_TAG = "<pitch level='%d'>"; 7639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PITCH_CLOSE_TAG = "</pitch>"; 7739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOLUME_OPEN_TAG = "<volume level='%d'>"; 7839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOLUME_CLOSE_TAG = "</volume>"; 7939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PHONEME_OPEN_TAG = "<phoneme ph='"; 804bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Triviconst char * PICO_PHONEME_CLOSE_TAG = "'/>"; 8139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 8239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/* supported voices 8339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Pico does not seperately specify the voice and locale. */ 8439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedLangIso3[] = { "eng", "eng", "deu", "spa", "fra", "ita" }; 8539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedCountryIso3[] = { "USA", "GBR", "DEU", "ESP", "FRA", "ITA" }; 861ee916b1cdb8e54192a4d11d7fae4cd0953baadbJean-Michel Triviconst char * picoSupportedLang[] = { "en-US", "en-GB", "de-DE", "es-ES", "fr-FR", "it-IT" }; 8739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoInternalLang[] = { "en-US", "en-GB", "de-DE", "es-ES", "fr-FR", "it-IT" }; 8839358f0dacad8cece6c2d3ef1055030f57090c79Jean-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" }; 8939358f0dacad8cece6c2d3ef1055030f57090c79Jean-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" }; 9039358f0dacad8cece6c2d3ef1055030f57090c79Jean-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" }; 9139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst int picoNumSupportedVocs = 6; 92b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 9354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* supported properties */ 9439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedProperties[] = { "language", "rate", "pitch", "volume" }; 9539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst int picoNumSupportedProperties = 4; 96b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 9754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 9854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* adapation layer global variables */ 9939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TrivisynthDoneCB_t * picoSynthDoneCBPtr; 10039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivivoid * picoMemArea = NULL; 10139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_System picoSystem = NULL; 10239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoTaResource = NULL; 10339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoSgResource = NULL; 10439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoUtppResource = NULL; 10539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Engine picoEngine = NULL; 10639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoTaFileName = NULL; 10739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoSgFileName = NULL; 10839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoUtppFileName = NULL; 10939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoTaResourceName = NULL; 11039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoSgResourceName = NULL; 11139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoUtppResourceName = NULL; 11254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoSynthAbort = 0; 11339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivichar * picoProp_currLang = NULL; /* current language */ 11454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currRate = PICO_DEF_RATE; /* current rate */ 11554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currPitch = PICO_DEF_PITCH; /* current pitch */ 11654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currVolume = PICO_DEF_VOLUME; /* current volume */ 11754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1189b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Triviint picoCurrentLangIndex = -1; 119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1205ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivichar * pico_alt_lingware_path = NULL; 1215ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi 122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* internal helper functions */ 124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 12539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** checkForLocale 12639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Check whether the requested locale is among the supported locales. 1271ee916b1cdb8e54192a4d11d7fae4cd0953baadbJean-Michel Trivi * @locale - the locale to check, either in xx or xx-YY format 12839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return index of the locale, or -1 if not supported. 129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 13039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic int checkForLocale( const char * locale ) 131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 13254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi int found = -1; /* language not found */ 13339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int i; 13439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (locale == NULL) { 1355da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi LOGE("checkForLocale called with NULL language"); 1364bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return found; 13739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 13854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 13954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Verify that the requested locale is a locale that we support. */ 1404bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) { 1414bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strcmp(locale, picoSupportedLang[i]) == 0) { /* in array */ 142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen found = i; 143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 14554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi }; 14639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 147410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi /* The exact locale was not found. */ 1484bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (found < 0) { 14954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* We didn't find an exact match; it may have been specified with only the first 2 characters. 15039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi This could overmatch ISO 639-3 language codes.%% */ 151410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi 152410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi /* check whether the current language matches the locale's language */ 153410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi if ((picoCurrentLangIndex > -1) && 154410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi (strncmp(locale, picoSupportedLang[picoCurrentLangIndex], 2) == 0)) { 155410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi /* the current language matches the requested language, let's use it */ 156410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi found = picoCurrentLangIndex; 157410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi } else { 158410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi /* check whether we can find a match at least on the language */ 159410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) { 160410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi if (strncmp(locale, picoSupportedLang[i], 2) == 0) { 161410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi found = i; 162410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi break; 163410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi } 164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 166410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi 1674bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (found < 0) { 168410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi LOGE("TtsEngine::set language called with unsupported locale %s", locale); 169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 17054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi }; 171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return found; 172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 17454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** cleanResources 17654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Unloads any loaded Pico resources. 177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 17854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivistatic void cleanResources( void ) 179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1804bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoEngine) { 18154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_disposeEngine( picoSystem, &picoEngine ); 18239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_releaseVoiceDefinition( picoSystem, (pico_Char *) PICO_VOICE_NAME ); 183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoEngine = NULL; 184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1854bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoUtppResource) { 18654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoUtppResource ); 187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppResource = NULL; 188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1894bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoTaResource) { 19054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoTaResource ); 191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaResource = NULL; 192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1934bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSgResource) { 19454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoSgResource ); 195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgResource = NULL; 196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 197dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi 198dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi if (picoSystem) { 199dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi pico_terminate(&picoSystem); 200dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi picoSystem = NULL; 201dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi } 2029b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi picoCurrentLangIndex = -1; 203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 20554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** cleanFiles 20754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Frees any memory allocated for file and resource strings. 208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 20954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivistatic void cleanFiles( void ) 210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 2114bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currLang) { 21239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoProp_currLang ); 213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currLang = NULL; 214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2154eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2164bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoTaFileName) { 21739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoTaFileName ); 218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaFileName = NULL; 219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2204eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2214bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSgFileName) { 22239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoSgFileName ); 223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgFileName = NULL; 224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2254eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2264bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoUtppFileName) { 22739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoUtppFileName ); 228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppFileName = NULL; 229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2304eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2314bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoTaResourceName) { 23239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoTaResourceName ); 233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaResourceName = NULL; 234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2354eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2364bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSgResourceName) { 23739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoSgResourceName ); 238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgResourceName = NULL; 239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2404eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2414bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoUtppResourceName) { 24239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoUtppResourceName ); 243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppResourceName = NULL; 244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 2479b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi/** hasResourcesForLanguage 2489b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * Check to see if the resources required to load the language at the specified index 2499b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * are properly installed 2509b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @langIndex - the index of the language to check the resources for. The index is valid. 2519b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return true if the required resources are installed, false otherwise 2529b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi */ 2539b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivistatic bool hasResourcesForLanguage(int langIndex) { 2549b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi FILE * pFile; 2559b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi char* fileName = (char*)malloc(PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE); 2564bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 257a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi /* check resources on system (under PICO_SYSTEM_LINGWARE_PATH). */ 258a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi strcpy((char*)fileName, PICO_SYSTEM_LINGWARE_PATH); 259a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi strcat((char*)fileName, (const char*)picoInternalTaLingware[langIndex]); 260a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi pFile = fopen(fileName, "r"); 261a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi if (pFile != NULL) { 262a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi /* "ta" file found. */ 263a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi fclose (pFile); 264a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi /* now look for "sg" file. */ 265a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi strcpy((char*)fileName, PICO_SYSTEM_LINGWARE_PATH); 266a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi strcat((char*)fileName, (const char*)picoInternalSgLingware[langIndex]); 267a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi pFile = fopen(fileName, "r"); 268a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi if (pFile != NULL) { 269a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi /* "sg" file found, no need to continue checking, return success. */ 270a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi fclose(pFile); 271a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi free(fileName); 272a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi return true; 273a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi } 274a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi } 275a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi 276a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi /* resources not found on system, check resources on alternative location */ 2775ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi /* (under pico_alt_lingware_path). */ 2785ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi strcpy((char*)fileName, pico_alt_lingware_path); 2799b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcat((char*)fileName, (const char*)picoInternalTaLingware[langIndex]); 2804bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi pFile = fopen(fileName, "r"); 2814bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (pFile == NULL) { 2829b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2839b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return false; 2849b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 2859b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi fclose (pFile); 2869b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 2879b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 2885ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi strcpy((char*)fileName, pico_alt_lingware_path); 2899b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcat((char*)fileName, (const char*)picoInternalSgLingware[langIndex]); 2909b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi pFile = fopen(fileName, "r"); 2919b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (pFile == NULL) { 2929b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2939b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return false; 2949b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 2959b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi fclose(pFile); 2969b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2979b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return true; 2989b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 2999b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi} 3009b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 3014eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi/** doLanguageSwitchFromLangIndex 30239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Switch to the requested locale. 30339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If the locale is already loaded, it returns immediately. 30439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If another locale is already is loaded, it will first be unloaded and the new one then loaded. 30539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If no locale is loaded, the requested locale will be loaded. 30639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @langIndex - the index of the locale/voice to load, which is guaranteed to be supported. 307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return TTS_SUCCESS or TTS_FAILURE 3084eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi */ 30939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic tts_result doLanguageSwitchFromLangIndex( int langIndex ) 310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 31139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int ret; /* function result code */ 31239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 313dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi if (langIndex>=0) { 314dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi /* If we already have a loaded locale, check whether it is the same one as requested. */ 315dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi if (picoProp_currLang && (strcmp(picoProp_currLang, picoSupportedLang[langIndex]) == 0)) { 316410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi //LOGI("Language already loaded (%s == %s)", picoProp_currLang, 317410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi // picoSupportedLang[langIndex]); 318dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi return TTS_SUCCESS; 319dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi } 320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 322dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi /* It is not the same locale; unload the current one first. Also invalidates the system object*/ 323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 3244eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 32539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Allocate memory for file and resource names. */ 326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 327dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi 328dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi if (picoSystem==NULL) { 329dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi /*re-init system object*/ 330dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi ret = pico_initialize( picoMemArea, PICO_MEM_SIZE, &picoSystem ); 331dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi if (PICO_OK != ret) { 332dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi LOGE("Failed to initialize the pico system object\n"); 333dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi return TTS_FAILURE; 334dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi } 335dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi } 336dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi 33739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoProp_currLang = (char *) malloc( 10 ); 33839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoTaFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 33939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSgFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 34039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoUtppFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 34139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoTaResourceName = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 34239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSgResourceName = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 34339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoUtppResourceName =(pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 34439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 345dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi if ( 346dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi (picoProp_currLang==NULL) || (picoTaFileName==NULL) || (picoSgFileName==NULL) || 347dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi (picoUtppFileName==NULL) || (picoTaResourceName==NULL) || (picoSgResourceName==NULL) || 348dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi (picoUtppResourceName==NULL) 349dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi ) { 350dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi LOGE("Failed to allocate memory for internal strings\n"); 351dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi cleanResources(); 352dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi return TTS_FAILURE; 353dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi } 354dd1501a7191f7be46c119296ae5bcf2c3dc6e5e8Jean-Michel Trivi 355a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi /* Find where to load the resource files from: system or alternative location */ 356a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi /* based on availability of the Ta file. Try the alternative location first, this is where */ 3575ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi /* more recent language file updates would be installed (under pico_alt_lingware_path). */ 358a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi bool bUseSystemPath = true; 359a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi FILE * pFile; 360a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi char* tmpFileName = (char*)malloc(PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE); 3615ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi strcpy((char*)tmpFileName, pico_alt_lingware_path); 362a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi strcat((char*)tmpFileName, (const char*)picoInternalTaLingware[langIndex]); 363a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi pFile = fopen(tmpFileName, "r"); 364a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi if (pFile != NULL) { 3655ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi /* "ta" file found under pico_alt_lingware_path, don't use the system path. */ 366a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi fclose (pFile); 367a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi bUseSystemPath = false; 368a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi } 369a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi free(tmpFileName); 370a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi 37139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set the path and file names for resource files. */ 372a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi if (bUseSystemPath) { 373a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi strcpy((char *) picoTaFileName, PICO_SYSTEM_LINGWARE_PATH); 374a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi strcpy((char *) picoSgFileName, PICO_SYSTEM_LINGWARE_PATH); 375a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi strcpy((char *) picoUtppFileName, PICO_SYSTEM_LINGWARE_PATH); 376a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi } else { 3775ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi strcpy((char *) picoTaFileName, pico_alt_lingware_path); 3785ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi strcpy((char *) picoSgFileName, pico_alt_lingware_path); 3795ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi strcpy((char *) picoUtppFileName, pico_alt_lingware_path); 380a8d076f716bca609b7e740cd888177fbc589a521Jean-Michel Trivi } 38139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoTaFileName, (const char *) picoInternalTaLingware[langIndex]); 38239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoSgFileName, (const char *) picoInternalSgLingware[langIndex]); 38339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoUtppFileName, (const char *) picoInternalUtppLingware[langIndex]); 38439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 38539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the text analysis Lingware resource file. */ 38639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoTaFileName, &picoTaResource ); 3874bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3884eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load textana resource for %s [%d]", picoSupportedLang[langIndex], ret); 389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3934eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 39439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the signal generation Lingware resource file. */ 39539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoSgFileName, &picoSgResource ); 3964bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3974eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load siggen resource for %s [%d]", picoSupportedLang[langIndex], ret); 398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4024eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 40339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the utpp Lingware resource file if exists - NOTE: this file is optional 40439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi and is currently not used. Loading is only attempted for future compatibility. 40539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If this file is not present the loading will still succeed. */ 40639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoUtppFileName, &picoUtppResource ); 4074bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if ((PICO_OK != ret) && (ret != PICO_EXC_CANT_OPEN_FILE)) { 4084eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load utpp resource for %s [%d]", picoSupportedLang[langIndex], ret); 409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 4124bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 4134eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 41439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the text analysis resource name. */ 41539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoTaResource, (char *) picoTaResourceName ); 4164bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 4174eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get textana resource name for %s [%d]", picoSupportedLang[langIndex], ret); 418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4224eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 42339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the signal generation resource name. */ 42439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoSgResource, (char *) picoSgResourceName ); 425744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if ((PICO_OK == ret) && (picoUtppResource != NULL)) { 42639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get utpp resource name - optional: see note above. */ 42739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoUtppResource, (char *) picoUtppResourceName ); 4284bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 4294eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get utpp resource name for %s [%d]", picoSupportedLang[langIndex], ret); 430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 4364eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get siggen resource name for %s [%d]", picoSupportedLang[langIndex], ret); 437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4414eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 44239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Create a voice definition. */ 44339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_createVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME ); 4444bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 4454eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to create voice for %s [%d]", picoSupportedLang[langIndex], ret); 446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4504eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 45139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add the text analysis resource to the voice. */ 45239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoTaResourceName ); 4534bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 4544eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add textana resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4594eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 46039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add the signal generation resource to the voice. */ 46139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoSgResourceName ); 462744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if ((PICO_OK == ret) && (picoUtppResource != NULL)) { 46339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add utpp resource to voice - optional: see note above. */ 46439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoUtppResourceName ); 4654bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 4664eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add utpp resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4724eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 4734bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 4744eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add siggen resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 477b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 48039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_newEngine( picoSystem, (const pico_Char *) PICO_VOICE_NAME, &picoEngine ); 4814bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 4824eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to create engine for %s [%d]", picoSupportedLang[langIndex], ret); 483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4874eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 48839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set the current locale/voice. */ 48939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy( picoProp_currLang, picoSupportedLang[langIndex] ); 4905da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi picoCurrentLangIndex = langIndex; 491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGI("loaded %s successfully", picoProp_currLang); 492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 49539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 4964eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi/** doLanguageSwitch 49739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Switch to the requested locale. 49839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If this locale is already loaded, it returns immediately. 49939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If another locale is already loaded, this will first be unloaded 50039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * and the new one then loaded. 50139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If no locale is loaded, the requested will be loaded. 5021ee916b1cdb8e54192a4d11d7fae4cd0953baadbJean-Michel Trivi * @locale - the locale to check, either in xx or xx-YY format (i.e "en" or "en-US") 5034eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi * return TTS_SUCCESS or TTS_FAILURE 5044eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi*/ 50539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic tts_result doLanguageSwitch( const char * locale ) 5064eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi{ 50739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int loclIndex; /* locale index */ 5084eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 50939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the new locale. */ 51039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi loclIndex = checkForLocale( locale ); 5114bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (loclIndex < 0) { 51239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Tried to swith to non-supported locale %s", locale); 51339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 5144bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 515410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi //LOGI("Found supported locale %s", picoSupportedLang[loclIndex]); 51639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return doLanguageSwitchFromLangIndex( loclIndex ); 5174eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi} 5184eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 51939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** doAddProperties 52139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Add <speed>, <pitch> and <volume> tags to the text, 52239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * if the properties have been set to non-default values, and return the new string. 52339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The calling function is responsible for freeing the returned string. 524b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @str - text to apply tags to 525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return new string with tags applied 526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 52739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic char * doAddProperties( const char * str ) 528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 52939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * data = NULL; 53039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int haspitch, hasspeed, hasvol; /* parameters */ 53139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int textlen; /* property string length */ 53239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi haspitch = 0; hasspeed = 0; hasvol = 0; 53339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi textlen = strlen(str) + 1; 5344bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currPitch != PICO_DEF_PITCH) { /* non-default pitch */ 535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_PITCH_OPEN_TAG) + 5; 536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_PITCH_CLOSE_TAG); 537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen haspitch = 1; 538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5394bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currRate != PICO_DEF_RATE) { /* non-default rate */ 540b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_SPEED_OPEN_TAG) + 5; 541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_SPEED_CLOSE_TAG); 542b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hasspeed = 1; 543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 544474a319cfd410d4bbc5c76d0b382348181f499b8Charles Chen 5452821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi if (picoProp_currVolume != PICO_DEF_VOLUME) { /* non-default volume */ 546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_VOLUME_OPEN_TAG) + 5; 547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_VOLUME_CLOSE_TAG); 548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hasvol = 1; 5492821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi } 5504eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 55139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Compose the property strings. */ 55239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi data = (char *) malloc( textlen ); /* allocate string */ 5534bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!data) { 554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return NULL; 555b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 55654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi memset(data, 0, textlen); /* clear it */ 5574bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (haspitch) { 558b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_PITCH_OPEN_TAG) + strlen(PICO_PITCH_CLOSE_TAG) + 5); 559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_PITCH_OPEN_TAG, picoProp_currPitch); 560b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 561b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 562b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5634eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 5644bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (hasspeed) { 565b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_SPEED_OPEN_TAG) + strlen(PICO_SPEED_CLOSE_TAG) + 5); 566b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_SPEED_OPEN_TAG, picoProp_currRate); 567b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 568b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 569b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5704eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 5714bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (hasvol) { 572b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_VOLUME_OPEN_TAG) + strlen(PICO_VOLUME_CLOSE_TAG) + 5); 573b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_VOLUME_OPEN_TAG, picoProp_currVolume); 574b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 575b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 576b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5774eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 578b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, str); 5794bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (hasvol) { 580b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_VOLUME_CLOSE_TAG); 581b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5824eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 5834bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (hasspeed) { 584b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_SPEED_CLOSE_TAG); 585b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5864eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 5874bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (haspitch) { 588b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_PITCH_CLOSE_TAG); 589b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 590b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return data; 591b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 592b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 59354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 594d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi/** get_tok 595d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * Searches for tokens in a string 596d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @str - text to be processed 597d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @pos - position of first character to be searched in str 598d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @textlen - postion of last character to be searched 599d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @tokstart - address of a variable to receive the start of the token found 600d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @tokstart - address of a variable to receive the length of the token found 601d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * return : 1=token found, 0=token not found 602d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * notes : the token separator set could be enlarged adding characters in "seps" 603d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi*/ 604d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivistatic int get_tok(const char * str , int pos, int textlen, int *tokstart, int *toklen) 605d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi{ 606d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi const char * seps = " "; 607d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 608d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*look for start*/ 609d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi while ((pos<textlen) && (strchr(seps,str[pos]) != NULL)) { 610d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi pos++; 611d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 612d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi if (pos == textlen) { 613d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*no characters != seps found whithin string*/ 614d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi return 0; 615d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 616d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi *tokstart = pos; 617d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*look for end*/ 618d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi while ((pos<textlen) && (strchr(seps,str[pos]) == NULL)) { 619d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi pos++; 620d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 621d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi *toklen = pos - *tokstart; 622d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi return 1; 623d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi}/*get_tok*/ 624d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 625d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 626d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi/** get_sub_tok 627d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * Searches for subtokens in a token having a compound structure with camel case like "xxxYyyy" 628d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @str - text to be processed 629d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @pos - position of first character to be searched in str 630d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @textlen - postion of last character to be searched in str 631d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @tokstart - address of a variable to receive the start of the sub token found 632d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @tokstart - address of a variable to receive the length of the sub token found 633d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * return : 1=sub token found, 0=sub token not found 634d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * notes : the sub token separator set could be enlarged adding characters in "seps" 635d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi*/ 636d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivistatic int get_sub_tok(const char * str , int pos, int textlen, int *tokstart, int *toklen) { 637d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 638d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi const char * seps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 639d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 640d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi if (pos == textlen) { 641d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi return 0; 642d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 643d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 644d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*first char != space*/ 645d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi *tokstart = pos; 646d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*finding first non separator*/ 647d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi while ((pos < textlen) && (strchr(seps, str[pos]) != NULL)) { 648d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi pos++; 649d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 650d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi if (pos == textlen) { 651d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*characters all in seps found whithin string : return full token*/ 652d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi *toklen = pos - *tokstart; 653d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi return 1; 654d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 655d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*pos should be pointing to first non seps and more chars are there*/ 656d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*finding first separator*/ 657d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi while ((pos < textlen) && (strchr(seps, str[pos]) == NULL)) { 658d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi pos++; 659d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 660d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi if (pos == textlen) { 661d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*transition non seps->seps not found : return full token*/ 662d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi *toklen = pos - *tokstart; 663d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi return 1; 664d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 665d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi *toklen = pos - *tokstart; 666d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi return 1; 667d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi}/*get_sub_tok*/ 668d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 669d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 670d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi/** doCamelCase 671d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * Searches for tokens having a compound structure with camel case and transforms them as follows : 672d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * "XxxxYyyy" -->> "Xxxx Yyyy", 673d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * "xxxYyyy" -->> "xxx Yyyy", 674d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * "XXXYyyy" -->> "XXXYyyy" 675d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * etc.... 676d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * The calling function is responsible for freeing the returned string. 677d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * @str - text to be processed 678d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi * return new string with text processed 679d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi*/ 680d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivistatic char * doCamelCase( const char * str ) 681d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi{ 682d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi int textlen; /* input string length */ 683d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi int totlen; /* output string length */ 684d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi int tlen_2, nsubtok; /* nuber of subtokens */ 685d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi int toklen, tokstart; /*legnth and start of generic token*/ 686d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi int stoklen, stokstart; /*legnth and start of generic sub-token*/ 687d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi int pos, tokpos, outpos; /*postion of current char in input string and token and output*/ 688d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi char *data; /*pointer of the returned string*/ 689d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 690d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi pos = 0; 691d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tokpos = 0; 692d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi toklen = 0; 693d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi stoklen = 0; 694d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tlen_2 = 0; 695d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi totlen = 0; 696d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 697d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi textlen = strlen(str) + 1; 698d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 699d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*counting characters after sub token splitting including spaces*/ 700d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi //while ((pos<textlen) && (str[pos]!=0)) { 701d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi while (get_tok(str, pos, textlen, &tokstart, &toklen)) { 702d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tokpos = tokstart; 703d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tlen_2 = 0; 704d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi nsubtok = 0; 705d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi while (get_sub_tok(str, tokpos, tokstart+toklen, &stokstart, &stoklen)) { 706d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi totlen += stoklen; 707d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tlen_2 += stoklen; 708d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tokpos = stokstart + stoklen; 709d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi nsubtok += 1; 710d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 711d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi totlen += nsubtok; /*add spaces between subtokens*/ 712d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi pos = tokstart + tlen_2; 713d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 714d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi //} 715d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /* Allocate the return string */ 7162821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi 717d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi data = (char *) malloc( totlen ); /* allocate string */ 718d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi if (!data) { 719d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi return NULL; 720d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 721d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi memset(data, 0, totlen); /* clear it */ 722d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi outpos = 0; 723d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi pos = 0; 724d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /*copying characters*/ 725d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi //while ((pos<textlen) && (str[pos]!=0)) { 726d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi while (get_tok (str, pos, textlen, &tokstart, &toklen)) { 727d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tokpos = tokstart; 728d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tlen_2 = 0; 729d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi nsubtok = 0; 730d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi while (get_sub_tok(str, tokpos, tokstart+toklen, &stokstart, &stoklen)) { 731d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi strncpy(&(data[outpos]), &(str[stokstart]), stoklen); 732d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi outpos += stoklen; 733d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi strncpy(&(data[outpos]), " ", 1); 734d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tlen_2 += stoklen; 735d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi outpos += 1; 736d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi tokpos = stokstart + stoklen; 737d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 738d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi pos=tokstart+tlen_2; 739d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi } 740d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi //} 7412821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi if (outpos == 0) { 7422821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi outpos = 1; 7432821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi } 7442821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi data[outpos-1] = 0; 745d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi return data; 746d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi}/*doCamelCase*/ 747d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 748d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi 74939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** createPhonemeString 75039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Wrap all individual words in <phoneme> tags. 75139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The Pico <phoneme> tag only supports one word in each tag, 75239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * therefore they must be individually wrapped! 75339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @xsampa - text to convert to Pico phomene string 75439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @length - length of the input string 75539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return new string with tags applied 75639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 7574bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Triviextern char * createPhonemeString( const char * xsampa, int length ) 75839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 75939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * convstring = NULL; 76039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int origStrLen = strlen(xsampa); 76139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int numWords = 1; 76239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int start, totalLength, i, j; 76339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 764744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi for (i = 0; i < origStrLen; i ++) { 765744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if ((xsampa[i] == ' ') || (xsampa[i] == '#')) { 766744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi numWords ++; 767744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 768744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 769744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi 770744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if (numWords == 1) { 771744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi convstring = new char[origStrLen + 17]; 772744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi convstring[0] = '\0'; 773744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(convstring, PICO_PHONEME_OPEN_TAG); 774744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(convstring, xsampa); 775744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(convstring, PICO_PHONEME_CLOSE_TAG); 776744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } else { 777744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi char * words[numWords]; 778744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi start = 0; totalLength = 0; i = 0; j = 0; 779744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi for (i=0, j=0; i < origStrLen; i++) { 780744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if ((xsampa[i] == ' ') || (xsampa[i] == '#')) { 781744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi words[j] = new char[i+1-start+17]; 782744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi words[j][0] = '\0'; 783744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat( words[j], PICO_PHONEME_OPEN_TAG); 784744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strncat(words[j], xsampa+start, i-start); 785744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat( words[j], PICO_PHONEME_CLOSE_TAG); 786744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi start = i + 1; 787744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi j++; 788744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi totalLength += strlen(words[j-1]); 789744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 790744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 791744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi words[j] = new char[i+1-start+17]; 792744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi words[j][0] = '\0'; 793744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(words[j], PICO_PHONEME_OPEN_TAG); 794744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(words[j], xsampa+start); 795744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(words[j], PICO_PHONEME_CLOSE_TAG); 796744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi totalLength += strlen(words[j]); 797744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi convstring = new char[totalLength + 1]; 798744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi convstring[0] = '\0'; 799744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi for (i=0 ; i < numWords ; i++) { 800744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(convstring, words[i]); 801744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi delete [] words[i]; 802744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 803744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 804744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi 805744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi return convstring; 80639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 80739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 8084bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi/* The XSAMPA uses as many as 5 characters to represent a single IPA code. */ 80939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitypedef struct tagPhnArr 8104bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi{ 81139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char16_t strIPA; /* IPA Unicode symbol */ 8124bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi char strXSAMPA[6]; /* SAMPA sequence */ 8134bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi} PArr; 81439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 815e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi#define phn_cnt (134+7) 81639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 81739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TriviPArr PhnAry[phn_cnt] = { 81839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 819e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi /* XSAMPA conversion table 820e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi This maps a single IPA symbol to a sequence representing XSAMPA. 821e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi This relies upon a direct one-to-one correspondance 822e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi including diphthongs and affricates. */ 82339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 824e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi /* Vowels (23) complete */ 82539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025B, "E"}, 82639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0251, "A"}, 82739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0254, "O"}, 82839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00F8, "2"}, 82939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0153, "9"}, 83039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0276, "&"}, 83139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0252, "Q"}, 83239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028C, "V"}, 83339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0264, "7"}, 83439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026F, "M"}, 83539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0268, "1"}, 83639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0289, "}"}, 83739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026A, "I"}, 83839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028F, "Y"}, 83939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028A, "U"}, 84039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0259, "@"}, 84139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0275, "8"}, 84239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0250, "6"}, 84339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00E6, "{"}, 84439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025C, "3"}, 8454bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x025A, "@`"}, 8464bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x025E, "3\\\\"}, 8474bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0258, "@\\\\"}, 84839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 849e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi /* Consonants (60) complete */ 8504bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0288, "t`"}, 8514bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0256, "d`"}, 8524bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x025F, "J\\\\"}, 85339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0261, "g"}, 8544bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0262, "G\\\\"}, 85539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0294, "?"}, 85639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0271, "F"}, 8574bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0273, "n`"}, 85839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0272, "J"}, 85939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x014B, "N"}, 8604bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0274, "N\\\\"}, 8614bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0299, "B\\\\"}, 8624bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0280, "R\\\\"}, 86339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x027E, "4"}, 8644bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x027D, "r`"}, 8654bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0278, "p\\\\"}, 86639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03B2, "B"}, 86739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03B8, "T"}, 86839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00F0, "D"}, 86939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0283, "S"}, 87039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0292, "Z"}, 8714bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0282, "s`"}, 8724bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0290, "z`"}, 87339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00E7, "C"}, 8744bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x029D, "j\\\\"}, 87539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0263, "G"}, 87639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03C7, "X"}, 87739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0281, "R"}, 8784bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0127, "X\\\\"}, 8794bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0295, "?\\\\"}, 8804bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0266, "h\\\\"}, 88139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026C, "K"}, 8824bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x026E, "K\\\\"}, 88339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028B, "P"}, 8844bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0279, "r\\\\"}, 8854bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x027B, "r\\\\'"}, 8864bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0270, "M\\\\"}, 8874bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x026D, "l`"}, 88839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028E, "L"}, 8894bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x029F, "L\\\\"}, 89039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0253, "b_<"}, 89139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0257, "d_<"}, 89239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0284, "J\\_<"}, 89339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0260, "g_<"}, 89439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x029B, "G\\_<"}, 89539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028D, "W"}, 89639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0265, "H"}, 8974bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x029C, "H\\\\"}, 8984bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02A1, ">\\\\"}, 8994bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02A2, "<\\\\"}, 900e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x0267, "x\\\\"}, /* hooktop heng */ 9014bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0298, "O\\\\"}, 9024bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x01C0, "|\\\\"}, 9034bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x01C3, "!\\\\"}, 90439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x01C2, "=\\"}, 90539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x01C1, "|\\|\\"}, 9064bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x027A, "l\\\\"}, 9074bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0255, "s\\\\"}, 9084bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0291, "z\\\\"}, 90939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026B, "l_G"}, 91039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 911e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi 912e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi /* Diacritics (37) complete */ 91339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02BC, "_>"}, 91439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0325, "_0"}, 91539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x030A, "_0"}, 91639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x032C, "_v"}, 91739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B0, "_h"}, 91839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0324, "_t"}, 91939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0330, "_k"}, 92039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033C, "_N"}, 92139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x032A, "_d"}, 92239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033A, "_a"}, 92339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033B, "_m"}, 92439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0339, "_O"}, 92539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031C, "_c"}, 92639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031F, "_+"}, 92739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0320, "_-"}, 928e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x0308, "_\""}, /* centralized */ 92939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033D, "_x"}, 93039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0318, "_A"}, 93139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0319, "_q"}, 9324bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02DE, "`"}, 93339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B7, "_w"}, 93439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B2, "_j"}, 93539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02E0, "_G"}, 936e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02E4, "_?\\\\"}, /* pharyngealized */ 937e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x0303, "~"}, /* nasalized */ 93839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x207F, "_n"}, 93939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02E1, "_l"}, 94039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031A, "_}"}, 94139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0334, "_e"}, 942e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x031D, "_r"}, /* raised equivalent to 02D4 */ 943e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02D4, "_r"}, /* raised equivalent to 031D */ 944e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x031E, "_o"}, /* lowered equivalent to 02D5 */ 945e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02D5, "_o"}, /* lowered equivalent to 031E */ 946e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x0329, "="}, /* sylabic */ 947e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x032F, "_^"}, /* non-sylabic */ 948e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x0361, "_"}, /* top tie bar */ 94939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x035C, "_"}, 950e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi 951e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi /* Suprasegmental (15) incomplete */ 952e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02C8, "\""}, /* primary stress */ 953e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02CC, "%"}, /* secondary stress */ 954e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02D0, ":"}, /* long */ 955e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02D1, ":\\\\"}, /* half-long */ 956e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x0306, "_X"}, /* extra short */ 957e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi 958e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x2016, "||"}, /* major group */ 959e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x203F, "-\\\\"}, /* bottom tie bar */ 960e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x2197, "<R>"}, /* global rise */ 961e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x2198, "<F>"}, /* global fall */ 962e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x2193, "<D>"}, /* downstep */ 963e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x2191, "<U>"}, /* upstep */ 964e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02E5, "<T>"}, /* extra high level */ 965e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02E7, "<M>"}, /* mid level */ 966e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi {0x02E9, "<B>"}, /* extra low level */ 967e76209c9322210aaf4cb36b4d3a5f727510ef7b9Jean-Michel Trivi 9683cebc19d44aba7d72b0154655cdd2b70cb2be32aJean-Michel Trivi {0x025D, "3`:"}, /* non-IPA %% */ 96939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 97039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Affricates (6) complete */ 97139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A3, "d_z"}, 97239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A4, "d_Z"}, 9734bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02A5, "d_z\\\\"}, 97439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A6, "t_s"}, 97539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A7, "t_S"}, 9764bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02A8, "t_s\\\\"} 97739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi }; 97839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 97939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 98039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivivoid CnvIPAPnt( const char16_t IPnt, char * XPnt ) 98139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 98239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char16_t ThisPnt = IPnt; /* local copy of single IPA codepoint */ 98339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int idx; /* index into table */ 984744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi 98539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Convert an individual IPA codepoint. 98639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi A single IPA code could map to a string. 98739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Search the table. If it is not found, use the same character. 98839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Since most codepoints can be contained within 16 bits, 98939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi they are represented as wide chars. */ 99039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi XPnt[0] = 0; /* clear the result string */ 99139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 99239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Search the table for the conversion. */ 9934bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi for (idx = 0; idx < phn_cnt; idx ++) { /* for each item in table */ 994744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if (IPnt == PhnAry[idx].strIPA) { /* matches IPA code */ 9954bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi strcat( XPnt, (const char *)&(PhnAry[idx].strXSAMPA) ); /* copy the XSAMPA string */ 9964bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return; 99739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 9984bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 99939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(XPnt, (const char *)&ThisPnt); /* just copy it */ 100039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 100139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 100239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 100339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** cnvIpaToXsampa 100439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Convert an IPA character string to an XSAMPA character string. 100539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @ipaString - input IPA string to convert 100639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @outXsampaString - converted XSAMPA string is passed back in this parameter 100739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return size of the new string 100839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 10094bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 10104bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Triviint cnvIpaToXsampa( const char16_t * ipaString, size_t ipaStringSize, char ** outXsampaString ) 101139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 10124bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi size_t xsize; /* size of result */ 1013d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi size_t ipidx; /* index into IPA string */ 10144bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi char * XPnt; /* short XSAMPA char sequence */ 101539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 101639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Convert an IPA string to an XSAMPA string and store the xsampa string in *outXsampaString. 101739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi It is the responsibility of the caller to free the allocated string. 101839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Increment through the string. For each base & combination convert it to the XSAMP equivalent. 101939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Because of the XSAMPA limitations, not all IPA characters will be covered. */ 102039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi XPnt = (char *) malloc(6); 10214bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi xsize = (4 * ipaStringSize) + 8; /* assume more than double size */ 1022744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi *outXsampaString = (char *) malloc( xsize );/* allocate return string */ 102339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi *outXsampaString[0] = 0; 1024744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi xsize = 0; /* clear final */ 10254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 1026744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi for (ipidx = 0; ipidx < ipaStringSize; ipidx ++) { /* for each IPA code */ 1027744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi CnvIPAPnt( ipaString[ipidx], XPnt ); /* get converted character */ 1028744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat((char *)*outXsampaString, XPnt ); /* concatenate XSAMPA */ 10294bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 103039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free(XPnt); 1031744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi xsize = strlen(*outXsampaString); /* get the final length */ 103239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return xsize; 103339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 103439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 103539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 103639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/* Google Engine API function implementations */ 1037b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1038b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** init 103939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Allocates Pico memory block and initializes the Pico system. 1040b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * synthDoneCBPtr - Pointer to callback function which will receive generated samples 10415ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi * config - the engine configuration parameters, here only contains the non-system path 10425ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi * for the lingware location 1043b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1044b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 104553a14fa444487d31d735b9a90d01c075be2418baJean-Michel Trivitts_result TtsEngine::init( synthDoneCB_t synthDoneCBPtr, const char *config ) 1046b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 10474bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (synthDoneCBPtr == NULL) { 1048b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Callback pointer is NULL"); 1049b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 1050b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 10514eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 105239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoMemArea = malloc( PICO_MEM_SIZE ); 10534bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!picoMemArea) { 1054b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Failed to allocate memory for Pico system"); 1055b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 1056b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 10574eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 105839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Status ret = pico_initialize( picoMemArea, PICO_MEM_SIZE, &picoSystem ); 10594bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 1060b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Failed to initialize Pico system"); 106139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoMemArea ); 1062b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoMemArea = NULL; 1063b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 1064b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 10654eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1066b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthDoneCBPtr = synthDoneCBPtr; 10674bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 10689b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi picoCurrentLangIndex = -1; 10694bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 10705ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi // was the initialization given an alternative path for the lingware location? 10715ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi if ((config != NULL) && (strlen(config) > 0)) { 10725ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi pico_alt_lingware_path = (char*)malloc(strlen(config)); 10735ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi strcpy((char*)pico_alt_lingware_path, config); 10745ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi LOGV("Alternative lingware path %s", pico_alt_lingware_path); 10755ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi } else { 10765ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi pico_alt_lingware_path = (char*)malloc(strlen(PICO_LINGWARE_PATH)); 10775ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi strcpy((char*)pico_alt_lingware_path, PICO_LINGWARE_PATH); 10785ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi LOGV("Using predefined lingware path %s", pico_alt_lingware_path); 10795ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi } 10805ec310c3cff5d5bde0aad3ba4964a31b89476755Jean-Michel Trivi 1081b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1082b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1083b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 108454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1085b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** shutdown 108654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Unloads all Pico resources; terminates Pico system and frees Pico memory block. 1087b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1088b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 108954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::shutdown( void ) 1090b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1091b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 10924eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 10934bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSystem) { 1094b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen pico_terminate(&picoSystem); 1095b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSystem = NULL; 1096b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 10974bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoMemArea) { 1098b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(picoMemArea); 1099b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoMemArea = NULL; 1100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 11014eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 1103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 110639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 110739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** loadLanguage 110839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Load a new language. 110939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @lang - string with ISO 3 letter language code. 111039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @country - string with ISO 3 letter country code . 111139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 111239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return tts_result 111339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 111439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::loadLanguage(const char *lang, const char *country, const char *variant) 111539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 111639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 111739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi //return setProperty("language", value, size); 111839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 111939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 112039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 112139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** setLanguage 112239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Load a new language (locale). Use the ISO 639-3 language codes. 112339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @lang - string with ISO 639-3 language code. 112439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @country - string with ISO 3 letter country code. 112539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 112639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return tts_result 112739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi */ 112839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::setLanguage( const char * lang, const char * country, const char * variant ) 112939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 1130410a1a0acbd50d7a73f0b2dbfc3e52c0808fc98dJean-Michel Trivi //LOGI("TtsEngine::setLanguage %s %s %s", lang, country, variant); 113139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int langIndex; 113239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int countryIndex; 113339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int i; 113439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 113539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (lang == NULL) 113639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 113739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("TtsEngine::setLanguage called with NULL language"); 113839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 113939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 114039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 114139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We look for a match on the language first 114239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi then we look for a match on the country. 114339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If no match on the language: 114439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return an error. 114539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If match on the language, but no match on the country: 114639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi load the language found for the language match. 114739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If match on the language, and match on the country: 114839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi load the language found for the country match. */ 114939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 115039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Find a match on the language. */ 115139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = -1; /* no match */ 115239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) 115339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 115439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (strcmp(lang, picoSupportedLangIso3[i]) == 0) 115539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 115639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = i; 115739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi break; 115839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 115939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 116039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (langIndex < 0) 116139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 116239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* The language isn't supported. */ 116339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("TtsEngine::setLanguage called with unsupported language"); 116439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 116539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 116639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 116739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Find a match on the country, if there is one. */ 116839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (country != NULL) 116939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 117039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi countryIndex = -1; 117139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = langIndex; i < picoNumSupportedVocs; i ++) 117239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 117339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if ( (strcmp(lang, picoSupportedLangIso3[i]) == 0) 117439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi && (strcmp(country, picoSupportedCountryIso3[i]) == 0)) 117539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 117639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi countryIndex = i; 117739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi break; 117839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 117939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 118039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 118139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (countryIndex < 0) 118239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 118339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We didn't find a match on the country, but we had a match on the language. 118439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Use that language. */ 118539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGI("TtsEngine::setLanguage found matching language(%s) but not matching country(%s).", 118639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi lang, country); 118739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 118839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi else 118939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 119039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We have a match on both the language and the country. */ 119139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = countryIndex; 119239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 119339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 119439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 119539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return doLanguageSwitchFromLangIndex( langIndex ); /* switch the language */ 119639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 119739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 119839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 1199b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi/** isLanguageAvailable 1200b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * Returns the level of support for a language. 1201b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @lang - string with ISO 3 letter language code. 1202b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @country - string with ISO 3 letter country code . 1203b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 12049b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return tts_support_result 1205b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi*/ 1206b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivitts_support_result TtsEngine::isLanguageAvailable(const char *lang, const char *country, 1207b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi const char *variant) { 12089b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int langIndex = -1; 12099b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int countryIndex = -1; 12109b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi //------------------------- 12119b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // language matching 12129b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // if no language specified 12139b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (lang == NULL) { 12149b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi LOGE("TtsEngine::isLanguageAvailable called with no language"); 12159b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_LANG_NOT_SUPPORTED; 12169b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12179b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 12189b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // find a match on the language 121939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (int i = 0; i < picoNumSupportedVocs; i++) 12209b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi { 12219b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (strcmp(lang, picoSupportedLangIso3[i]) == 0) { 12229b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi langIndex = i; 12239b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi break; 12249b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12259b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12269b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (langIndex < 0) { 12279b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // language isn't supported 12289b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi LOGV("TtsEngine::isLanguageAvailable called with unsupported language"); 12299b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_LANG_NOT_SUPPORTED; 12309b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12319b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 12329b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi //------------------------- 12339b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // country matching 12349b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // if no country specified 12359b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if ((country == NULL) || (strlen(country) == 0)) { 12369b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language 12379b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_AVAILABLE : TTS_LANG_MISSING_DATA); 12389b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12394bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 12409b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // find a match on the country 124139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (int i = langIndex; i < picoNumSupportedVocs; i++) { 12429b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if ((strcmp(lang, picoSupportedLangIso3[i]) == 0) 12439b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi && (strcmp(country, picoSupportedCountryIso3[i]) == 0)) { 12449b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi countryIndex = i; 12459b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi break; 12469b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12479b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12489b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (countryIndex < 0) { 12499b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // we didn't find a match on the country, but we had a match on the language 12509b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language 12519b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_AVAILABLE : TTS_LANG_MISSING_DATA); 12529b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 12539b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // we have a match on the language and the country 12549b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi langIndex = countryIndex; 12559b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language + country 12569b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_COUNTRY_AVAILABLE : TTS_LANG_MISSING_DATA); 12579b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12584bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 12599b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // no variants supported in this library, TTS_LANG_COUNTRY_VAR_AVAILABLE cannot be returned. 1260b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi} 1261b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi 12624eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** getLanguage 126454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Get the currently loaded language - if any. 12659b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @lang - string with current ISO 3 letter language code, empty string if no loaded language. 12669b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @country - string with current ISO 3 letter country code, empty string if no loaded language. 12679b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @variant - string with current language variant, empty string if no loaded language. 1268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 12709b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivitts_result TtsEngine::getLanguage(char *language, char *country, char *variant) 12719b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi{ 12729b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (picoCurrentLangIndex == -1) { 12739b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(language, "\0"); 12749b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(country, "\0"); 12759b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(variant, "\0"); 12769b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 12775f6105e73f0c74acd10126175d4952ade10a0b05Jean-Michel Trivi strcpy(language, picoSupportedLangIso3[picoCurrentLangIndex]); 12785f6105e73f0c74acd10126175d4952ade10a0b05Jean-Michel Trivi strcpy(country, picoSupportedCountryIso3[picoCurrentLangIndex]); 12799b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // no variant in this implementation 12809b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(variant, "\0"); 12819b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 12829b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_SUCCESS; 12839b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi} 12849b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 12859b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 12869b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi/** setAudioFormat 12879b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * sets the audio format to use for synthesis, returns what is actually used. 12889b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @encoding - reference to encoding format 12899b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @rate - reference to sample rate 12909b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @channels - reference to number of channels 12919b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return tts_result 12929b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * */ 12939b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivitts_result TtsEngine::setAudioFormat(AudioSystem::audio_format& encoding, uint32_t& rate, 12949b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int& channels) 1295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 12969b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // ignore the input parameters, the enforced audio parameters are fixed here 12979b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi encoding = AudioSystem::PCM_16_BIT; 12989b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi rate = 16000; 12999b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi channels = 1; 13009b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_SUCCESS; 1301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 130354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** setProperty 130554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Set property. The supported properties are: language, rate, pitch and volume. 1306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @property - name of property to set 1307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @value - value to set 1308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @size - size of value 1309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 131154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::setProperty( const char * property, const char * value, const size_t size ) 1312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 131339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int rate; 131439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int pitch; 131539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int volume; 131639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 131739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set a specific property for the engine. 131839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Supported properties include: language (locale), rate, pitch, volume. */ 131954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Sanity check */ 13204bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (property == NULL) { 1321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("setProperty called with property NULL"); 1322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 13234bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 13244eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 13254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (value == NULL) { 1326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("setProperty called with value NULL"); 1327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 13284bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 13294eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 13304bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strncmp(property, "language", 8) == 0) { 133139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Verify it's in correct format. */ 13324bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strlen(value) != 2 && strlen(value) != 6) { 1333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("change language called with incorrect format"); 1334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 13354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 13364eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 133739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Try to switch to specified language. */ 13384bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (doLanguageSwitch(value) == TTS_FAILURE) { 1339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("failed to load language"); 1340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 13414bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 1342b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 13444bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "rate", 4) == 0) { 134539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = atoi(value); 13464bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (rate < PICO_MIN_RATE) { 134739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = PICO_MIN_RATE; 13484bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 13494bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (rate > PICO_MAX_RATE) { 135039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = PICO_MAX_RATE; 13514bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currRate = rate; 1353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 13544bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "pitch", 5) == 0) { 135539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = atoi(value); 13564bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (pitch < PICO_MIN_PITCH) { 135739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = PICO_MIN_PITCH; 13584bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 13594bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (pitch > PICO_MAX_PITCH) { 136039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = PICO_MAX_PITCH; 13614bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currPitch = pitch; 1363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 13644bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "volume", 6) == 0) { 136539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = atoi(value); 13664bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (volume < PICO_MIN_VOLUME) { 136739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = PICO_MIN_VOLUME; 13684bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 13694bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (volume > PICO_MAX_VOLUME) { 137039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = PICO_MAX_VOLUME; 13714bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currVolume = volume; 1373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 13744bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 1377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 137954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** getProperty 138154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Get the property. Supported properties are: language, rate, pitch and volume. 1382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @property - name of property to get 138339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @value - buffer which will receive value of property 138439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @iosize - size of value - if size is too small on return this will contain actual size needed 1385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 138739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::getProperty( const char * property, char * value, size_t * iosize ) 1388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 138939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the property for the engine. 139039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi This property was previously set by setProperty or by default. */ 139154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* sanity check */ 13924bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (property == NULL) { 1393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("getProperty called with property NULL"); 1394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 13954bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 13964eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 13974bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (value == NULL) { 1398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("getProperty called with value NULL"); 1399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 14004bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 14014eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 14024bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strncmp(property, "language", 8) == 0) { 14034bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currLang == NULL) { 1404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, ""); 14054bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 14064bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (*iosize < strlen(picoProp_currLang)+1) { 1407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(picoProp_currLang) + 1; 1408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 140939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 14104bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi strcpy(value, picoProp_currLang); 141139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 14124bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_SUCCESS; 14134bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "rate", 4) == 0) { 1414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmprate[4]; 1415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmprate, "%d", picoProp_currRate); 14164bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (*iosize < strlen(tmprate)+1) { 1417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmprate) + 1; 1418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 1419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmprate); 1421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 14224bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "pitch", 5) == 0) { 1423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmppitch[4]; 1424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmppitch, "%d", picoProp_currPitch); 14254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (*iosize < strlen(tmppitch)+1) { 1426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmppitch) + 1; 1427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 1428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmppitch); 1430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 14314bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "volume", 6) == 0) { 1432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmpvol[4]; 1433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmpvol, "%d", picoProp_currVolume); 14344bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (*iosize < strlen(tmpvol)+1) { 1435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmpvol) + 1; 1436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 14374bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmpvol); 1439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 14404bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 144139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 144239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Unknown property */ 144339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Unsupported property"); 144439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_PROPERTY_UNSUPPORTED; 1445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 144754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** synthesizeText 144954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Synthesizes a text string. 145039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The text string could be annotated with SSML tags. 145139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @text - text to synthesize 145239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @buffer - buffer which will receive generated samples 1453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @bufferSize - size of buffer 1454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @userdata - pointer to user data which will be passed back to callback function 1455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 145739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::synthesizeText( const char * text, int8_t * buffer, size_t bufferSize, void * userdata ) 1458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 145939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int err; 146039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int cbret; 146139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Char * inp = NULL; 1462d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi char * expanded_text = NULL; 146339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Char * local_text = NULL; 146439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi short outbuf[MAX_OUTBUF_SIZE/2]; 146539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Int16 bytes_sent, bytes_recv, text_remaining, out_data_type; 1466b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen pico_Status ret; 146739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi SvoxSsmlParser * parser = NULL; 14684eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 146939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSynthAbort = 0; 14704bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (text == NULL) { 1471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("synthesizeText called with NULL string"); 1472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 14734bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 14744eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 14752821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi if (strlen(text) == 0) { 14762821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi return TTS_SUCCESS; 14772821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi } 14782821fc14ed38e674f41309fc52d5f52a6b9bb1daJean-Michel Trivi 14794bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (buffer == NULL) { 1480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("synthesizeText called with NULL buffer"); 1481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 148239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 14834bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 14844bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if ( (strncmp(text, "<speak", 6) == 0) || (strncmp(text, "<?xml", 5) == 0) ) { 14854bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* SSML input */ 14864bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi parser = new SvoxSsmlParser(); 14874bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (parser && parser->initSuccessful()) { 14884bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi err = parser->parseDocument(text, 1); 14894bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (err == XML_STATUS_ERROR) { 14904bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* Note: for some reason expat always thinks the input document has an error 14914bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi at the end, even when the XML document is perfectly formed */ 14924bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi LOGI("Warning: SSML document parsed with errors"); 14934bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 14944bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi char * parsed_text = parser->getParsedDocument(); 14954bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (parsed_text) { 14964bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* Add property tags to the string - if any. */ 14974bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi local_text = (pico_Char *) doAddProperties( parsed_text ); 14984bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!local_text) { 14994bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi LOGE("Failed to allocate memory for text string"); 15004bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi delete parser; 15014bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 15024bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 15034bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi char * lang = parser->getParsedDocumentLanguage(); 15045da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi if (lang != NULL) { 15055da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi if (doLanguageSwitch(lang) == TTS_FAILURE) { 15065da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi LOGE("Failed to switch to language (%s) specified in SSML document.", lang); 15075da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi delete parser; 15085da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi return TTS_FAILURE; 15095da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi } 15105da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi } else { 15115da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi // lang is NULL, pick a language so the synthesis can be performed 15125da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi if (picoCurrentLangIndex == -1) { 15135da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi // no current language loaded, pick the first one and load it 15145da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi if (doLanguageSwitchFromLangIndex(0) == TTS_FAILURE) { 15155da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi LOGE("Failed to switch to default language."); 15165da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi delete parser; 15175da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi return TTS_FAILURE; 15185da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi } 15195da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi } 15208dda5a28837ae0851ea2d3cc64a69decf8c76668Jean-Michel Trivi //LOGI("No language in SSML, using current language (%s).", picoProp_currLang); 15214bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 15224bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi delete parser; 15234bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 15244bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi LOGE("Failed to parse SSML document"); 15254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi delete parser; 15264bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 15274bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 15284bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 15294bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi LOGE("Failed to create SSML parser"); 15304bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (parser) { 15314bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi delete parser; 15324bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 15334bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 15344bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 15354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 1536d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi /* camelCase pre-processing */ 1537fcc21f46aeca27a74898c1d111f4e153001db2a2Jean-Michel Trivi expanded_text = doCamelCase(text); 15384bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* Add property tags to the string - if any. */ 1539fcc21f46aeca27a74898c1d111f4e153001db2a2Jean-Michel Trivi local_text = (pico_Char *) doAddProperties( expanded_text ); 1540fcc21f46aeca27a74898c1d111f4e153001db2a2Jean-Michel Trivi if (expanded_text) { 1541070c0460fcdfe276cce9dbf49a883d7c6a02c5c4Jean-Michel Trivi free( expanded_text ); 1542fcc21f46aeca27a74898c1d111f4e153001db2a2Jean-Michel Trivi } 15434bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!local_text) { 1544070c0460fcdfe276cce9dbf49a883d7c6a02c5c4Jean-Michel Trivi LOGE("Failed to allocate memory for text string"); 15454bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 15464bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 15484eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 154939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi text_remaining = strlen((const char *) local_text) + 1; 15504eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 155139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi inp = (pico_Char *) local_text; 15524eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen size_t bufused = 0; 15544eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 155554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* synthesis loop */ 15564bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi while (text_remaining) { 15574bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSynthAbort) { 15587bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi ret = pico_resetEngine( picoEngine, PICO_RESET_SOFT ); 1559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 15604bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 15614eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 156254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Feed the text into the engine. */ 156339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_putTextUtf8( picoEngine, inp, text_remaining, &bytes_sent ); 15644bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (ret != PICO_OK) { 1565b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Error synthesizing string '%s': [%d]", text, ret); 15664bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (local_text) { 156739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( local_text ); 156839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 15694bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 15704bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 15714eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1572b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen text_remaining -= bytes_sent; 1573b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen inp += bytes_sent; 15744bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi do { 15754bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSynthAbort) { 15767bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi ret = pico_resetEngine( picoEngine, PICO_RESET_SOFT ); 1577b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 1578b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 157954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Retrieve the samples and add them to the buffer. */ 1580d434f44285f109dfbda5a4e821b89f53d2050ca7Jean-Michel Trivi ret = pico_getData( picoEngine, (void *) outbuf, MAX_OUTBUF_SIZE, &bytes_recv, 15814bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi &out_data_type ); 15824bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (bytes_recv) { 15834bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if ((bufused + bytes_recv) <= bufferSize) { 158439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi memcpy(buffer+bufused, (int8_t *) outbuf, bytes_recv); 1585b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen bufused += bytes_recv; 15864bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 158754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* The buffer filled; pass this on to the callback function. */ 15884bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi cbret = picoSynthDoneCBPtr(userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, 15894bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi bufused, TTS_SYNTH_PENDING); 15904bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (cbret == TTS_CALLBACK_HALT) { 1591b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGI("Halt requested by caller. Halting."); 1592b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 1; 15937bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi ret = pico_resetEngine( picoEngine, PICO_RESET_SOFT ); 1594b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 15954bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1596b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen bufused = 0; 159739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi memcpy(buffer, (int8_t *) outbuf, bytes_recv); 15984eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi bufused += bytes_recv; 1599b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 16004bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1601b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } while (PICO_STEP_BUSY == ret); 16024eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 160339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* This chunk of synthesis is finished; pass the remaining samples. 160454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi Use 16 KHz, 16-bit samples. */ 16054bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!picoSynthAbort) { 16064bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, 16074bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi TTS_SYNTH_PENDING); 1608b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1609b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 0; 16104eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 16114bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (ret != PICO_STEP_IDLE) { 1612de0498d852dc3f1517989ffa06593aa67f8b5d80Charles Chen if (ret != 0){ 1613de0498d852dc3f1517989ffa06593aa67f8b5d80Charles Chen LOGE("Error occurred during synthesis [%d]", ret); 1614de0498d852dc3f1517989ffa06593aa67f8b5d80Charles Chen } 16154bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (local_text) { 16164bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi free(local_text); 16174bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 161839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGV("Synth loop: sending TTS_SYNTH_DONE after error"); 16194bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, 16204bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi TTS_SYNTH_DONE); 16217bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi pico_resetEngine( picoEngine, PICO_RESET_SOFT ); 1622b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 1623b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1624b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 16254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 162639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Synthesis is done; notify the caller */ 162739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGV("Synth loop: sending TTS_SYNTH_DONE after all done, or was asked to stop"); 16284bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, 16294bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi TTS_SYNTH_DONE); 16304eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 163139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (local_text) { 163239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( local_text ); 163339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1634b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1635b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1636b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 163754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 163854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1639b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** stop 164054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Aborts the running synthesis. 1641b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1642b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 164339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::stop( void ) 1644b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1645b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 1; 1646b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1647b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1648b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 164954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1650b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus 1651b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" { 1652b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 1653b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 165439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TriviTtsEngine * getTtsEngine( void ) 1655b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1656b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return new TtsEngine(); 1657b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1658b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1659b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus 1660b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1661b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 1662b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1663