/* com_svox_picottsengine.cpp

 * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *   This is the Manager layer.  It sits on top of the native Pico engine
 *   and provides the interface to the defined Google TTS engine API.
 *   The Google engine API is the boundary to allow a TTS engine to be swapped.
 *   The Manager layer also provide the SSML tag interpretation.
 *   The supported SSML tags are mapped to corresponding tags natively supported by Pico.
 *   Native Pico functions always begin with picoXXX.
 *
 *   In the Pico engine, the language cannot be changed indpendently of the voice.
 *   If either the voice or locale/language are changed, a new resource is loaded.
 *
 *   Only a subset of SSML 1.0 tags are supported.
 *   Some SSML tags involve significant complexity.
 *   If the language is changed through an SSML tag, there is a latency for the load.
 *
 */
//#define LOG_NDEBUG 0

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define LOG_TAG "SVOX Pico Engine"

#include <utils/Log.h>
#include <utils/String16.h>                     /* for strlen16 */
#include <android_runtime/AndroidRuntime.h>
#include <tts/TtsEngine.h>
#include <cutils/jstring.h>
#include <picoapi.h>
#include <picodefs.h>
#include "svox_ssml_parser.h"

using namespace android;

/* adaptation layer defines */
#define PICO_MEM_SIZE       2500000
/* speaking rate    */
#define PICO_MIN_RATE        20
#define PICO_MAX_RATE       500
#define PICO_DEF_RATE       100
/* speaking pitch   */
#define PICO_MIN_PITCH       50
#define PICO_MAX_PITCH      200
#define PICO_DEF_PITCH      100
/* speaking volume  */
#define PICO_MIN_VOLUME       0
#define PICO_MAX_VOLUME     500
#define PICO_DEF_VOLUME     120

/* string constants */
#define MAX_OUTBUF_SIZE     128
const char * PICO_SYSTEM_LINGWARE_PATH      = "/system/tts/lang_pico/";
const char * PICO_LINGWARE_PATH             = "/sdcard/svox/";
const char * PICO_VOICE_NAME                = "PicoVoice";
const char * PICO_SPEED_OPEN_TAG            = "<speed level='%d'>";
const char * PICO_SPEED_CLOSE_TAG           = "</speed>";
const char * PICO_PITCH_OPEN_TAG            = "<pitch level='%d'>";
const char * PICO_PITCH_CLOSE_TAG           = "</pitch>";
const char * PICO_VOLUME_OPEN_TAG           = "<volume level='%d'>";
const char * PICO_VOLUME_CLOSE_TAG          = "</volume>";
const char * PICO_PHONEME_OPEN_TAG          = "<phoneme ph='";
const char * PICO_PHONEME_CLOSE_TAG         = "'/>";

/* supported voices
   Pico does not seperately specify the voice and locale.   */
const char * picoSupportedLangIso3[]        = { "eng",              "eng",              "deu",              "spa",              "fra",              "ita" };
const char * picoSupportedCountryIso3[]     = { "USA",              "GBR",              "DEU",              "ESP",              "FRA",              "ITA" };
const char * picoSupportedLang[]            = { "en-US",            "en-GB",            "de-DE",            "es-ES",            "fr-FR",            "it-IT" };
const char * picoInternalLang[]             = { "en-US",            "en-GB",            "de-DE",            "es-ES",            "fr-FR",            "it-IT" };
const 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" };
const 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" };
const 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" };
const int picoNumSupportedVocs              = 6;

/* supported properties */
const char * picoSupportedProperties[]      = { "language", "rate", "pitch", "volume" };
const int    picoNumSupportedProperties     = 4;


/* adapation layer global variables */
synthDoneCB_t * picoSynthDoneCBPtr;
void *          picoMemArea         = NULL;
pico_System     picoSystem          = NULL;
pico_Resource   picoTaResource      = NULL;
pico_Resource   picoSgResource      = NULL;
pico_Resource   picoUtppResource    = NULL;
pico_Engine     picoEngine          = NULL;
pico_Char *     picoTaFileName      = NULL;
pico_Char *     picoSgFileName      = NULL;
pico_Char *     picoUtppFileName    = NULL;
pico_Char *     picoTaResourceName  = NULL;
pico_Char *     picoSgResourceName  = NULL;
pico_Char *     picoUtppResourceName = NULL;
int     picoSynthAbort = 0;
char *  picoProp_currLang   = NULL;                 /* current language */
int     picoProp_currRate   = PICO_DEF_RATE;        /* current rate     */
int     picoProp_currPitch  = PICO_DEF_PITCH;       /* current pitch    */
int     picoProp_currVolume = PICO_DEF_VOLUME;      /* current volume   */

int picoCurrentLangIndex = -1;


/* internal helper functions */

/** checkForLocale
 *  Check whether the requested locale is among the supported locales.
 *  @locale -  the locale to check, either in xx or xx-YY format
 *  return index of the locale, or -1 if not supported.
*/
static int checkForLocale( const char * locale )
{
     int found = -1;                                         /* language not found   */
     int i;
     if (locale == NULL) {
        LOGE("checkForLocale called with NULL language");
        return found;
     }

    /* Verify that the requested locale is a locale that we support.    */
    for (i = 0; i < picoNumSupportedVocs; i ++) {
        if (strcmp(locale, picoSupportedLang[i]) == 0) { /* in array */
            found = i;
            break;
        }
    };

    /* The locale was not found.    */
    if (found < 0) {
        /* We didn't find an exact match; it may have been specified with only the first 2 characters.
           This could overmatch ISO 639-3 language codes.%%                                   */
        for (i = 0; i < picoNumSupportedVocs; i ++) {
            if (strncmp(locale, picoSupportedLang[i], 2) == 0) {
                found = i;
                break;
            }
        }
        if (found < 0) {
            LOGE("TtsEngine::set language called with unsupported locale");
        }
    };
    return found;
}


/** cleanResources
 *  Unloads any loaded Pico resources.
*/
static void cleanResources( void )
{
    if (picoEngine) {
        pico_disposeEngine( picoSystem, &picoEngine );
        pico_releaseVoiceDefinition( picoSystem, (pico_Char *) PICO_VOICE_NAME );
        picoEngine = NULL;
    }
    if (picoUtppResource) {
        pico_unloadResource( picoSystem, &picoUtppResource );
        picoUtppResource = NULL;
    }
    if (picoTaResource) {
        pico_unloadResource( picoSystem, &picoTaResource );
        picoTaResource = NULL;
    }
    if (picoSgResource) {
        pico_unloadResource( picoSystem, &picoSgResource );
        picoSgResource = NULL;
    }

    if (picoSystem) {
        pico_terminate(&picoSystem);
        picoSystem = NULL;
    }
    picoCurrentLangIndex = -1;
}


/** cleanFiles
 *  Frees any memory allocated for file and resource strings.
*/
static void cleanFiles( void )
{
    if (picoProp_currLang) {
        free( picoProp_currLang );
        picoProp_currLang = NULL;
    }

    if (picoTaFileName) {
        free( picoTaFileName );
        picoTaFileName = NULL;
    }

    if (picoSgFileName) {
        free( picoSgFileName );
        picoSgFileName = NULL;
    }

    if (picoUtppFileName) {
        free( picoUtppFileName );
        picoUtppFileName = NULL;
    }

    if (picoTaResourceName) {
        free( picoTaResourceName );
        picoTaResourceName = NULL;
    }

    if (picoSgResourceName) {
        free( picoSgResourceName );
        picoSgResourceName = NULL;
    }

    if (picoUtppResourceName) {
        free( picoUtppResourceName );
        picoUtppResourceName = NULL;
    }
}

/** hasResourcesForLanguage
 *  Check to see if the resources required to load the language at the specified index
 *  are properly installed
 *  @langIndex - the index of the language to check the resources for. The index is valid.
 *  return true if the required resources are installed, false otherwise
 */
static bool hasResourcesForLanguage(int langIndex) {
    FILE * pFile;
    char* fileName = (char*)malloc(PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE);

    /* check resources on system (under PICO_SYSTEM_LINGWARE_PATH). */
    strcpy((char*)fileName, PICO_SYSTEM_LINGWARE_PATH);
    strcat((char*)fileName, (const char*)picoInternalTaLingware[langIndex]);
    pFile = fopen(fileName, "r");
    if (pFile != NULL) {
        /* "ta" file found. */
        fclose (pFile);
        /* now look for "sg" file. */
        strcpy((char*)fileName, PICO_SYSTEM_LINGWARE_PATH);
        strcat((char*)fileName, (const char*)picoInternalSgLingware[langIndex]);
        pFile = fopen(fileName, "r");
        if (pFile != NULL) {
            /* "sg" file found, no need to continue checking, return success. */
            fclose(pFile);
            free(fileName);
            return true;
        }
    }

    /* resources not found on system, check resources on alternative location */
    /* (under PICO_LINGWARE_PATH).                                            */
    strcpy((char*)fileName, PICO_LINGWARE_PATH);
    strcat((char*)fileName, (const char*)picoInternalTaLingware[langIndex]);
    pFile = fopen(fileName, "r");
    if (pFile == NULL) {
        free(fileName);
        return false;
    } else {
        fclose (pFile);
    }

    strcpy((char*)fileName, PICO_LINGWARE_PATH);
    strcat((char*)fileName, (const char*)picoInternalSgLingware[langIndex]);
    pFile = fopen(fileName, "r");
    if (pFile == NULL) {
        free(fileName);
        return false;
    } else {
        fclose(pFile);
        free(fileName);
        return true;
    }
}

/** doLanguageSwitchFromLangIndex
 *  Switch to the requested locale.
 *  If the locale is already loaded, it returns immediately.
 *  If another locale is already is loaded, it will first be unloaded and the new one then loaded.
 *  If no locale is loaded, the requested locale will be loaded.
 *  @langIndex -  the index of the locale/voice to load, which is guaranteed to be supported.
 *  return TTS_SUCCESS or TTS_FAILURE
 */
static tts_result doLanguageSwitchFromLangIndex( int langIndex )
{
    int ret;                                        /* function result code */

    if (langIndex>=0) {
        /* If we already have a loaded locale, check whether it is the same one as requested.   */
        if (picoProp_currLang && (strcmp(picoProp_currLang, picoSupportedLang[langIndex]) == 0)) {
            LOGI("Language already loaded (%s == %s)", picoProp_currLang,
                    picoSupportedLang[langIndex]);
            return TTS_SUCCESS;
        }
    }

    /* It is not the same locale; unload the current one first. Also invalidates the system object*/
    cleanResources();

    /* Allocate memory for file and resource names.     */
    cleanFiles();

    if (picoSystem==NULL) {
        /*re-init system object*/
        ret = pico_initialize( picoMemArea, PICO_MEM_SIZE, &picoSystem );
        if (PICO_OK != ret) {
            LOGE("Failed to initialize the pico system object\n");
            return TTS_FAILURE;
        }
    }

    picoProp_currLang   = (char *)      malloc( 10 );
    picoTaFileName      = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
    picoSgFileName      = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
    picoUtppFileName    = (pico_Char *) malloc( PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE );
    picoTaResourceName  = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE );
    picoSgResourceName  = (pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE );
    picoUtppResourceName =(pico_Char *) malloc( PICO_MAX_RESOURCE_NAME_SIZE );

    if (
        (picoProp_currLang==NULL) || (picoTaFileName==NULL) || (picoSgFileName==NULL) ||
        (picoUtppFileName==NULL) || (picoTaResourceName==NULL) || (picoSgResourceName==NULL) ||
        (picoUtppResourceName==NULL)
        ) {
        LOGE("Failed to allocate memory for internal strings\n");
        cleanResources();
        return TTS_FAILURE;
    }

    /* Find where to load the resource files from: system or alternative location              */
    /* based on availability of the Ta file. Try the alternative location first, this is where */
    /* more recent language file updates would be installed (under PICO_LINGWARE_PATH).        */
    bool bUseSystemPath = true;
    FILE * pFile;
    char* tmpFileName = (char*)malloc(PICO_MAX_DATAPATH_NAME_SIZE + PICO_MAX_FILE_NAME_SIZE);
    strcpy((char*)tmpFileName, PICO_LINGWARE_PATH);
    strcat((char*)tmpFileName, (const char*)picoInternalTaLingware[langIndex]);
    pFile = fopen(tmpFileName, "r");
    if (pFile != NULL) {
        /* "ta" file found under PICO_LINGWARE_PATH, don't use the system path. */
        fclose (pFile);
        bUseSystemPath = false;
    }
    free(tmpFileName);

    /* Set the path and file names for resource files.  */
    if (bUseSystemPath) {
        strcpy((char *) picoTaFileName,   PICO_SYSTEM_LINGWARE_PATH);
        strcpy((char *) picoSgFileName,   PICO_SYSTEM_LINGWARE_PATH);
        strcpy((char *) picoUtppFileName, PICO_SYSTEM_LINGWARE_PATH);
    } else {
        strcpy((char *) picoTaFileName,   PICO_LINGWARE_PATH);
        strcpy((char *) picoSgFileName,   PICO_LINGWARE_PATH);
        strcpy((char *) picoUtppFileName, PICO_LINGWARE_PATH);
    }
    strcat((char *) picoTaFileName,   (const char *) picoInternalTaLingware[langIndex]);
    strcat((char *) picoSgFileName,   (const char *) picoInternalSgLingware[langIndex]);
    strcat((char *) picoUtppFileName, (const char *) picoInternalUtppLingware[langIndex]);

    /* Load the text analysis Lingware resource file.   */
    ret = pico_loadResource( picoSystem, picoTaFileName, &picoTaResource );
    if (PICO_OK != ret) {
        LOGE("Failed to load textana resource for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    /* Load the signal generation Lingware resource file.   */
    ret = pico_loadResource( picoSystem, picoSgFileName, &picoSgResource );
    if (PICO_OK != ret) {
        LOGE("Failed to load siggen resource for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    /* Load the utpp Lingware resource file if exists - NOTE: this file is optional
       and is currently not used. Loading is only attempted for future compatibility.
       If this file is not present the loading will still succeed.                      */
    ret = pico_loadResource( picoSystem, picoUtppFileName, &picoUtppResource );
    if ((PICO_OK != ret) && (ret != PICO_EXC_CANT_OPEN_FILE)) {
        LOGE("Failed to load utpp resource for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    /* Get the text analysis resource name.     */
    ret = pico_getResourceName( picoSystem, picoTaResource, (char *) picoTaResourceName );
    if (PICO_OK != ret) {
        LOGE("Failed to get textana resource name for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    /* Get the signal generation resource name. */
    ret = pico_getResourceName( picoSystem, picoSgResource, (char *) picoSgResourceName );
    if ((PICO_OK == ret) && (picoUtppResource != NULL)) {
        /* Get utpp resource name - optional: see note above.   */
        ret = pico_getResourceName( picoSystem, picoUtppResource, (char *) picoUtppResourceName );
        if (PICO_OK != ret)  {
            LOGE("Failed to get utpp resource name for %s [%d]", picoSupportedLang[langIndex], ret);
            cleanResources();
            cleanFiles();
            return TTS_FAILURE;
        }
    }
    if (PICO_OK != ret) {
        LOGE("Failed to get siggen resource name for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    /* Create a voice definition.   */
    ret = pico_createVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME );
    if (PICO_OK != ret) {
        LOGE("Failed to create voice for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    /* Add the text analysis resource to the voice. */
    ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoTaResourceName );
    if (PICO_OK != ret) {
        LOGE("Failed to add textana resource to voice for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    /* Add the signal generation resource to the voice. */
    ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoSgResourceName );
    if ((PICO_OK == ret) && (picoUtppResource != NULL)) {
        /* Add utpp resource to voice - optional: see note above.   */
        ret = pico_addResourceToVoiceDefinition( picoSystem, (const pico_Char *) PICO_VOICE_NAME, picoUtppResourceName );
        if (PICO_OK != ret) {
            LOGE("Failed to add utpp resource to voice for %s [%d]", picoSupportedLang[langIndex], ret);
            cleanResources();
            cleanFiles();
            return TTS_FAILURE;
        }
    }

    if (PICO_OK != ret) {
        LOGE("Failed to add siggen resource to voice for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    ret = pico_newEngine( picoSystem, (const pico_Char *) PICO_VOICE_NAME, &picoEngine );
    if (PICO_OK != ret) {
        LOGE("Failed to create engine for %s [%d]", picoSupportedLang[langIndex], ret);
        cleanResources();
        cleanFiles();
        return TTS_FAILURE;
    }

    /* Set the current locale/voice.    */
    strcpy( picoProp_currLang, picoSupportedLang[langIndex] );
    picoCurrentLangIndex = langIndex;
    LOGI("loaded %s successfully", picoProp_currLang);
    return TTS_SUCCESS;
}


/** doLanguageSwitch
 *  Switch to the requested locale.
 *  If this locale is already loaded, it returns immediately.
 *  If another locale is already loaded, this will first be unloaded
 *  and the new one then loaded.
 *  If no locale is loaded, the requested will be loaded.
 *  @locale -  the locale to check, either in xx or xx-YY format (i.e "en" or "en-US")
 *  return TTS_SUCCESS or TTS_FAILURE
*/
static tts_result doLanguageSwitch( const char * locale )
{
    int loclIndex;                              /* locale index */

    /* Load the new locale. */
    loclIndex = checkForLocale( locale );
    if (loclIndex < 0)  {
        LOGE("Tried to swith to non-supported locale %s", locale);
        return TTS_FAILURE;
    }
    LOGI("Found supported locale %s", picoSupportedLang[loclIndex]);
    return doLanguageSwitchFromLangIndex( loclIndex );
}


/** doAddProperties
 *  Add <speed>, <pitch> and <volume> tags to the text,
 *  if the properties have been set to non-default values, and return the new string.
 *  The calling function is responsible for freeing the returned string.
 *  @str - text to apply tags to
 *  return new string with tags applied
*/
static char * doAddProperties( const char * str )
{
    char *  data = NULL;
    int     haspitch, hasspeed, hasvol;                 /* parameters           */
    int     textlen;                                    /* property string length   */

    haspitch = 0; hasspeed = 0; hasvol = 0;
    textlen = strlen(str) + 1;
    if (picoProp_currPitch != PICO_DEF_PITCH) {          /* non-default pitch    */
        textlen += strlen(PICO_PITCH_OPEN_TAG) + 5;
        textlen += strlen(PICO_PITCH_CLOSE_TAG);
        haspitch = 1;
    }
    if (picoProp_currRate != PICO_DEF_RATE) {            /* non-default rate     */
        textlen += strlen(PICO_SPEED_OPEN_TAG) + 5;
        textlen += strlen(PICO_SPEED_CLOSE_TAG);
        hasspeed = 1;
    }

    // Always set the volume for now - this is to work around not being able
    // to change the default volume.
    // TODO: Fix the underlying problem so that default volume as defined by
    // PICO_DEF_VOLUME is respected.
    //if (picoProp_currVolume != PICO_DEF_VOLUME) {        /* non-default volume   */
        textlen += strlen(PICO_VOLUME_OPEN_TAG) + 5;
        textlen += strlen(PICO_VOLUME_CLOSE_TAG);
        hasvol = 1;
    //}

    /* Compose the property strings.    */
    data = (char *) malloc( textlen );                  /* allocate string      */
    if (!data) {
        return NULL;
    }
    memset(data, 0, textlen);                           /* clear it             */
    if (haspitch) {
        char* tmp = (char*)malloc(strlen(PICO_PITCH_OPEN_TAG) + strlen(PICO_PITCH_CLOSE_TAG) + 5);
        sprintf(tmp, PICO_PITCH_OPEN_TAG, picoProp_currPitch);
        strcat(data, tmp);
        free(tmp);
    }

    if (hasspeed) {
        char* tmp = (char*)malloc(strlen(PICO_SPEED_OPEN_TAG) + strlen(PICO_SPEED_CLOSE_TAG) + 5);
        sprintf(tmp, PICO_SPEED_OPEN_TAG, picoProp_currRate);
        strcat(data, tmp);
        free(tmp);
    }

    if (hasvol) {
        char* tmp = (char*)malloc(strlen(PICO_VOLUME_OPEN_TAG) + strlen(PICO_VOLUME_CLOSE_TAG) + 5);
        sprintf(tmp, PICO_VOLUME_OPEN_TAG, picoProp_currVolume);
        strcat(data, tmp);
        free(tmp);
    }

    strcat(data, str);

    if (hasvol) {
        strcat(data, PICO_VOLUME_CLOSE_TAG);
    }

    if (hasspeed) {
        strcat(data, PICO_SPEED_CLOSE_TAG);
    }

    if (haspitch) {
        strcat(data, PICO_PITCH_CLOSE_TAG);
    }

    return data;
}


/** get_tok
 *  Searches for tokens in a string
 *  @str - text to be processed
 *  @pos - position of first character to be searched in str
 *  @textlen - postion of last character to be searched
 *  @tokstart - address of a variable to receive the start of the token found
 *  @tokstart - address of a variable to receive the length of the token found
 *  return : 1=token found, 0=token not found
 *  notes : the token separator set could be enlarged adding characters in "seps"
*/
static int  get_tok(const char * str , int pos, int textlen, int *tokstart, int *toklen)
{
    const char * seps = " ";

    /*look for start*/
    while ((pos<textlen) && (strchr(seps,str[pos]) != NULL)) {
        pos++;
    }
    if (pos == textlen) {
        /*no characters != seps found whithin string*/
        return 0;
    }
    *tokstart = pos;
    /*look for end*/
    while ((pos<textlen) && (strchr(seps,str[pos]) == NULL)) {
        pos++;
    }
    *toklen = pos - *tokstart;
    return 1;
}/*get_tok*/


/** get_sub_tok
 *  Searches for subtokens in a token having a compound structure with camel case like "xxxYyyy"
 *  @str - text to be processed
 *  @pos - position of first character to be searched in str
 *  @textlen - postion of last character to be searched in str
 *  @tokstart - address of a variable to receive the start of the sub token found
 *  @tokstart - address of a variable to receive the length of the sub token found
 *  return : 1=sub token found, 0=sub token not found
 *  notes : the sub token separator set could be enlarged adding characters in "seps"
*/
static int  get_sub_tok(const char * str , int pos, int textlen, int *tokstart, int *toklen) {

    const char * seps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    if (pos == textlen) {
        return 0;
    }

    /*first char != space*/
    *tokstart = pos;
    /*finding first non separator*/
    while ((pos < textlen) && (strchr(seps, str[pos]) != NULL)) {
        pos++;
    }
    if (pos == textlen) {
        /*characters all in seps found whithin string : return full token*/
        *toklen = pos - *tokstart;
        return 1;
    }
    /*pos should be pointing to first non seps and more chars are there*/
    /*finding first separator*/
    while ((pos < textlen) && (strchr(seps, str[pos]) == NULL)) {
        pos++;
    }
    if (pos == textlen) {
        /*transition non seps->seps not found : return full token*/
        *toklen = pos - *tokstart;
        return 1;
    }
    *toklen = pos - *tokstart;
    return 1;
}/*get_sub_tok*/


/** doCamelCase
 *  Searches for tokens having a compound structure with camel case and transforms them as follows :
 *        "XxxxYyyy" -->> "Xxxx Yyyy",
 *        "xxxYyyy"  -->> "xxx Yyyy",
 *        "XXXYyyy"  -->> "XXXYyyy"
 *        etc....
 *  The calling function is responsible for freeing the returned string.
 *  @str - text to be processed
 *  return new string with text processed
*/
static char * doCamelCase( const char * str )
{
    int     textlen;             /* input string length   */
    int     totlen;              /* output string length   */
    int     tlen_2, nsubtok;     /* nuber of subtokens   */
    int     toklen, tokstart;    /*legnth and start of generic token*/
    int     stoklen, stokstart;  /*legnth and start of generic sub-token*/
    int     pos, tokpos, outpos; /*postion of current char in input string and token and output*/
    char    *data;               /*pointer of the returned string*/

    pos = 0;
    tokpos = 0;
    toklen = 0;
    stoklen = 0;
    tlen_2 = 0;
    totlen = 0;

    textlen = strlen(str) + 1;

    /*counting characters after sub token splitting including spaces*/
    //while ((pos<textlen) && (str[pos]!=0)) {
    while (get_tok(str, pos, textlen, &tokstart, &toklen)) {
        tokpos = tokstart;
        tlen_2 = 0;
        nsubtok = 0;
        while (get_sub_tok(str, tokpos, tokstart+toklen, &stokstart, &stoklen)) {
            totlen += stoklen;
            tlen_2 += stoklen;
            tokpos = stokstart + stoklen;
            nsubtok += 1;
        }
        totlen += nsubtok;    /*add spaces between subtokens*/
        pos = tokstart + tlen_2;
    }
    //}
    /* Allocate the return string */
    data = (char *) malloc( totlen );                  /* allocate string      */
    if (!data) {
        return NULL;
    }
    memset(data, 0, totlen);                           /* clear it             */
    outpos = 0;
    pos = 0;
    /*copying characters*/
    //while ((pos<textlen) && (str[pos]!=0)) {
    while (get_tok  (str, pos, textlen, &tokstart, &toklen)) {
        tokpos = tokstart;
        tlen_2 = 0;
        nsubtok = 0;
        while (get_sub_tok(str, tokpos, tokstart+toklen, &stokstart, &stoklen)) {
            strncpy(&(data[outpos]), &(str[stokstart]), stoklen);
            outpos += stoklen;
            strncpy(&(data[outpos]), " ", 1);
            tlen_2 += stoklen;
            outpos += 1;
            tokpos = stokstart + stoklen;
        }
        pos=tokstart+tlen_2;
    }
    //}
    data[outpos] = 0;
    return data;
}/*doCamelCase*/


/** createPhonemeString
 *  Wrap all individual words in <phoneme> tags.
 *  The Pico <phoneme> tag only supports one word in each tag,
 *  therefore they must be individually wrapped!
 *  @xsampa - text to convert to Pico phomene string
 *  @length - length of the input string
 *  return new string with tags applied
*/
extern char * createPhonemeString( const char * xsampa, int length )
{
    char *  convstring = NULL;
    int     origStrLen = strlen(xsampa);
    int     numWords   = 1;
    int     start, totalLength, i, j;

    for (i = 0; i < origStrLen; i ++) {
        if ((xsampa[i] == ' ') || (xsampa[i] == '#')) {
            numWords ++;
        }
    }

    if (numWords == 1) {
        convstring = new char[origStrLen + 17];
        convstring[0] = '\0';
        strcat(convstring, PICO_PHONEME_OPEN_TAG);
        strcat(convstring, xsampa);
        strcat(convstring, PICO_PHONEME_CLOSE_TAG);
    } else {
        char * words[numWords];
        start = 0; totalLength = 0; i = 0; j = 0;
        for (i=0, j=0; i < origStrLen; i++) {
            if ((xsampa[i] == ' ') || (xsampa[i] == '#')) {
                words[j]    = new char[i+1-start+17];
                words[j][0] = '\0';
                strcat( words[j], PICO_PHONEME_OPEN_TAG);
                strncat(words[j], xsampa+start, i-start);
                strcat( words[j], PICO_PHONEME_CLOSE_TAG);
                start = i + 1;
                j++;
                totalLength += strlen(words[j-1]);
            }
        }
        words[j]    = new char[i+1-start+17];
        words[j][0] = '\0';
        strcat(words[j], PICO_PHONEME_OPEN_TAG);
        strcat(words[j], xsampa+start);
        strcat(words[j], PICO_PHONEME_CLOSE_TAG);
        totalLength += strlen(words[j]);
        convstring = new char[totalLength + 1];
        convstring[0] = '\0';
        for (i=0 ; i < numWords ; i++) {
            strcat(convstring, words[i]);
            delete [] words[i];
        }
    }

    return convstring;
}

/* The XSAMPA uses as many as 5 characters to represent a single IPA code.  */
typedef struct tagPhnArr
{
    char16_t    strIPA;             /* IPA Unicode symbol       */
    char        strXSAMPA[6];       /* SAMPA sequence           */
} PArr;

#define phn_cnt (134+7)

PArr    PhnAry[phn_cnt] = {

    /* XSAMPA conversion table
	   This maps a single IPA symbol to a sequence representing XSAMPA.
       This relies upon a direct one-to-one correspondance
       including diphthongs and affricates.						      */

    /* Vowels (23) complete     */
    {0x025B,        "E"},
    {0x0251,        "A"},
    {0x0254,        "O"},
    {0x00F8,        "2"},
    {0x0153,        "9"},
    {0x0276,        "&"},
    {0x0252,        "Q"},
    {0x028C,        "V"},
    {0x0264,        "7"},
    {0x026F,        "M"},
    {0x0268,        "1"},
    {0x0289,        "}"},
    {0x026A,        "I"},
    {0x028F,        "Y"},
    {0x028A,        "U"},
    {0x0259,        "@"},
    {0x0275,        "8"},
    {0x0250,        "6"},
    {0x00E6,        "{"},
    {0x025C,        "3"},
    {0x025A,        "@`"},
    {0x025E,        "3\\\\"},
    {0x0258,        "@\\\\"},

    /* Consonants (60) complete */
    {0x0288,        "t`"},
    {0x0256,        "d`"},
    {0x025F,        "J\\\\"},
    {0x0261,        "g"},
    {0x0262,        "G\\\\"},
    {0x0294,        "?"},
    {0x0271,        "F"},
    {0x0273,        "n`"},
    {0x0272,        "J"},
    {0x014B,        "N"},
    {0x0274,        "N\\\\"},
    {0x0299,        "B\\\\"},
    {0x0280,        "R\\\\"},
    {0x027E,        "4"},
    {0x027D,        "r`"},
    {0x0278,        "p\\\\"},
    {0x03B2,        "B"},
    {0x03B8,        "T"},
    {0x00F0,        "D"},
    {0x0283,        "S"},
    {0x0292,        "Z"},
    {0x0282,        "s`"},
    {0x0290,        "z`"},
    {0x00E7,        "C"},
    {0x029D,        "j\\\\"},
    {0x0263,        "G"},
    {0x03C7,        "X"},
    {0x0281,        "R"},
    {0x0127,        "X\\\\"},
    {0x0295,        "?\\\\"},
    {0x0266,        "h\\\\"},
    {0x026C,        "K"},
    {0x026E,        "K\\\\"},
    {0x028B,        "P"},
    {0x0279,        "r\\\\"},
    {0x027B,        "r\\\\'"},
    {0x0270,        "M\\\\"},
    {0x026D,        "l`"},
    {0x028E,        "L"},
    {0x029F,        "L\\\\"},
    {0x0253,        "b_<"},
    {0x0257,        "d_<"},
    {0x0284,        "J\\_<"},
    {0x0260,        "g_<"},
    {0x029B,        "G\\_<"},
    {0x028D,        "W"},
    {0x0265,        "H"},
    {0x029C,        "H\\\\"},
    {0x02A1,        ">\\\\"},
    {0x02A2,        "<\\\\"},
    {0x0267,        "x\\\\"},		/* hooktop heng	*/
    {0x0298,        "O\\\\"},
    {0x01C0,        "|\\\\"},
    {0x01C3,        "!\\\\"},
    {0x01C2,        "=\\"},
    {0x01C1,        "|\\|\\"},
    {0x027A,        "l\\\\"},
    {0x0255,        "s\\\\"},
    {0x0291,        "z\\\\"},
    {0x026B,        "l_G"},


    /* Diacritics (37) complete */
    {0x02BC,        "_>"},
    {0x0325,        "_0"},
    {0x030A,        "_0"},
    {0x032C,        "_v"},
    {0x02B0,        "_h"},
    {0x0324,        "_t"},
    {0x0330,        "_k"},
    {0x033C,        "_N"},
    {0x032A,        "_d"},
    {0x033A,        "_a"},
    {0x033B,        "_m"},
    {0x0339,        "_O"},
    {0x031C,        "_c"},
    {0x031F,        "_+"},
    {0x0320,        "_-"},
    {0x0308,        "_\""},     /* centralized		*/
    {0x033D,        "_x"},
    {0x0318,        "_A"},
    {0x0319,        "_q"},
    {0x02DE,        "`"},
    {0x02B7,        "_w"},
    {0x02B2,        "_j"},
    {0x02E0,        "_G"},
    {0x02E4,        "_?\\\\"},	/* pharyngealized	*/
    {0x0303,        "~"},		/* nasalized		*/
    {0x207F,        "_n"},
    {0x02E1,        "_l"},
    {0x031A,        "_}"},
    {0x0334,        "_e"},
    {0x031D,        "_r"},		/* raised  equivalent to 02D4 */
    {0x02D4,        "_r"},		/* raised  equivalent to 031D */
    {0x031E,        "_o"},		/* lowered equivalent to 02D5 */
    {0x02D5,        "_o"},		/* lowered equivalent to 031E */
    {0x0329,        "="},		/* sylabic			*/
    {0x032F,        "_^"},		/* non-sylabic		*/
    {0x0361,        "_"},		/* top tie bar		*/
    {0x035C,        "_"},

    /* Suprasegmental (15) incomplete */
    {0x02C8,        "\""},		/* primary   stress	*/
    {0x02CC,        "%"},		/* secondary stress	*/
    {0x02D0,        ":"},		/* long				*/
    {0x02D1,        ":\\\\"},	/* half-long		*/
    {0x0306,        "_X"},		/* extra short		*/

    {0x2016,        "||"},		/* major group		*/
    {0x203F,        "-\\\\"},	/* bottom tie bar	*/
    {0x2197,        "<R>"},		/* global rise		*/
    {0x2198,        "<F>"},		/* global fall		*/
    {0x2193,        "<D>"},		/* downstep			*/
    {0x2191,        "<U>"},		/* upstep			*/
    {0x02E5,        "<T>"},		/* extra high level	*/
    {0x02E7,        "<M>"},		/* mid level		*/
    {0x02E9,        "<B>"},		/* extra low level	*/

    {0x025D,        "3`:"},		/* non-IPA	%%		*/

    /* Affricates (6) complete  */
    {0x02A3,        "d_z"},
    {0x02A4,        "d_Z"},
    {0x02A5,        "d_z\\\\"},
    {0x02A6,        "t_s"},
    {0x02A7,        "t_S"},
    {0x02A8,        "t_s\\\\"}
    };


void CnvIPAPnt( const char16_t IPnt, char * XPnt )
{
    char16_t        ThisPnt = IPnt;                     /* local copy of single IPA codepoint   */
    int             idx;                                /* index into table         */

    /* Convert an individual IPA codepoint.
       A single IPA code could map to a string.
       Search the table.  If it is not found, use the same character.
       Since most codepoints can be contained within 16 bits,
       they are represented as wide chars.              */
    XPnt[0] = 0;                                        /* clear the result string  */

    /* Search the table for the conversion. */
    for (idx = 0; idx < phn_cnt; idx ++) {               /* for each item in table   */
        if (IPnt == PhnAry[idx].strIPA) {                /* matches IPA code         */
            strcat( XPnt, (const char *)&(PhnAry[idx].strXSAMPA) ); /* copy the XSAMPA string   */
            return;
        }
    }
    strcat(XPnt, (const char *)&ThisPnt);               /* just copy it             */
}


/** cnvIpaToXsampa
 *  Convert an IPA character string to an XSAMPA character string.
 *  @ipaString - input IPA string to convert
 *  @outXsampaString - converted XSAMPA string is passed back in this parameter
 *  return size of the new string
*/

int cnvIpaToXsampa( const char16_t * ipaString, size_t ipaStringSize, char ** outXsampaString )
{
    size_t xsize;                                  /* size of result               */
    size_t ipidx;                                  /* index into IPA string        */
    char * XPnt;                                   /* short XSAMPA char sequence   */

    /* Convert an IPA string to an XSAMPA string and store the xsampa string in *outXsampaString.
       It is the responsibility of the caller to free the allocated string.
       Increment through the string.  For each base & combination convert it to the XSAMP equivalent.
       Because of the XSAMPA limitations, not all IPA characters will be covered.       */
    XPnt = (char *) malloc(6);
    xsize   = (4 * ipaStringSize) + 8;          /* assume more than double size */
    *outXsampaString = (char *) malloc( xsize );/* allocate return string   */
    *outXsampaString[0] = 0;
    xsize = 0;                                  /* clear final              */

    for (ipidx = 0; ipidx < ipaStringSize; ipidx ++) { /* for each IPA code        */
        CnvIPAPnt( ipaString[ipidx], XPnt );           /* get converted character  */
        strcat((char *)*outXsampaString, XPnt );       /* concatenate XSAMPA       */
    }
    free(XPnt);
    xsize = strlen(*outXsampaString);                  /* get the final length     */
    return xsize;
}


/* Google Engine API function implementations */

/** init
 *  Allocates Pico memory block and initializes the Pico system.
 *  synthDoneCBPtr - Pointer to callback function which will receive generated samples
 *  return tts_result
*/
tts_result TtsEngine::init( synthDoneCB_t synthDoneCBPtr )
{
    if (synthDoneCBPtr == NULL) {
        LOGE("Callback pointer is NULL");
        return TTS_FAILURE;
    }

    picoMemArea = malloc( PICO_MEM_SIZE );
    if (!picoMemArea) {
        LOGE("Failed to allocate memory for Pico system");
        return TTS_FAILURE;
    }

    pico_Status ret = pico_initialize( picoMemArea, PICO_MEM_SIZE, &picoSystem );
    if (PICO_OK != ret) {
        LOGE("Failed to initialize Pico system");
        free( picoMemArea );
        picoMemArea = NULL;
        return TTS_FAILURE;
    }

    picoSynthDoneCBPtr = synthDoneCBPtr;

    picoCurrentLangIndex = -1;

    return TTS_SUCCESS;
}


/** shutdown
 *  Unloads all Pico resources; terminates Pico system and frees Pico memory block.
 *  return tts_result
*/
tts_result TtsEngine::shutdown( void )
{
    cleanResources();

    if (picoSystem) {
        pico_terminate(&picoSystem);
        picoSystem = NULL;
    }
    if (picoMemArea) {
        free(picoMemArea);
        picoMemArea = NULL;
    }

    cleanFiles();
    return TTS_SUCCESS;
}


/** loadLanguage
 *  Load a new language.
 *  @lang - string with ISO 3 letter language code.
 *  @country - string with ISO 3 letter country code .
 *  @variant - string with language variant for that language and country pair.
 *  return tts_result
*/
tts_result TtsEngine::loadLanguage(const char *lang, const char *country, const char *variant)
{
    return TTS_FAILURE;
    //return setProperty("language", value, size);
}


/** setLanguage
 *  Load a new language (locale).  Use the ISO 639-3 language codes.
 *  @lang - string with ISO 639-3 language code.
 *  @country - string with ISO 3 letter country code.
 *  @variant - string with language variant for that language and country pair.
 *  return tts_result
 */
tts_result TtsEngine::setLanguage( const char * lang, const char * country, const char * variant )
{
    int langIndex;
    int countryIndex;
    int i;

    if (lang == NULL)
        {
        LOGE("TtsEngine::setLanguage called with NULL language");
        return TTS_FAILURE;
        }

    /* We look for a match on the language first
       then we look for a match on the country.
       If no match on the language:
             return an error.
       If match on the language, but no match on the country:
             load the language found for the language match.
       If match on the language, and match on the country:
             load the language found for the country match.     */

    /* Find a match on the language.    */
    langIndex = -1;                                     /* no match */
    for (i = 0; i < picoNumSupportedVocs; i ++)
        {
        if (strcmp(lang, picoSupportedLangIso3[i]) == 0)
            {
            langIndex = i;
            break;
            }
        }
    if (langIndex < 0)
        {
        /* The language isn't supported.    */
        LOGE("TtsEngine::setLanguage called with unsupported language");
        return TTS_FAILURE;
        }

    /* Find a match on the country, if there is one.    */
    if (country != NULL)
        {
        countryIndex = -1;
        for (i = langIndex; i < picoNumSupportedVocs; i ++)
            {
            if (   (strcmp(lang,    picoSupportedLangIso3[i])    == 0)
                && (strcmp(country, picoSupportedCountryIso3[i]) == 0))
                {
                countryIndex = i;
                break;
                }
            }

        if (countryIndex < 0)
            {
            /* We didn't find a match on the country, but we had a match on the language.
               Use that language.                                                       */
            LOGI("TtsEngine::setLanguage found matching language(%s) but not matching country(%s).",
                    lang, country);
            }
        else
            {
            /* We have a match on both the language and the country.    */
            langIndex = countryIndex;
            }
        }

    return doLanguageSwitchFromLangIndex( langIndex );      /* switch the language  */
}


/** isLanguageAvailable
 *  Returns the level of support for a language.
 *  @lang - string with ISO 3 letter language code.
 *  @country - string with ISO 3 letter country code .
 *  @variant - string with language variant for that language and country pair.
 *  return tts_support_result
*/
tts_support_result TtsEngine::isLanguageAvailable(const char *lang, const char *country,
            const char *variant) {
    int langIndex = -1;
    int countryIndex = -1;
    //-------------------------
    // language matching
    // if no language specified
    if (lang == NULL)  {
        LOGE("TtsEngine::isLanguageAvailable called with no language");
        return TTS_LANG_NOT_SUPPORTED;
    }

    // find a match on the language
    for (int i = 0; i < picoNumSupportedVocs; i++)
    {
        if (strcmp(lang, picoSupportedLangIso3[i]) == 0) {
            langIndex = i;
            break;
        }
    }
    if (langIndex < 0) {
        // language isn't supported
        LOGV("TtsEngine::isLanguageAvailable called with unsupported language");
        return TTS_LANG_NOT_SUPPORTED;
    }

    //-------------------------
    // country matching
    // if no country specified
    if ((country == NULL) || (strlen(country) == 0)) {
        // check installation of matched language
        return (hasResourcesForLanguage(langIndex) ? TTS_LANG_AVAILABLE : TTS_LANG_MISSING_DATA);
    }

    // find a match on the country
    for (int i = langIndex; i < picoNumSupportedVocs; i++) {
        if ((strcmp(lang, picoSupportedLangIso3[i]) == 0)
                && (strcmp(country, picoSupportedCountryIso3[i]) == 0)) {
            countryIndex = i;
            break;
        }
    }
    if (countryIndex < 0)  {
        // we didn't find a match on the country, but we had a match on the language
        // check installation of matched language
        return (hasResourcesForLanguage(langIndex) ? TTS_LANG_AVAILABLE : TTS_LANG_MISSING_DATA);
    } else {
        // we have a match on the language and the country
        langIndex = countryIndex;
        // check installation of matched language + country
        return (hasResourcesForLanguage(langIndex) ? TTS_LANG_COUNTRY_AVAILABLE : TTS_LANG_MISSING_DATA);
    }

    // no variants supported in this library, TTS_LANG_COUNTRY_VAR_AVAILABLE cannot be returned.
}


/** getLanguage
 *  Get the currently loaded language - if any.
 *  @lang - string with current ISO 3 letter language code, empty string if no loaded language.
 *  @country - string with current ISO 3 letter country code, empty string if no loaded language.
 *  @variant - string with current language variant, empty string if no loaded language.
 *  return tts_result
*/
tts_result TtsEngine::getLanguage(char *language, char *country, char *variant)
{
    if (picoCurrentLangIndex == -1) {
        strcpy(language, "\0");
        strcpy(country, "\0");
        strcpy(variant, "\0");
    } else {
        strcpy(language, picoSupportedLangIso3[picoCurrentLangIndex]);
        strcpy(country, picoSupportedCountryIso3[picoCurrentLangIndex]);
        // no variant in this implementation
        strcpy(variant, "\0");
    }
    return TTS_SUCCESS;
}


/** setAudioFormat
 * sets the audio format to use for synthesis, returns what is actually used.
 * @encoding - reference to encoding format
 * @rate - reference to sample rate
 * @channels - reference to number of channels
 * return tts_result
 * */
tts_result TtsEngine::setAudioFormat(AudioSystem::audio_format& encoding, uint32_t& rate,
            int& channels)
{
    // ignore the input parameters, the enforced audio parameters are fixed here
    encoding = AudioSystem::PCM_16_BIT;
    rate = 16000;
    channels = 1;
    return TTS_SUCCESS;
}


/** setProperty
 *  Set property. The supported properties are:  language, rate, pitch and volume.
 *  @property - name of property to set
 *  @value - value to set
 *  @size - size of value
 *  return tts_result
*/
tts_result TtsEngine::setProperty( const char * property, const char * value, const size_t size )
{
    int rate;
    int pitch;
    int volume;

    /* Set a specific property for the engine.
       Supported properties include: language (locale), rate, pitch, volume.    */
    /* Sanity check */
    if (property == NULL) {
        LOGE("setProperty called with property NULL");
        return TTS_PROPERTY_UNSUPPORTED;
    }

    if (value == NULL) {
        LOGE("setProperty called with value NULL");
        return TTS_VALUE_INVALID;
    }

    if (strncmp(property, "language", 8) == 0) {
        /* Verify it's in correct format.   */
        if (strlen(value) != 2 && strlen(value) != 6) {
            LOGE("change language called with incorrect format");
            return TTS_VALUE_INVALID;
        }

        /* Try to switch to specified language. */
        if (doLanguageSwitch(value) == TTS_FAILURE) {
            LOGE("failed to load language");
            return TTS_FAILURE;
        } else {
            return TTS_SUCCESS;
        }
    } else if (strncmp(property, "rate", 4) == 0) {
        rate = atoi(value);
        if (rate < PICO_MIN_RATE) {
            rate = PICO_MIN_RATE;
        }
        if (rate > PICO_MAX_RATE) {
            rate = PICO_MAX_RATE;
        }
        picoProp_currRate = rate;
        return TTS_SUCCESS;
    } else if (strncmp(property, "pitch", 5) == 0) {
        pitch = atoi(value);
        if (pitch < PICO_MIN_PITCH) {
            pitch = PICO_MIN_PITCH;
        }
        if (pitch > PICO_MAX_PITCH) {
            pitch = PICO_MAX_PITCH;
        }
        picoProp_currPitch = pitch;
        return TTS_SUCCESS;
    } else if (strncmp(property, "volume", 6) == 0) {
        volume = atoi(value);
        if (volume < PICO_MIN_VOLUME) {
            volume = PICO_MIN_VOLUME;
        }
        if (volume > PICO_MAX_VOLUME) {
            volume = PICO_MAX_VOLUME;
        }
        picoProp_currVolume = volume;
        return TTS_SUCCESS;
    }

    return TTS_PROPERTY_UNSUPPORTED;
}


/** getProperty
 *  Get the property.  Supported properties are:  language, rate, pitch and volume.
 *  @property - name of property to get
 *  @value    - buffer which will receive value of property
 *  @iosize   - size of value - if size is too small on return this will contain actual size needed
 *  return tts_result
*/
tts_result TtsEngine::getProperty( const char * property, char * value, size_t * iosize )
{
    /* Get the property for the engine.
       This property was previously set by setProperty or by default.       */
    /* sanity check */
    if (property == NULL) {
        LOGE("getProperty called with property NULL");
        return TTS_PROPERTY_UNSUPPORTED;
    }

    if (value == NULL) {
        LOGE("getProperty called with value NULL");
        return TTS_VALUE_INVALID;
    }

    if (strncmp(property, "language", 8) == 0) {
        if (picoProp_currLang == NULL) {
            strcpy(value, "");
        } else {
            if (*iosize < strlen(picoProp_currLang)+1)  {
                *iosize = strlen(picoProp_currLang) + 1;
                return TTS_PROPERTY_SIZE_TOO_SMALL;
            }
            strcpy(value, picoProp_currLang);
        }
        return TTS_SUCCESS;
    } else if (strncmp(property, "rate", 4) == 0) {
        char tmprate[4];
        sprintf(tmprate, "%d", picoProp_currRate);
        if (*iosize < strlen(tmprate)+1) {
            *iosize = strlen(tmprate) + 1;
            return TTS_PROPERTY_SIZE_TOO_SMALL;
        }
        strcpy(value, tmprate);
        return TTS_SUCCESS;
    } else if (strncmp(property, "pitch", 5) == 0) {
        char tmppitch[4];
        sprintf(tmppitch, "%d", picoProp_currPitch);
        if (*iosize < strlen(tmppitch)+1) {
            *iosize = strlen(tmppitch) + 1;
            return TTS_PROPERTY_SIZE_TOO_SMALL;
        }
        strcpy(value, tmppitch);
        return TTS_SUCCESS;
    } else if (strncmp(property, "volume", 6) == 0) {
        char tmpvol[4];
        sprintf(tmpvol, "%d", picoProp_currVolume);
        if (*iosize < strlen(tmpvol)+1) {
            *iosize = strlen(tmpvol) + 1;
            return TTS_PROPERTY_SIZE_TOO_SMALL;
        }
        strcpy(value, tmpvol);
        return TTS_SUCCESS;
    }

    /* Unknown property */
    LOGE("Unsupported property");
    return TTS_PROPERTY_UNSUPPORTED;
}


/** synthesizeText
 *  Synthesizes a text string.
 *  The text string could be annotated with SSML tags.
 *  @text     - text to synthesize
 *  @buffer   - buffer which will receive generated samples
 *  @bufferSize - size of buffer
 *  @userdata - pointer to user data which will be passed back to callback function
 *  return tts_result
*/
tts_result TtsEngine::synthesizeText( const char * text, int8_t * buffer, size_t bufferSize, void * userdata )
{
    int         err;
    int         cbret;
    pico_Char * inp = NULL;
    char *      expanded_text = NULL;
    pico_Char * local_text = NULL;
    short       outbuf[MAX_OUTBUF_SIZE/2];
    pico_Int16  bytes_sent, bytes_recv, text_remaining, out_data_type;
    pico_Status ret;
    SvoxSsmlParser * parser = NULL;

    picoSynthAbort = 0;
    if (text == NULL) {
        LOGE("synthesizeText called with NULL string");
        return TTS_FAILURE;
    }

    if (buffer == NULL) {
        LOGE("synthesizeText called with NULL buffer");
        return TTS_FAILURE;
    }

    if ( (strncmp(text, "<speak", 6) == 0) || (strncmp(text, "<?xml", 5) == 0) ) {
        /* SSML input */
        parser = new SvoxSsmlParser();
        if (parser && parser->initSuccessful()) {
            err = parser->parseDocument(text, 1);
            if (err == XML_STATUS_ERROR) {
                /* Note: for some reason expat always thinks the input document has an error
                   at the end, even when the XML document is perfectly formed */
                LOGI("Warning: SSML document parsed with errors");
            }
            char * parsed_text = parser->getParsedDocument();
            if (parsed_text) {
                /* Add property tags to the string - if any.    */
                local_text = (pico_Char *) doAddProperties( parsed_text );
                if (!local_text) {
                    LOGE("Failed to allocate memory for text string");
                    delete parser;
                    return TTS_FAILURE;
                }
                char * lang = parser->getParsedDocumentLanguage();
                if (lang != NULL) {
                    if (doLanguageSwitch(lang) == TTS_FAILURE) {
                        LOGE("Failed to switch to language (%s) specified in SSML document.", lang);
                        delete parser;
                        return TTS_FAILURE;
                    }
                } else {
                    // lang is NULL, pick a language so the synthesis can be performed
                    if (picoCurrentLangIndex == -1) {
                        // no current language loaded, pick the first one and load it
                        if (doLanguageSwitchFromLangIndex(0) == TTS_FAILURE) {
                            LOGE("Failed to switch to default language.");
                            delete parser;
                            return TTS_FAILURE;
                        }
                    }
                    LOGE("No language in SSML, using current language (%s).", picoProp_currLang);
                }
                delete parser;
            } else {
                LOGE("Failed to parse SSML document");
                delete parser;
                return TTS_FAILURE;
            }
        } else {
            LOGE("Failed to create SSML parser");
            if (parser) {
                delete parser;
            }
            return TTS_FAILURE;
        }
    } else {
        /* camelCase pre-processing */
        //expanded_text = doCamelCase(text);
        /* Add property tags to the string - if any.    */
        local_text = (pico_Char *) doAddProperties( text );//expanded_text );
        /*if (expanded_text) {
            LOGV("freeing string for %s", expanded_text);
            free( expanded_text );
        }*/
        if (!local_text) {
            LOGE("Failed to allocate memory for text string");
            return TTS_FAILURE;
        }
    }

    text_remaining = strlen((const char *) local_text) + 1;

    inp = (pico_Char *) local_text;

    size_t bufused = 0;

    /* synthesis loop   */
    while (text_remaining) {

        if (picoSynthAbort) {
            ret = pico_resetEngine( picoEngine, PICO_RESET_SOFT );
            break;
        }

        /* Feed the text into the engine.   */
        ret = pico_putTextUtf8( picoEngine, inp, text_remaining, &bytes_sent );
        if (ret != PICO_OK) {
            LOGE("Error synthesizing string '%s': [%d]", text, ret);
            if (local_text) {
                free( local_text );
            }
            return TTS_FAILURE;
        }

        text_remaining -= bytes_sent;
        inp += bytes_sent;
        do {
            if (picoSynthAbort) {
                ret = pico_resetEngine( picoEngine, PICO_RESET_SOFT );
                break;
            }
            /* Retrieve the samples and add them to the buffer. */
            ret = pico_getData( picoEngine, (void *) outbuf, MAX_OUTBUF_SIZE, &bytes_recv,
                    &out_data_type );
            if (bytes_recv) {
                if ((bufused + bytes_recv) <= bufferSize) {
                    memcpy(buffer+bufused, (int8_t *) outbuf, bytes_recv);
                    bufused += bytes_recv;
                } else {
                    /* The buffer filled; pass this on to the callback function.    */
                    cbret = picoSynthDoneCBPtr(userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer,
                            bufused, TTS_SYNTH_PENDING);
                    if (cbret == TTS_CALLBACK_HALT) {
                        LOGI("Halt requested by caller. Halting.");
                        picoSynthAbort = 1;
                        ret = pico_resetEngine( picoEngine, PICO_RESET_SOFT );
                        break;
                    }
                    bufused = 0;
                    memcpy(buffer, (int8_t *) outbuf, bytes_recv);
                    bufused += bytes_recv;
                }
            }
        } while (PICO_STEP_BUSY == ret);

        /* This chunk of synthesis is finished; pass the remaining samples.
           Use 16 KHz, 16-bit samples.                                              */
        if (!picoSynthAbort) {
            picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused,
                    TTS_SYNTH_PENDING);
        }
        picoSynthAbort = 0;

        if (ret != PICO_STEP_IDLE) {
            if (ret != 0){
                LOGE("Error occurred during synthesis [%d]", ret);
            }
            if (local_text) {
                free(local_text);
            }
            LOGV("Synth loop: sending TTS_SYNTH_DONE after error");
            picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused,
                    TTS_SYNTH_DONE);
            pico_resetEngine( picoEngine, PICO_RESET_SOFT );
            return TTS_FAILURE;
        }
    }

    /* Synthesis is done; notify the caller */
    LOGV("Synth loop: sending TTS_SYNTH_DONE after all done, or was asked to stop");
    picoSynthDoneCBPtr( userdata, 16000, AudioSystem::PCM_16_BIT, 1, buffer, bufused,
            TTS_SYNTH_DONE);

    if (local_text) {
        free( local_text );
    }
    return TTS_SUCCESS;
}


/** synthesizeIpa
 *  Synthesizes a phonetic string in IPA format.
    The Pico engine understands only XSAMPA, so the IPA must be converted.
    The string must also be parceled into words since it can only hanlde a word at a time.
    Each phonemic word must be wrapped with a tag.
 *  @ipa - phonetic string to synthesize
 *  @buffer - buffer which will receive generated samples
 *  @bufferSize - size of buffer
 *  @userdata - pointer to user data which will be passed back to callback function
 *  return tts_result
*/
tts_result TtsEngine::synthesizeIpa( const char * ipa, int8_t * buffer, size_t bufferSize, void * userdata )
{
    // deprecated call
    return TTS_FAILURE;

}


/** stop
 *  Aborts the running synthesis.
 *  return tts_result
*/
tts_result TtsEngine::stop( void )
{
    picoSynthAbort = 1;
    return TTS_SUCCESS;
}


#ifdef __cplusplus
extern "C" {
#endif

TtsEngine * getTtsEngine( void )
{
    return new TtsEngine();
}

#ifdef __cplusplus
}
#endif

