com_svox_picottsengine.cpp revision de0498d852dc3f1517989ffa06593aa67f8b5d80
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 */ 32b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 33b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdio.h> 34b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <unistd.h> 354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi#include <stdlib.h> 36b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 37b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define LOG_TAG "SVOX Pico Engine" 38b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 39b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <utils/Log.h> 4039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include <utils/String16.h> /* for strlen16 */ 41b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <android_runtime/AndroidRuntime.h> 42b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <tts/TtsEngine.h> 4339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include <cutils/jstring.h> 44b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <picoapi.h> 45b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <picodefs.h> 4639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#include "svox_ssml_parser.h" 47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 48b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenusing namespace android; 49b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* adaptation layer defines */ 514eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi#define PICO_MEM_SIZE 2500000 5254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking rate */ 5339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_RATE 20 54b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_RATE 500 5539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_DEF_RATE 100 5654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking pitch */ 5739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_PITCH 50 58b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_PITCH 200 5939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_DEF_PITCH 100 6054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* speaking volume */ 6139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_MIN_VOLUME 0 62b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICO_MAX_VOLUME 500 6339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi#define PICO_DEF_VOLUME 250 6439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 6554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* string constants */ 66b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define MAX_OUTBUF_SIZE 128 6739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_LINGWARE_PATH = "/sdcard/svox/"; 6839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOICE_NAME = "PicoVoice"; 6939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_SPEED_OPEN_TAG = "<speed level='%d'>"; 7039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_SPEED_CLOSE_TAG = "</speed>"; 7139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PITCH_OPEN_TAG = "<pitch level='%d'>"; 7239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PITCH_CLOSE_TAG = "</pitch>"; 7339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOLUME_OPEN_TAG = "<volume level='%d'>"; 7439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_VOLUME_CLOSE_TAG = "</volume>"; 7539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * PICO_PHONEME_OPEN_TAG = "<phoneme ph='"; 764bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Triviconst char * PICO_PHONEME_CLOSE_TAG = "'/>"; 7739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 7839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/* supported voices 7939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Pico does not seperately specify the voice and locale. */ 8039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedLangIso3[] = { "eng", "eng", "deu", "spa", "fra", "ita" }; 8139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedCountryIso3[] = { "USA", "GBR", "DEU", "ESP", "FRA", "ITA" }; 821ee916b1cdb8e54192a4d11d7fae4cd0953baadbJean-Michel Triviconst char * picoSupportedLang[] = { "en-US", "en-GB", "de-DE", "es-ES", "fr-FR", "it-IT" }; 8339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoInternalLang[] = { "en-US", "en-GB", "de-DE", "es-ES", "fr-FR", "it-IT" }; 8439358f0dacad8cece6c2d3ef1055030f57090c79Jean-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" }; 8539358f0dacad8cece6c2d3ef1055030f57090c79Jean-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" }; 8639358f0dacad8cece6c2d3ef1055030f57090c79Jean-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" }; 8739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst int picoNumSupportedVocs = 6; 88b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 8954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* supported properties */ 9039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst char * picoSupportedProperties[] = { "language", "rate", "pitch", "volume" }; 9139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Triviconst int picoNumSupportedProperties = 4; 92b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 9354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 9454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi/* adapation layer global variables */ 9539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TrivisynthDoneCB_t * picoSynthDoneCBPtr; 9639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivivoid * picoMemArea = NULL; 9739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_System picoSystem = NULL; 9839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoTaResource = NULL; 9939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoSgResource = NULL; 10039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Resource picoUtppResource = NULL; 10139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Engine picoEngine = NULL; 10239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoTaFileName = NULL; 10339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoSgFileName = NULL; 10439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoUtppFileName = NULL; 10539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoTaResourceName = NULL; 10639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoSgResourceName = NULL; 10739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivipico_Char * picoUtppResourceName = NULL; 10854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoSynthAbort = 0; 10939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivichar * picoProp_currLang = NULL; /* current language */ 11054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currRate = PICO_DEF_RATE; /* current rate */ 11154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currPitch = PICO_DEF_PITCH; /* current pitch */ 11254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Triviint picoProp_currVolume = PICO_DEF_VOLUME; /* current volume */ 11354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1149b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Triviint picoCurrentLangIndex = -1; 115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* internal helper functions */ 118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 11939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** checkForLocale 12039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Check whether the requested locale is among the supported locales. 1211ee916b1cdb8e54192a4d11d7fae4cd0953baadbJean-Michel Trivi * @locale - the locale to check, either in xx or xx-YY format 12239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return index of the locale, or -1 if not supported. 123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 12439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic int checkForLocale( const char * locale ) 125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 12654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi int found = -1; /* language not found */ 12739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int i; 12839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (locale == NULL) { 1295da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi LOGE("checkForLocale called with NULL language"); 1304bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return found; 13139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 13254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 13354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Verify that the requested locale is a locale that we support. */ 1344bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) { 1354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strcmp(locale, picoSupportedLang[i]) == 0) { /* in array */ 136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen found = i; 137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 13954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi }; 14039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 14139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* The locale was not found. */ 1424bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (found < 0) { 14354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* We didn't find an exact match; it may have been specified with only the first 2 characters. 14439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi This could overmatch ISO 639-3 language codes.%% */ 1454bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) { 1464bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strncmp(locale, picoSupportedLang[i], 2) == 0) { 147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen found = i; 148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1514bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (found < 0) { 15239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("TtsEngine::set language called with unsupported locale"); 153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 15454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi }; 155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return found; 156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 15854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** cleanResources 16054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Unloads any loaded Pico resources. 161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 16254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivistatic void cleanResources( void ) 163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1644bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoEngine) { 16554823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_disposeEngine( picoSystem, &picoEngine ); 16639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_releaseVoiceDefinition( picoSystem, (pico_Char *) PICO_VOICE_NAME ); 167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoEngine = NULL; 168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1694bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoUtppResource) { 17054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoUtppResource ); 171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppResource = NULL; 172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1734bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoTaResource) { 17454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoTaResource ); 175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaResource = NULL; 176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1774bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSgResource) { 17854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi pico_unloadResource( picoSystem, &picoSgResource ); 179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgResource = NULL; 180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1819b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi picoCurrentLangIndex = -1; 182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 18454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** cleanFiles 18654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Frees any memory allocated for file and resource strings. 187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 18854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivistatic void cleanFiles( void ) 189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1904bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currLang) { 19139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoProp_currLang ); 192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currLang = NULL; 193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1944eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1954bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoTaFileName) { 19639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoTaFileName ); 197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaFileName = NULL; 198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1994eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2004bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSgFileName) { 20139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoSgFileName ); 202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgFileName = NULL; 203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2044eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2054bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoUtppFileName) { 20639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoUtppFileName ); 207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppFileName = NULL; 208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2094eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2104bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoTaResourceName) { 21139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoTaResourceName ); 212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoTaResourceName = NULL; 213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2144eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2154bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSgResourceName) { 21639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoSgResourceName ); 217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSgResourceName = NULL; 218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 2194eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 2204bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoUtppResourceName) { 22139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoUtppResourceName ); 222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoUtppResourceName = NULL; 223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 2269b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi/** hasResourcesForLanguage 2279b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * Check to see if the resources required to load the language at the specified index 2289b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * are properly installed 2299b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @langIndex - the index of the language to check the resources for. The index is valid. 2309b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return true if the required resources are installed, false otherwise 2319b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi */ 2329b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivistatic bool hasResourcesForLanguage(int langIndex) { 2339b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi FILE * pFile; 2349b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi char* fileName = (char*)malloc(PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE); 2354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 2369b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy((char*)fileName, PICO_LINGWARE_PATH); 2379b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcat((char*)fileName, (const char*)picoInternalTaLingware[langIndex]); 2384bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi pFile = fopen(fileName, "r"); 2394bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (pFile == NULL) { 2409b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2419b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return false; 2429b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 2439b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi fclose (pFile); 2449b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 2459b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 2469b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy((char*)fileName, PICO_LINGWARE_PATH); 2479b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcat((char*)fileName, (const char*)picoInternalSgLingware[langIndex]); 2489b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi pFile = fopen(fileName, "r"); 2499b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (pFile == NULL) { 2509b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2519b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return false; 2529b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 2539b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi fclose(pFile); 2549b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi free(fileName); 2559b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return true; 2569b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 2579b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi} 2589b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 2594eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi/** doLanguageSwitchFromLangIndex 26039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Switch to the requested locale. 26139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If the locale is already loaded, it returns immediately. 26239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If another locale is already is loaded, it will first be unloaded and the new one then loaded. 26339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If no locale is loaded, the requested locale will be loaded. 26439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @langIndex - the index of the locale/voice to load, which is guaranteed to be supported. 265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return TTS_SUCCESS or TTS_FAILURE 2664eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi */ 26739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic tts_result doLanguageSwitchFromLangIndex( int langIndex ) 268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 26939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int ret; /* function result code */ 27039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 27139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* If we already have a loaded locale, check whether it is the same one as requested. */ 2724bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currLang && (strcmp(picoProp_currLang, picoSupportedLang[langIndex]) == 0)) { 2734eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGI("Language already loaded (%s == %s)", picoProp_currLang, picoSupportedLang[langIndex]); 274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 27739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* It is not the same locale; unload the current one first. */ 278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 2794eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 28039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Allocate memory for file and resource names. */ 281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 28239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoProp_currLang = (char *) malloc( 10 ); 28339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoTaFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 28439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSgFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 28539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoUtppFileName = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE ); 28639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoTaResourceName = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 28739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSgResourceName = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 28839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoUtppResourceName =(pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE ); 28939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 29039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set the path and file names for resource files. */ 29139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy((char *) picoTaFileName, PICO_LINGWARE_PATH); 29239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoTaFileName, (const char *) picoInternalTaLingware[langIndex]); 29339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy((char *) picoSgFileName, PICO_LINGWARE_PATH); 29439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoSgFileName, (const char *) picoInternalSgLingware[langIndex]); 29539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy((char *) picoUtppFileName, PICO_LINGWARE_PATH); 29639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat((char *) picoUtppFileName, (const char *) picoInternalUtppLingware[langIndex]); 29739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 29839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the text analysis Lingware resource file. */ 29939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoTaFileName, &picoTaResource ); 3004bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3014eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load textana resource for %s [%d]", picoSupportedLang[langIndex], ret); 302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3064eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 30739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the signal generation Lingware resource file. */ 30839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoSgFileName, &picoSgResource ); 3094bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3104eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load siggen resource for %s [%d]", picoSupportedLang[langIndex], ret); 311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3154eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 31639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the utpp Lingware resource file if exists - NOTE: this file is optional 31739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi and is currently not used. Loading is only attempted for future compatibility. 31839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If this file is not present the loading will still succeed. */ 31939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_loadResource( picoSystem, picoUtppFileName, &picoUtppResource ); 3204bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if ((PICO_OK != ret) && (ret != PICO_EXC_CANT_OPEN_FILE)) { 3214eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to load utpp resource for %s [%d]", picoSupportedLang[langIndex], ret); 322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 3254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 3264eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 32739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the text analysis resource name. */ 32839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoTaResource, (char *) picoTaResourceName ); 3294bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3304eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get textana resource name for %s [%d]", picoSupportedLang[langIndex], ret); 331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3354eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 33639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the signal generation resource name. */ 33739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoSgResource, (char *) picoSgResourceName ); 338744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if ((PICO_OK == ret) && (picoUtppResource != NULL)) { 33939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get utpp resource name - optional: see note above. */ 34039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_getResourceName( picoSystem, picoUtppResource, (char *) picoUtppResourceName ); 3414bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3424eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get utpp resource name for %s [%d]", picoSupportedLang[langIndex], ret); 343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3484bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3494eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to get siggen resource name for %s [%d]", picoSupportedLang[langIndex], ret); 350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 351b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3544eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 35539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Create a voice definition. */ 35639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_createVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME ); 3574bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3584eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to create voice for %s [%d]", picoSupportedLang[langIndex], ret); 359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3634eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 36439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add the text analysis resource to the voice. */ 36539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoTaResourceName ); 3664bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3674eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add textana resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3724eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 37339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add the signal generation resource to the voice. */ 37439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoSgResourceName ); 375744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if ((PICO_OK == ret) && (picoUtppResource != NULL)) { 37639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Add utpp resource to voice - optional: see note above. */ 37739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoUtppResourceName ); 3784bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3794eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add utpp resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 3854eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 3864bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3874eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to add siggen resource to voice for %s [%d]", picoSupportedLang[langIndex], ret); 388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 39339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_newEngine( picoSystem, (const pico_Char *) PICO_VOICE_NAME, &picoEngine ); 3944bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 3954eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi LOGE("Failed to create engine for %s [%d]", picoSupportedLang[langIndex], ret); 396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4004eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 40139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set the current locale/voice. */ 40239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcpy( picoProp_currLang, picoSupportedLang[langIndex] ); 4035da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi picoCurrentLangIndex = langIndex; 404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGI("loaded %s successfully", picoProp_currLang); 405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 40839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 4094eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi/** doLanguageSwitch 41039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Switch to the requested locale. 41139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If this locale is already loaded, it returns immediately. 41239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If another locale is already loaded, this will first be unloaded 41339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * and the new one then loaded. 41439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * If no locale is loaded, the requested will be loaded. 4151ee916b1cdb8e54192a4d11d7fae4cd0953baadbJean-Michel Trivi * @locale - the locale to check, either in xx or xx-YY format (i.e "en" or "en-US") 4164eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi * return TTS_SUCCESS or TTS_FAILURE 4174eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi*/ 41839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic tts_result doLanguageSwitch( const char * locale ) 4194eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi{ 42039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int loclIndex; /* locale index */ 4214eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 42239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Load the new locale. */ 42339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi loclIndex = checkForLocale( locale ); 4244bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (loclIndex < 0) { 42539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Tried to swith to non-supported locale %s", locale); 42639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 4274bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 42839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGI("Found supported locale %s", picoSupportedLang[loclIndex]); 42939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return doLanguageSwitchFromLangIndex( loclIndex ); 4304eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi} 4314eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 43239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** doAddProperties 43439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Add <speed>, <pitch> and <volume> tags to the text, 43539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * if the properties have been set to non-default values, and return the new string. 43639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The calling function is responsible for freeing the returned string. 437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @str - text to apply tags to 438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return new string with tags applied 439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 44039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivistatic char * doAddProperties( const char * str ) 441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 44239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * data = NULL; 44339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int haspitch, hasspeed, hasvol; /* parameters */ 44439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int textlen; /* property string length */ 4454eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 44639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi haspitch = 0; hasspeed = 0; hasvol = 0; 44739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi textlen = strlen(str) + 1; 4484bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currPitch != PICO_DEF_PITCH) { /* non-default pitch */ 449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_PITCH_OPEN_TAG) + 5; 450b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_PITCH_CLOSE_TAG); 451b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen haspitch = 1; 452b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4534bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currRate != PICO_DEF_RATE) { /* non-default rate */ 454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_SPEED_OPEN_TAG) + 5; 455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_SPEED_CLOSE_TAG); 456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hasspeed = 1; 457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4584bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currVolume != PICO_DEF_VOLUME) { /* non-default volume */ 459b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_VOLUME_OPEN_TAG) + 5; 460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen textlen += strlen(PICO_VOLUME_CLOSE_TAG); 461b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen hasvol = 1; 462b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4634eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 46439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Compose the property strings. */ 46539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi data = (char *) malloc( textlen ); /* allocate string */ 4664bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!data) { 467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return NULL; 468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 46954823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi memset(data, 0, textlen); /* clear it */ 4704bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (haspitch) { 471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_PITCH_OPEN_TAG) + strlen(PICO_PITCH_CLOSE_TAG) + 5); 472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_PITCH_OPEN_TAG, picoProp_currPitch); 473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4764eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 4774bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (hasspeed) { 478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_SPEED_OPEN_TAG) + strlen(PICO_SPEED_CLOSE_TAG) + 5); 479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_SPEED_OPEN_TAG, picoProp_currRate); 480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4834eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 4844bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (hasvol) { 485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char* tmp = (char*)malloc(strlen(PICO_VOLUME_OPEN_TAG) + strlen(PICO_VOLUME_CLOSE_TAG) + 5); 486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmp, PICO_VOLUME_OPEN_TAG, picoProp_currVolume); 487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, tmp); 488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(tmp); 489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4904eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, str); 4924eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 4934bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (hasvol) { 494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_VOLUME_CLOSE_TAG); 495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 4964eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 4974bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (hasspeed) { 498b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_SPEED_CLOSE_TAG); 499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5004eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 5014bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (haspitch) { 502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcat(data, PICO_PITCH_CLOSE_TAG); 503b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 5044eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return data; 506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 50854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 50939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** createPhonemeString 51039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Wrap all individual words in <phoneme> tags. 51139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The Pico <phoneme> tag only supports one word in each tag, 51239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * therefore they must be individually wrapped! 51339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @xsampa - text to convert to Pico phomene string 51439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @length - length of the input string 51539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return new string with tags applied 51639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 5174bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Triviextern char * createPhonemeString( const char * xsampa, int length ) 51839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 51939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char * convstring = NULL; 52039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int origStrLen = strlen(xsampa); 52139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int numWords = 1; 52239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int start, totalLength, i, j; 52339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 524744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi for (i = 0; i < origStrLen; i ++) { 525744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if ((xsampa[i] == ' ') || (xsampa[i] == '#')) { 526744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi numWords ++; 527744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 528744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 529744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi 530744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if (numWords == 1) { 531744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi convstring = new char[origStrLen + 17]; 532744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi convstring[0] = '\0'; 533744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(convstring, PICO_PHONEME_OPEN_TAG); 534744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(convstring, xsampa); 535744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(convstring, PICO_PHONEME_CLOSE_TAG); 536744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } else { 537744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi char * words[numWords]; 538744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi start = 0; totalLength = 0; i = 0; j = 0; 539744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi for (i=0, j=0; i < origStrLen; i++) { 540744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if ((xsampa[i] == ' ') || (xsampa[i] == '#')) { 541744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi words[j] = new char[i+1-start+17]; 542744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi words[j][0] = '\0'; 543744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat( words[j], PICO_PHONEME_OPEN_TAG); 544744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strncat(words[j], xsampa+start, i-start); 545744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat( words[j], PICO_PHONEME_CLOSE_TAG); 546744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi start = i + 1; 547744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi j++; 548744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi totalLength += strlen(words[j-1]); 549744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 550744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 551744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi words[j] = new char[i+1-start+17]; 552744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi words[j][0] = '\0'; 553744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(words[j], PICO_PHONEME_OPEN_TAG); 554744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(words[j], xsampa+start); 555744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(words[j], PICO_PHONEME_CLOSE_TAG); 556744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi totalLength += strlen(words[j]); 557744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi convstring = new char[totalLength + 1]; 558744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi convstring[0] = '\0'; 559744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi for (i=0 ; i < numWords ; i++) { 560744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat(convstring, words[i]); 561744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi delete [] words[i]; 562744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 563744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi } 564744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi 565744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi return convstring; 56639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 56739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 5684bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi/* The XSAMPA uses as many as 5 characters to represent a single IPA code. */ 56939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitypedef struct tagPhnArr 5704bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi{ 57139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char16_t strIPA; /* IPA Unicode symbol */ 5724bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi char strXSAMPA[6]; /* SAMPA sequence */ 5734bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi} PArr; 57439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 5754bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi#define phn_cnt (134) 57639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 57739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TriviPArr PhnAry[phn_cnt] = { 57839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 57939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* XSAMPA conversion table */ 58039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 581744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi /* Vowels (23) incomplete */ 58239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025B, "E"}, 58339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0251, "A"}, 58439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0254, "O"}, 58539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00F8, "2"}, 58639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0153, "9"}, 58739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0276, "&"}, 58839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0252, "Q"}, 58939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028C, "V"}, 59039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0264, "7"}, 59139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026F, "M"}, 59239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0268, "1"}, 59339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0289, "}"}, 59439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026A, "I"}, 59539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028F, "Y"}, 59639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028A, "U"}, 59739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0259, "@"}, 59839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0275, "8"}, 59939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0250, "6"}, 60039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00E6, "{"}, 60139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x025C, "3"}, 6024bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x025A, "@`"}, 6034bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x025E, "3\\\\"}, 6044bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0258, "@\\\\"}, 60539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 606744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi /* Consonants (60) incomplete */ 6074bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0288, "t`"}, 6084bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0256, "d`"}, 6094bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x025F, "J\\\\"}, 61039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0261, "g"}, 6114bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0262, "G\\\\"}, 61239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0294, "?"}, 61339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0271, "F"}, 6144bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0273, "n`"}, 61539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0272, "J"}, 61639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x014B, "N"}, 6174bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0274, "N\\\\"}, 6184bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0299, "B\\\\"}, 6194bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0280, "R\\\\"}, 62039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x027E, "4"}, 6214bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x027D, "r`"}, 6224bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0278, "p\\\\"}, 62339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03B2, "B"}, 62439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03B8, "T"}, 62539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00F0, "D"}, 62639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0283, "S"}, 62739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0292, "Z"}, 6284bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0282, "s`"}, 6294bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0290, "z`"}, 63039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x00E7, "C"}, 6314bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x029D, "j\\\\"}, 63239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0263, "G"}, 63339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x03C7, "X"}, 63439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0281, "R"}, 6354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0127, "X\\\\"}, 6364bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0295, "?\\\\"}, 6374bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0266, "h\\\\"}, 63839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026C, "K"}, 6394bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x026E, "K\\\\"}, 64039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028B, "P"}, 6414bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0279, "r\\\\"}, 6424bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x027B, "r\\\\'"}, 6434bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0270, "M\\\\"}, 6444bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x026D, "l`"}, 64539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028E, "L"}, 6464bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x029F, "L\\\\"}, 64739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0253, "b_<"}, 64839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0257, "d_<"}, 64939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0284, "J\\_<"}, 65039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0260, "g_<"}, 65139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x029B, "G\\_<"}, 65239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x028D, "W"}, 65339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0265, "H"}, 6544bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x029C, "H\\\\"}, 6554bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02A1, ">\\\\"}, 6564bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02A2, "<\\\\"}, 6574bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0298, "O\\\\"}, 6584bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x01C0, "|\\\\"}, 6594bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x01C3, "!\\\\"}, 66039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x01C2, "=\\"}, 66139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x01C1, "|\\|\\"}, 6624bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x027A, "l\\\\"}, 6634bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0255, "s\\\\"}, 6644bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0291, "z\\\\"}, 6654bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0267, "x\\\\"}, 66639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x026B, "l_G"}, 66739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 668744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi /* Diacritics (34) incomplete */ 66939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02BC, "_>"}, 67039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0325, "_0"}, 67139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x030A, "_0"}, 67239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x032C, "_v"}, 67339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B0, "_h"}, 67439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0324, "_t"}, 67539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0330, "_k"}, 67639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033C, "_N"}, 67739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x032A, "_d"}, 67839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033A, "_a"}, 67939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033B, "_m"}, 68039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0339, "_O"}, 68139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031C, "_c"}, 68239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031F, "_+"}, 68339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0320, "_-"}, 6844bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x0308, "_\""}, /* centralized */ 68539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x033D, "_x"}, 68639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0318, "_A"}, 68739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0319, "_q"}, 6884bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02DE, "`"}, 68939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B7, "_w"}, 69039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02B2, "_j"}, 69139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02E0, "_G"}, 6924bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02E4, "_?\\\\"}, 69339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0303, "~"}, 69439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x207F, "_n"}, 69539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02E1, "_l"}, 69639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031A, "_}"}, 69739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0334, "_e"}, 69839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031D, "_r"}, 69939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x031E, "_o"}, 70039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0329, "="}, 70139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x032F, "_^"}, 70239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02D0, ":"}, 70339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 7044bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* Others (11) complete */ 70539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0361, "_"}, 70639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x035C, "_"}, 7074bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02C8, "\""}, 70839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02CC, "%"}, 7094bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02D1, ":\\\\"}, 71039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x0306, "_X"}, 71139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x2016, "||"}, 7124bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x203F, "-\\\\"}, 71339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x2197, "<R>"}, 71439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x2198, "<F>"}, 7154bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x025D, "3`"}, 71639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 71739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Affricates (6) complete */ 71839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A3, "d_z"}, 71939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A4, "d_Z"}, 7204bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02A5, "d_z\\\\"}, 72139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A6, "t_s"}, 72239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi {0x02A7, "t_S"}, 7234bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi {0x02A8, "t_s\\\\"} 72439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi }; 72539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 72639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 72739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivivoid CnvIPAPnt( const char16_t IPnt, char * XPnt ) 72839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 72939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi char16_t ThisPnt = IPnt; /* local copy of single IPA codepoint */ 73039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int idx; /* index into table */ 731744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi 73239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Convert an individual IPA codepoint. 73339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi A single IPA code could map to a string. 73439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Search the table. If it is not found, use the same character. 73539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Since most codepoints can be contained within 16 bits, 73639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi they are represented as wide chars. */ 73739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi XPnt[0] = 0; /* clear the result string */ 73839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 73939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Search the table for the conversion. */ 7404bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi for (idx = 0; idx < phn_cnt; idx ++) { /* for each item in table */ 741744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi if (IPnt == PhnAry[idx].strIPA) { /* matches IPA code */ 7424bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi strcat( XPnt, (const char *)&(PhnAry[idx].strXSAMPA) ); /* copy the XSAMPA string */ 7434bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return; 74439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 7454bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 74639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi strcat(XPnt, (const char *)&ThisPnt); /* just copy it */ 74739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 74839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 74939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 75039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** cnvIpaToXsampa 75139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Convert an IPA character string to an XSAMPA character string. 75239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @ipaString - input IPA string to convert 75339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @outXsampaString - converted XSAMPA string is passed back in this parameter 75439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return size of the new string 75539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 7564bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 7574bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Triviint cnvIpaToXsampa( const char16_t * ipaString, size_t ipaStringSize, char ** outXsampaString ) 75839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 7594bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi size_t xsize; /* size of result */ 7604bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi int ipidx; /* index into IPA string */ 7614bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi char * XPnt; /* short XSAMPA char sequence */ 76239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 76339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Convert an IPA string to an XSAMPA string and store the xsampa string in *outXsampaString. 76439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi It is the responsibility of the caller to free the allocated string. 76539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Increment through the string. For each base & combination convert it to the XSAMP equivalent. 76639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Because of the XSAMPA limitations, not all IPA characters will be covered. */ 76739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi XPnt = (char *) malloc(6); 7684bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi xsize = (4 * ipaStringSize) + 8; /* assume more than double size */ 769744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi *outXsampaString = (char *) malloc( xsize );/* allocate return string */ 77039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi *outXsampaString[0] = 0; 771744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi xsize = 0; /* clear final */ 7724bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 773744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi for (ipidx = 0; ipidx < ipaStringSize; ipidx ++) { /* for each IPA code */ 774744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi CnvIPAPnt( ipaString[ipidx], XPnt ); /* get converted character */ 775744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi strcat((char *)*outXsampaString, XPnt ); /* concatenate XSAMPA */ 7764bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 77739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free(XPnt); 778744a0e6d86f037a9f815adbcbb2dc5f410aa5007Jean-Michel Trivi xsize = strlen(*outXsampaString); /* get the final length */ 77939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return xsize; 78039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 78139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 78239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 78339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/* Google Engine API function implementations */ 784b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 785b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** init 78639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Allocates Pico memory block and initializes the Pico system. 787b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * synthDoneCBPtr - Pointer to callback function which will receive generated samples 788b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 789b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 79054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::init( synthDoneCB_t synthDoneCBPtr ) 791b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 7924bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (synthDoneCBPtr == NULL) { 793b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Callback pointer is NULL"); 794b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 795b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 7964eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 79739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoMemArea = malloc( PICO_MEM_SIZE ); 7984bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!picoMemArea) { 799b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Failed to allocate memory for Pico system"); 800b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 801b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 8024eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 80339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Status ret = pico_initialize( picoMemArea, PICO_MEM_SIZE, &picoSystem ); 8044bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (PICO_OK != ret) { 805b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Failed to initialize Pico system"); 80639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( picoMemArea ); 807b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoMemArea = NULL; 808b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 809b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 8104eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 811b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthDoneCBPtr = synthDoneCBPtr; 8124bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 8139b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi picoCurrentLangIndex = -1; 8144bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 815b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 816b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 817b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 81854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 819b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** shutdown 82054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Unloads all Pico resources; terminates Pico system and frees Pico memory block. 821b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 822b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 82354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::shutdown( void ) 824b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 825b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanResources(); 8264eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 8274bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSystem) { 828b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen pico_terminate(&picoSystem); 829b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSystem = NULL; 830b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 8314bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoMemArea) { 832b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen free(picoMemArea); 833b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoMemArea = NULL; 834b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 8354eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 836b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen cleanFiles(); 837b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 838b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 839b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 84039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 84139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** loadLanguage 84239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Load a new language. 84339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @lang - string with ISO 3 letter language code. 84439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @country - string with ISO 3 letter country code . 84539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 84639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return tts_result 84739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi*/ 84839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::loadLanguage(const char *lang, const char *country, const char *variant) 84939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 85039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 85139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi //return setProperty("language", value, size); 85239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 85339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 85439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 85539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi/** setLanguage 85639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * Load a new language (locale). Use the ISO 639-3 language codes. 85739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @lang - string with ISO 639-3 language code. 85839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @country - string with ISO 3 letter country code. 85939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 86039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * return tts_result 86139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi */ 86239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::setLanguage( const char * lang, const char * country, const char * variant ) 86339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi{ 86439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int langIndex; 86539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int countryIndex; 86639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int i; 86739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 86839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (lang == NULL) 86939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 87039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("TtsEngine::setLanguage called with NULL language"); 87139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 87239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 87339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 87439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We look for a match on the language first 87539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi then we look for a match on the country. 87639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If no match on the language: 87739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return an error. 87839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If match on the language, but no match on the country: 87939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi load the language found for the language match. 88039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi If match on the language, and match on the country: 88139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi load the language found for the country match. */ 88239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 88339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Find a match on the language. */ 88439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = -1; /* no match */ 88539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = 0; i < picoNumSupportedVocs; i ++) 88639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 88739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (strcmp(lang, picoSupportedLangIso3[i]) == 0) 88839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 88939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = i; 89039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi break; 89139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 89239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 89339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (langIndex < 0) 89439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 89539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* The language isn't supported. */ 89639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("TtsEngine::setLanguage called with unsupported language"); 89739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 89839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 89939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 90039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Find a match on the country, if there is one. */ 90139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (country != NULL) 90239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 90339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi countryIndex = -1; 90439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (i = langIndex; i < picoNumSupportedVocs; i ++) 90539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 90639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if ( (strcmp(lang, picoSupportedLangIso3[i]) == 0) 90739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi && (strcmp(country, picoSupportedCountryIso3[i]) == 0)) 90839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 90939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi countryIndex = i; 91039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi break; 91139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 91239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 91339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 91439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (countryIndex < 0) 91539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 91639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We didn't find a match on the country, but we had a match on the language. 91739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Use that language. */ 91839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGI("TtsEngine::setLanguage found matching language(%s) but not matching country(%s).", 91939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi lang, country); 92039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 92139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi else 92239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi { 92339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* We have a match on both the language and the country. */ 92439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi langIndex = countryIndex; 92539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 92639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 92739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 92839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return doLanguageSwitchFromLangIndex( langIndex ); /* switch the language */ 92939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi} 93039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 93139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 932b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi/** isLanguageAvailable 933b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * Returns the level of support for a language. 934b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @lang - string with ISO 3 letter language code. 935b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @country - string with ISO 3 letter country code . 936b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi * @variant - string with language variant for that language and country pair. 9379b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return tts_support_result 938b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi*/ 939b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivitts_support_result TtsEngine::isLanguageAvailable(const char *lang, const char *country, 940b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi const char *variant) { 9419b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int langIndex = -1; 9429b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int countryIndex = -1; 9439b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi //------------------------- 9449b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // language matching 9459b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // if no language specified 9469b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (lang == NULL) { 9479b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi LOGE("TtsEngine::isLanguageAvailable called with no language"); 9489b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_LANG_NOT_SUPPORTED; 9499b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 9509b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 9519b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // find a match on the language 95239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (int i = 0; i < picoNumSupportedVocs; i++) 9539b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi { 9549b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (strcmp(lang, picoSupportedLangIso3[i]) == 0) { 9559b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi langIndex = i; 9569b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi break; 9579b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 9589b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 9599b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (langIndex < 0) { 9609b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // language isn't supported 9619b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi LOGV("TtsEngine::isLanguageAvailable called with unsupported language"); 9629b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_LANG_NOT_SUPPORTED; 9639b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 9649b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 9659b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi //------------------------- 9669b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // country matching 9679b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // if no country specified 9689b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if ((country == NULL) || (strlen(country) == 0)) { 9699b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language 9709b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_AVAILABLE : TTS_LANG_MISSING_DATA); 9719b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 9724bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 9739b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // find a match on the country 97439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi for (int i = langIndex; i < picoNumSupportedVocs; i++) { 9759b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if ((strcmp(lang, picoSupportedLangIso3[i]) == 0) 9769b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi && (strcmp(country, picoSupportedCountryIso3[i]) == 0)) { 9779b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi countryIndex = i; 9789b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi break; 9799b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 9809b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 9819b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (countryIndex < 0) { 9829b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // we didn't find a match on the country, but we had a match on the language 9839b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language 9849b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_AVAILABLE : TTS_LANG_MISSING_DATA); 9859b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 9869b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // we have a match on the language and the country 9879b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi langIndex = countryIndex; 9889b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // check installation of matched language + country 9899b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return (hasResourcesForLanguage(langIndex) ? TTS_LANG_COUNTRY_AVAILABLE : TTS_LANG_MISSING_DATA); 9909b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 9914bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 9929b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // no variants supported in this library, TTS_LANG_COUNTRY_VAR_AVAILABLE cannot be returned. 993b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi} 994b8f46add889c597c8c305691b1aa656d68bfa5c8Jean-Michel Trivi 9954eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 996b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** getLanguage 99754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Get the currently loaded language - if any. 9989b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @lang - string with current ISO 3 letter language code, empty string if no loaded language. 9999b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @country - string with current ISO 3 letter country code, empty string if no loaded language. 10009b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @variant - string with current language variant, empty string if no loaded language. 1001b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1002b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 10039b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivitts_result TtsEngine::getLanguage(char *language, char *country, char *variant) 10049b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi{ 10059b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi if (picoCurrentLangIndex == -1) { 10069b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(language, "\0"); 10079b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(country, "\0"); 10089b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(variant, "\0"); 10099b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } else { 10105f6105e73f0c74acd10126175d4952ade10a0b05Jean-Michel Trivi strcpy(language, picoSupportedLangIso3[picoCurrentLangIndex]); 10115f6105e73f0c74acd10126175d4952ade10a0b05Jean-Michel Trivi strcpy(country, picoSupportedCountryIso3[picoCurrentLangIndex]); 10129b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // no variant in this implementation 10139b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi strcpy(variant, "\0"); 10149b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi } 10159b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_SUCCESS; 10169b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi} 10179b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 10189b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi 10199b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi/** setAudioFormat 10209b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * sets the audio format to use for synthesis, returns what is actually used. 10219b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @encoding - reference to encoding format 10229b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @rate - reference to sample rate 10239b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * @channels - reference to number of channels 10249b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * return tts_result 10259b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi * */ 10269b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivitts_result TtsEngine::setAudioFormat(AudioSystem::audio_format& encoding, uint32_t& rate, 10279b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi int& channels) 1028b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 10299b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi // ignore the input parameters, the enforced audio parameters are fixed here 10309b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi encoding = AudioSystem::PCM_16_BIT; 10319b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi rate = 16000; 10329b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi channels = 1; 10339b08cc440f25c4722ca112642be87053fc47f918Jean-Michel Trivi return TTS_SUCCESS; 1034b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1035b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 103654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1037b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** setProperty 103854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Set property. The supported properties are: language, rate, pitch and volume. 1039b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @property - name of property to set 1040b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @value - value to set 1041b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @size - size of value 1042b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1043b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 104454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::setProperty( const char * property, const char * value, const size_t size ) 1045b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 104639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int rate; 104739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int pitch; 104839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int volume; 104939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 105039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Set a specific property for the engine. 105139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Supported properties include: language (locale), rate, pitch, volume. */ 105254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Sanity check */ 10534bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (property == NULL) { 1054b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("setProperty called with property NULL"); 1055b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 10564bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 10574eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 10584bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (value == NULL) { 1059b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("setProperty called with value NULL"); 1060b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 10614bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 10624eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 10634bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strncmp(property, "language", 8) == 0) { 106439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Verify it's in correct format. */ 10654bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strlen(value) != 2 && strlen(value) != 6) { 1066b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("change language called with incorrect format"); 1067b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 10684bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 10694eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 107039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Try to switch to specified language. */ 10714bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (doLanguageSwitch(value) == TTS_FAILURE) { 1072b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("failed to load language"); 1073b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 10744bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 1075b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1076b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 10774bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "rate", 4) == 0) { 107839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = atoi(value); 10794bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (rate < PICO_MIN_RATE) { 108039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = PICO_MIN_RATE; 10814bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 10824bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (rate > PICO_MAX_RATE) { 108339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi rate = PICO_MAX_RATE; 10844bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1085b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currRate = rate; 1086b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 10874bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "pitch", 5) == 0) { 108839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = atoi(value); 10894bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (pitch < PICO_MIN_PITCH) { 109039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = PICO_MIN_PITCH; 10914bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 10924bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (pitch > PICO_MAX_PITCH) { 109339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pitch = PICO_MAX_PITCH; 10944bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1095b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currPitch = pitch; 1096b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 10974bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "volume", 6) == 0) { 109839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = atoi(value); 10994bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (volume < PICO_MIN_VOLUME) { 110039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = PICO_MIN_VOLUME; 11014bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 11024bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (volume > PICO_MAX_VOLUME) { 110339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi volume = PICO_MAX_VOLUME; 11044bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoProp_currVolume = volume; 1106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 11074bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 1110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 111254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** getProperty 111454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Get the property. Supported properties are: language, rate, pitch and volume. 1115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @property - name of property to get 111639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @value - buffer which will receive value of property 111739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @iosize - size of value - if size is too small on return this will contain actual size needed 1118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 112039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::getProperty( const char * property, char * value, size_t * iosize ) 1121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 112239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Get the property for the engine. 112339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi This property was previously set by setProperty or by default. */ 112454823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* sanity check */ 11254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (property == NULL) { 1126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("getProperty called with property NULL"); 1127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_UNSUPPORTED; 11284bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 11294eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 11304bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (value == NULL) { 1131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("getProperty called with value NULL"); 1132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_VALUE_INVALID; 11334bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 11344eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 11354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (strncmp(property, "language", 8) == 0) { 11364bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoProp_currLang == NULL) { 1137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, ""); 11384bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 11394bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (*iosize < strlen(picoProp_currLang)+1) { 1140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(picoProp_currLang) + 1; 1141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 114239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 11434bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi strcpy(value, picoProp_currLang); 114439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 11454bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_SUCCESS; 11464bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "rate", 4) == 0) { 1147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmprate[4]; 1148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmprate, "%d", picoProp_currRate); 11494bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (*iosize < strlen(tmprate)+1) { 1150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmprate) + 1; 1151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 1152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmprate); 1154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 11554bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "pitch", 5) == 0) { 1156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmppitch[4]; 1157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmppitch, "%d", picoProp_currPitch); 11584bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (*iosize < strlen(tmppitch)+1) { 1159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmppitch) + 1; 1160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 1161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmppitch); 1163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 11644bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else if (strncmp(property, "volume", 6) == 0) { 1165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen char tmpvol[4]; 1166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen sprintf(tmpvol, "%d", picoProp_currVolume); 11674bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (*iosize < strlen(tmpvol)+1) { 1168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *iosize = strlen(tmpvol) + 1; 1169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_PROPERTY_SIZE_TOO_SMALL; 11704bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen strcpy(value, tmpvol); 1172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 11734bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 117439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi 117539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Unknown property */ 117639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGE("Unsupported property"); 117739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_PROPERTY_UNSUPPORTED; 1178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 118054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** synthesizeText 118254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Synthesizes a text string. 118339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * The text string could be annotated with SSML tags. 118439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @text - text to synthesize 118539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi * @buffer - buffer which will receive generated samples 1186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @bufferSize - size of buffer 1187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @userdata - pointer to user data which will be passed back to callback function 1188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 119039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::synthesizeText( const char * text, int8_t * buffer, size_t bufferSize, void * userdata ) 1191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 119239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int err; 119339358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi int cbret; 119439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Char * inp = NULL; 119539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Char * local_text = NULL; 119639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi short outbuf[MAX_OUTBUF_SIZE/2]; 119739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi pico_Int16 bytes_sent, bytes_recv, text_remaining, out_data_type; 1198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen pico_Status ret; 119939358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi SvoxSsmlParser * parser = NULL; 12004eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 120139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi picoSynthAbort = 0; 12024bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (text == NULL) { 1203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("synthesizeText called with NULL string"); 1204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 12054bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12064eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 12074bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (buffer == NULL) { 1208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("synthesizeText called with NULL buffer"); 1209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 121039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 12114bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 12124bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if ( (strncmp(text, "<speak", 6) == 0) || (strncmp(text, "<?xml", 5) == 0) ) { 12134bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* SSML input */ 12144bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi parser = new SvoxSsmlParser(); 12154bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (parser && parser->initSuccessful()) { 12164bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi err = parser->parseDocument(text, 1); 12174bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (err == XML_STATUS_ERROR) { 12184bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* Note: for some reason expat always thinks the input document has an error 12194bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi at the end, even when the XML document is perfectly formed */ 12204bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi LOGI("Warning: SSML document parsed with errors"); 12214bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12224bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi char * parsed_text = parser->getParsedDocument(); 12234bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (parsed_text) { 12244bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* Add property tags to the string - if any. */ 12254bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi local_text = (pico_Char *) doAddProperties( parsed_text ); 12264bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!local_text) { 12274bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi LOGE("Failed to allocate memory for text string"); 12284bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi delete parser; 12294bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 12304bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12314bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi char * lang = parser->getParsedDocumentLanguage(); 12325da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi if (lang != NULL) { 12335da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi if (doLanguageSwitch(lang) == TTS_FAILURE) { 12345da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi LOGE("Failed to switch to language (%s) specified in SSML document.", lang); 12355da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi delete parser; 12365da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi return TTS_FAILURE; 12375da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi } 12385da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi } else { 12395da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi // lang is NULL, pick a language so the synthesis can be performed 12405da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi if (picoCurrentLangIndex == -1) { 12415da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi // no current language loaded, pick the first one and load it 12425da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi if (doLanguageSwitchFromLangIndex(0) == TTS_FAILURE) { 12435da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi LOGE("Failed to switch to default language."); 12445da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi delete parser; 12455da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi return TTS_FAILURE; 12465da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi } 12475da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi } 12485da148ef02f1ed01db73163c2befde420b875a9fJean-Michel Trivi LOGE("No language in SSML, using current language (%s).", picoProp_currLang); 12494bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12504bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi delete parser; 12514bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 12524bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi LOGE("Failed to parse SSML document"); 12534bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi delete parser; 12544bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 12554bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12564bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 12574bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi LOGE("Failed to create SSML parser"); 12584bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (parser) { 12594bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi delete parser; 12604bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12614bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 12624bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12634bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 12644bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi /* Add property tags to the string - if any. */ 12654bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi local_text = (pico_Char *) doAddProperties( text ); 12664bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!local_text) { 1267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Failed to allocate memory for text string"); 12684bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 12694bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 12714eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 127239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi text_remaining = strlen((const char *) local_text) + 1; 12734eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 127439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi inp = (pico_Char *) local_text; 12754eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen size_t bufused = 0; 12774eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 127854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* synthesis loop */ 12794bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi while (text_remaining) { 12804bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 12814bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSynthAbort) { 128239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_resetEngine( picoEngine ); 1283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 12844bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12854eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 128654823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Feed the text into the engine. */ 128739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi ret = pico_putTextUtf8( picoEngine, inp, text_remaining, &bytes_sent ); 12884bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (ret != PICO_OK) { 1289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGE("Error synthesizing string '%s': [%d]", text, ret); 12904bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (local_text) { 129139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( local_text ); 129239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 12934bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi return TTS_FAILURE; 12944bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 12954eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 1296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen text_remaining -= bytes_sent; 1297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen inp += bytes_sent; 12984bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi do { 12994bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (picoSynthAbort) { 13000253f57b5d2454e31906bcfdfa9168587ecbef42Jean-Michel Trivi ret = pico_resetEngine( picoEngine ); 1301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 1302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 130354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* Retrieve the samples and add them to the buffer. */ 13044bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi ret = pico_getData( picoEngine, (void *) outbuf, MAX_OUTBUF_SIZE, &bytes_recv, 13054bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi &out_data_type ); 13064bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (bytes_recv) { 13074bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if ((bufused + bytes_recv) <= bufferSize) { 130839358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi memcpy(buffer+bufused, (int8_t *) outbuf, bytes_recv); 1309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen bufused += bytes_recv; 13104bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } else { 131154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi /* The buffer filled; pass this on to the callback function. */ 13124bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi cbret = picoSynthDoneCBPtr(userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, 13134bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi bufused, TTS_SYNTH_PENDING); 13144bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (cbret == TTS_CALLBACK_HALT) { 1315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen LOGI("Halt requested by caller. Halting."); 1316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 1; 13170253f57b5d2454e31906bcfdfa9168587ecbef42Jean-Michel Trivi ret = pico_resetEngine( picoEngine ); 1318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen break; 13194bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen bufused = 0; 132139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi memcpy(buffer, (int8_t *) outbuf, bytes_recv); 13224eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi bufused += bytes_recv; 1323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 13244bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 1325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } while (PICO_STEP_BUSY == ret); 13264eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 132739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* This chunk of synthesis is finished; pass the remaining samples. 132854823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi Use 16 KHz, 16-bit samples. */ 13294bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (!picoSynthAbort) { 13304bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, 13314bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi TTS_SYNTH_PENDING); 1332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 0; 13344eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 13354bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (ret != PICO_STEP_IDLE) { 1336de0498d852dc3f1517989ffa06593aa67f8b5d80Charles Chen if (ret != 0){ 1337de0498d852dc3f1517989ffa06593aa67f8b5d80Charles Chen LOGE("Error occurred during synthesis [%d]", ret); 1338de0498d852dc3f1517989ffa06593aa67f8b5d80Charles Chen } 13394bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi if (local_text) { 13404bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi free(local_text); 13414bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi } 134239358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGV("Synth loop: sending TTS_SYNTH_DONE after error"); 13434bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, 13444bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi TTS_SYNTH_DONE); 1345de0498d852dc3f1517989ffa06593aa67f8b5d80Charles Chen pico_resetEngine( picoEngine ); 1346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_FAILURE; 1347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 1348b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen } 13494bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi 135039358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi /* Synthesis is done; notify the caller */ 135139358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi LOGV("Synth loop: sending TTS_SYNTH_DONE after all done, or was asked to stop"); 13524bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused, 13534bbdb2d4013fa7deb73da0189e9a0e4819e69da9Jean-Michel Trivi TTS_SYNTH_DONE); 13544eea6515d68b88ebd2215309283d467b3212aa2bJean-Michel Trivi 135539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi if (local_text) { 135639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi free( local_text ); 135739358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi } 1358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 136154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** synthesizeIpa 136354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Synthesizes a phonetic string in IPA format. 136439358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi The Pico engine understands only XSAMPA, so the IPA must be converted. 136539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi The string must also be parceled into words since it can only hanlde a word at a time. 136639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi Each phonemic word must be wrapped with a tag. 1367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @ipa - phonetic string to synthesize 1368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @buffer - buffer which will receive generated samples 1369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @bufferSize - size of buffer 1370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @userdata - pointer to user data which will be passed back to callback function 1371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 137354823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivitts_result TtsEngine::synthesizeIpa( const char * ipa, int8_t * buffer, size_t bufferSize, void * userdata ) 1374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 137539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi // deprecated call 137639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivi return TTS_FAILURE; 137754823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 138054823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** stop 138254823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi * Aborts the running synthesis. 1383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * return tts_result 1384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/ 138539358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel Trivitts_result TtsEngine::stop( void ) 1386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen picoSynthAbort = 1; 1388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return TTS_SUCCESS; 1389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 139154823983fdcb4ee88d9a6c4e680ff2064dd95929Jean-Michel Trivi 1392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus 1393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" { 1394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 1395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 139639358f0dacad8cece6c2d3ef1055030f57090c79Jean-Michel TriviTtsEngine * getTtsEngine( void ) 1397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{ 1398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen return new TtsEngine(); 1399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus 1402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} 1403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif 1404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 1405