/* 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     100

/* 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;

char * pico_alt_lingware_path = NULL;


/* 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_alt_lingware_path).                                            */
    strcpy((char*)fileName, pico_alt_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_alt_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_alt_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_alt_lingware_path);
    strcat((char*)tmpFileName, (const char*)picoInternalTaLingware[langIndex]);
    pFile = fopen(tmpFileName, "r");
    if (pFile != NULL) {
        /* "ta" file found under pico_alt_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_alt_lingware_path);
        strcpy((char *) picoSgFileName,   pico_alt_lingware_path);
        strcpy((char *) picoUtppFileName, pico_alt_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;
    }

    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;
    }
    //}
    if (outpos == 0) {
        outpos = 1;
    }
    data[outpos-1] = 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
 *  config - the engine configuration parameters, here only contains the non-system path
 *      for the lingware location
 *  return tts_result
*/
tts_result TtsEngine::init( synthDoneCB_t synthDoneCBPtr, const char *config )
{
    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;

    // was the initialization given an alternative path for the lingware location?
    if ((config != NULL) && (strlen(config) > 0)) {
        pico_alt_lingware_path = (char*)malloc(strlen(config));
        strcpy((char*)pico_alt_lingware_path, config);
        LOGV("Alternative lingware path %s", pico_alt_lingware_path);
    } else {
        pico_alt_lingware_path = (char*)malloc(strlen(PICO_LINGWARE_PATH));
        strcpy((char*)pico_alt_lingware_path, PICO_LINGWARE_PATH);
        LOGV("Using predefined lingware path %s", pico_alt_lingware_path);
    }

    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 (strlen(text) == 0) {
        return TTS_SUCCESS;
    }

    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( expanded_text );
        if (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;
}



/** 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

