Home | History | Annotate | Download | only in lib
      1 /*
      2  * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /**
     17  * @file picoapi.c
     18  *
     19  * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
     20  * All rights reserved.
     21  *
     22  * History:
     23  * - 2009-04-20 -- initial version
     24  */
     25 #include "picodefs.h"
     26 #include "picoos.h"
     27 #include "picodbg.h"
     28 #include "picorsrc.h"
     29 #include "picoctrl.h"
     30 #include "picoapi.h"
     31 #include "picoapid.h"
     32 
     33 #ifdef __cplusplus
     34 extern "C" {
     35 #endif
     36 
     37 /* ****************************************************************************/
     38 /* System-level API functions                                                 */
     39 /* ****************************************************************************/
     40 
     41 #define MAGIC_MASK 0x5069636F  /* Pico */
     42 
     43 #define SET_MAGIC_NUMBER(sys) \
     44     (sys)->magic = ((picoos_uint32) (uintptr_t) (sys)) ^ MAGIC_MASK
     45 
     46 #define CHECK_MAGIC_NUMBER(sys) \
     47     ((sys)->magic == (((picoos_uint32) (uintptr_t) (sys)) ^ MAGIC_MASK))
     48 
     49 
     50 
     51 /* *** Auxiliary routines (may also be called from picoextapi.c) **************/
     52 
     53 
     54 int is_valid_system_handle(pico_System system)
     55 {
     56     return (system != NULL) && CHECK_MAGIC_NUMBER(system);
     57 }
     58 
     59 
     60 picoos_Common pico_sysGetCommon(pico_System this)
     61 {
     62     if (this != NULL) {
     63         return this->common;
     64     } else {
     65         return NULL;
     66     }
     67 }
     68 
     69 
     70 
     71 /* *** System initialization and termination functions ************************/
     72 pico_Status pico_initialize_priv(
     73         void *memory,
     74         const pico_Uint32 size,
     75         pico_Int16 enableMemProt,
     76         pico_System *system
     77         )
     78 {
     79     pico_Status status = PICO_OK;
     80 
     81     PICODBG_INITIALIZE(PICODBG_LOG_LEVEL_INFO);
     82     PICODBG_ENABLE_COLORS(0);
     83     /*PICODBG_SET_OUTPUT_FORMAT((PICODBG_SHOW_LEVEL | PICODBG_SHOW_SRCNAME));*/
     84 
     85     if (memory == NULL) {
     86         status = PICO_ERR_NULLPTR_ACCESS;
     87     } else if (size == 0) {
     88         status = PICO_ERR_INVALID_ARGUMENT;
     89     } else if (system == NULL) {
     90         status = PICO_ERR_NULLPTR_ACCESS;
     91     } else {
     92         byte_ptr_t rest_mem;
     93         picoos_objsize_t rest_mem_size;
     94         pico_System sys;
     95         picoos_MemoryManager sysMM;
     96         picoos_ExceptionManager sysEM;
     97 
     98         sys = (pico_System) picoos_raw_malloc(memory, size, sizeof(pico_system_t),
     99                 &rest_mem, &rest_mem_size);
    100         if (sys != NULL) {
    101             sysMM = picoos_newMemoryManager(rest_mem, rest_mem_size, enableMemProt ? TRUE : FALSE);
    102             if (sysMM != NULL) {
    103                 sysEM = picoos_newExceptionManager(sysMM);
    104                 sys->common = picoos_newCommon(sysMM);
    105                 sys->rm = picorsrc_newResourceManager(sysMM, sys->common);
    106                 if ((sysEM != NULL) && (sys->common != NULL) && (sys->rm != NULL)) {
    107                     sys->common->em = sysEM;
    108                     sys->common->mm = sysMM;
    109                     sys->engine = NULL;
    110 
    111                     picorsrc_createDefaultResource(sys->rm /*,&defaultResource */);
    112 
    113                     SET_MAGIC_NUMBER(sys);
    114                     status = PICO_OK;
    115                 } else {
    116                     status = PICO_EXC_OUT_OF_MEM;
    117                 }
    118             } else {
    119                 status = PICO_EXC_OUT_OF_MEM;
    120             }
    121         } else {
    122             status = PICO_EXC_OUT_OF_MEM;
    123         }
    124         *system = sys;
    125     }
    126 
    127     if (status != PICO_OK) {
    128         if (system != NULL) {
    129             *system = NULL;
    130         }
    131         PICODBG_TERMINATE();
    132     }
    133 
    134     return status;
    135 }
    136 /**
    137  * pico_initialize : initializes the pico system private memory
    138  * @param    memory : pointer to a free and already allocated memory area
    139  * @param    size : size of the memory area
    140  * @param    system : pointer to a pico_System struct
    141  * @return  PICO_OK : successful init, !PICO_OK : error on allocating private memory
    142  * @callgraph
    143  * @callergraph
    144 */
    145 PICO_FUNC pico_initialize(
    146         void *memory,
    147         const pico_Uint32 size,
    148         pico_System *system
    149         )
    150 {
    151     return pico_initialize_priv(memory, size, /*enableMemProt*/ FALSE, system);
    152 }
    153 
    154 /**
    155  * pico_terminate : deallocates the pico system private memory
    156  * @param    system : pointer to a pico_System struct
    157  * @return  PICO_OK : successful de-init, !PICO_OK : error on de-allocating private memory
    158  * @callgraph
    159  * @callergraph
    160 */
    161 PICO_FUNC pico_terminate(
    162         pico_System *system
    163         )
    164 {
    165     pico_Status status = PICO_OK;
    166 
    167     if ((system == NULL) || !is_valid_system_handle(*system)) {
    168         status = PICO_ERR_INVALID_HANDLE;
    169     } else {
    170         pico_System sys = *system;
    171 
    172         /* close engine(s) */
    173         picoctrl_disposeEngine(sys->common->mm, sys->rm, &sys->engine);
    174 
    175         /* close all resources */
    176         picorsrc_disposeResourceManager(sys->common->mm, &sys->rm);
    177 
    178         sys->magic ^= 0xFFFEFDFC;
    179         *system = NULL;
    180     }
    181 
    182     PICODBG_TERMINATE();
    183 
    184     return status;
    185 }
    186 
    187 
    188 
    189 /* *** System status and error/warning message retrieval function *************/
    190 
    191 /**
    192  * pico_getSystemStatusMessage : Returns a description of the system status or errors
    193  * @param    system : pointer to a pico_System struct
    194  * @param    errCode : pico_System error code
    195  * @param    outMessage : memory area where to return a string
    196  * @return  PICO_OK : successful
    197  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    198  * @callgraph
    199  * @callergraph
    200 */
    201 PICO_FUNC pico_getSystemStatusMessage(
    202         pico_System system,
    203         pico_Status errCode,
    204         pico_Retstring outMessage
    205         )
    206 {
    207     pico_Status status = PICO_OK;
    208 
    209     if (!is_valid_system_handle(system)) {
    210         status = PICO_ERR_INVALID_HANDLE;
    211         if (outMessage != NULL) {
    212             picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'system' not initialized", PICO_RETSTRINGSIZE);
    213         }
    214     } else if (outMessage == NULL) {
    215         status = PICO_ERR_NULLPTR_ACCESS;
    216     } else {
    217         if (picoos_emGetExceptionCode(system->common->em) == PICO_OK) {
    218             if (errCode == PICO_OK) {
    219                 picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "system ok", PICO_RETSTRINGSIZE);
    220             } else {
    221                 /* exceptionManager was not informed yet; produce default message */
    222                 picoos_setErrorMsg((picoos_char *) outMessage, PICO_RETSTRINGSIZE, errCode, NULL, NULL, NULL);
    223             }
    224         } else {
    225             picoos_emGetExceptionMessage(system->common->em, (picoos_char *) outMessage, PICO_RETSTRINGSIZE);
    226         }
    227     }
    228 
    229     return status;
    230 }
    231 
    232 /**
    233  * pico_getSystemStatusMessage : Returns the number of warnings
    234  * @param    system : pointer to a pico_System struct
    235  * @param    *outNrOfWarnings : pointer to location to receive number of warnings
    236  * @return  PICO_OK : successful
    237  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    238  * @callgraph
    239  * @callergraph
    240 */
    241 PICO_FUNC pico_getNrSystemWarnings(
    242         pico_System system,
    243         pico_Int32 *outNrOfWarnings
    244         )
    245 {
    246     pico_Status status = PICO_OK;
    247 
    248     if (!is_valid_system_handle(system)) {
    249         status = PICO_ERR_INVALID_HANDLE;
    250         if (outNrOfWarnings != NULL) {
    251             *outNrOfWarnings = 0;
    252         }
    253     } else if (outNrOfWarnings == NULL) {
    254         status = PICO_ERR_NULLPTR_ACCESS;
    255     } else {
    256         *outNrOfWarnings = picoos_emGetNumOfWarnings(system->common->em);
    257     }
    258 
    259     return status;
    260 }
    261 
    262 /**
    263  * pico_getSystemWarning : Returns a description of a warning
    264  * @param    system : pointer to a pico_System struct
    265  * @param    warningIndex : warning index
    266  * @param    *outCode : pointer to receive the warning code
    267  * @param    outMessage : pointer to receive the output message
    268  * @return  PICO_OK : successful
    269  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    270  * @callgraph
    271  * @callergraph
    272 */
    273 PICO_FUNC pico_getSystemWarning(
    274         pico_System system,
    275         const pico_Int32 warningIndex,
    276         pico_Status *outCode,
    277         pico_Retstring outMessage
    278         )
    279 {
    280     pico_Status status = PICO_OK;
    281 
    282     if (!is_valid_system_handle(system)) {
    283         status = PICO_ERR_INVALID_HANDLE;
    284         if (outMessage != NULL) {
    285             picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'system' not initialized", PICO_RETSTRINGSIZE);
    286         }
    287     } else if (warningIndex < 0) {
    288         status = PICO_ERR_INDEX_OUT_OF_RANGE;
    289     } else if ((outCode == NULL) || (outMessage == NULL)) {
    290         status = PICO_ERR_NULLPTR_ACCESS;
    291     } else {
    292         *outCode = picoos_emGetWarningCode(system->common->em, warningIndex);
    293         picoos_emGetWarningMessage(system->common->em, warningIndex, (picoos_char *) outMessage, (picoos_uint16) PICO_RETSTRINGSIZE);
    294     }
    295 
    296     return status;
    297 }
    298 
    299 
    300 
    301 /* *** Resource loading and unloading functions *******************************/
    302 
    303 /**
    304  * pico_loadResource : Loads a resource file into the Pico system
    305  * @param    system : pointer to a pico_System struct
    306  * @param    *lingwareFileName : lingware resource file name
    307  * @param    *outLingware : pointer to receive the loaded lingware resource memory area address
    308  * @return  PICO_OK : successful
    309  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    310  * @callgraph
    311  * @callergraph
    312 */
    313 PICO_FUNC pico_loadResource(
    314         pico_System system,
    315         const pico_Char *lingwareFileName,
    316         pico_Resource *outLingware
    317         )
    318 {
    319     pico_Status status = PICO_OK;
    320 
    321     if (!is_valid_system_handle(system)) {
    322         status = PICO_ERR_INVALID_HANDLE;
    323     } else if ((lingwareFileName == NULL) || (outLingware == NULL)) {
    324         status = PICO_ERR_NULLPTR_ACCESS;
    325     } else {
    326         PICODBG_DEBUG(("memory usage before resource loading"));
    327         picoos_showMemUsage(system->common->mm, FALSE, TRUE);
    328         picoos_emReset(system->common->em);
    329         status = picorsrc_loadResource(system->rm, (picoos_char *) lingwareFileName, (picorsrc_Resource *) outLingware);
    330         PICODBG_DEBUG(("memory used to load resource %s", lingwareFileName));
    331         picoos_showMemUsage(system->common->mm, TRUE, FALSE);
    332     }
    333 
    334     return status;
    335 }
    336 
    337 /**
    338  * pico_unloadResource : unLoads a resource file from the Pico system
    339  * @param    system : pointer to a pico_System struct
    340  * @param    *inoutLingware : pointer to the loaded lingware resource memory area address
    341  * @return  PICO_OK : successful
    342  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    343  * @callgraph
    344  * @callergraph
    345 */
    346 PICO_FUNC pico_unloadResource(
    347         pico_System system,
    348         pico_Resource *inoutLingware
    349         )
    350 {
    351     pico_Status status = PICO_OK;
    352 
    353     if (!is_valid_system_handle(system)) {
    354         status = PICO_ERR_INVALID_HANDLE;
    355     } else if (inoutLingware == NULL) {
    356         status = PICO_ERR_NULLPTR_ACCESS;
    357     } else if (!picoctrl_isValidResourceHandle(*((picorsrc_Resource *) inoutLingware))) {
    358         status = PICO_ERR_INVALID_HANDLE;
    359     } else {
    360         PICODBG_DEBUG(("memory usage before resource unloading"));
    361         picoos_showMemUsage(system->common->mm, FALSE, TRUE);
    362         picoos_emReset(system->common->em);
    363         status = picorsrc_unloadResource(system->rm, (picorsrc_Resource *) inoutLingware);
    364         PICODBG_DEBUG(("memory released by resource unloading"));
    365         picoos_showMemUsage(system->common->mm, TRUE, FALSE);
    366     }
    367 
    368     return status;
    369 }
    370 
    371 /* *** Resource inspection functions *******************************/
    372 /**
    373  * pico_getResourceName : Gets a resource name
    374  * @param    system : pointer to a pico_System struct
    375  * @param    resource : pointer to the loaded resource memory area address
    376  * @param    outName : pointer to the area to receuive the resource name
    377  * @return  PICO_OK : successful
    378  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    379  * @callgraph
    380  * @callergraph
    381 */
    382 PICO_FUNC pico_getResourceName(
    383         pico_System system,
    384         pico_Resource resource,
    385         pico_Retstring outName) {
    386 
    387     if (!is_valid_system_handle(system)) {
    388         return PICO_ERR_INVALID_HANDLE;
    389     } else if (NULL == outName) {
    390         return PICO_ERR_NULLPTR_ACCESS;
    391     }
    392     return picorsrc_rsrcGetName((picorsrc_Resource)resource, (picoos_char *) outName, PICO_RETSTRINGSIZE);
    393 }
    394 
    395 
    396 /* *** Voice definition functions *********************************************/
    397 
    398 /**
    399  * pico_createVoiceDefinition : Creates a voice definition
    400  * @param    system : pointer to a pico_System struct
    401  * @param    *voiceName : pointer to the area to receive the voice definition
    402  * @return  PICO_OK : successful
    403  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    404  * @callgraph
    405  * @callergraph
    406 */
    407 PICO_FUNC pico_createVoiceDefinition(
    408         pico_System system,
    409         const pico_Char *voiceName
    410         )
    411 {
    412     pico_Status status = PICO_OK;
    413 
    414     if (!is_valid_system_handle(system)) {
    415         status = PICO_ERR_INVALID_HANDLE;
    416     } else if (voiceName == NULL) {
    417         status = PICO_ERR_NULLPTR_ACCESS;
    418     } else if (picoos_strlen((picoos_char *) voiceName) == 0) {
    419         status = PICO_ERR_INVALID_ARGUMENT;
    420     } else {
    421         picoos_emReset(system->common->em);
    422         status = picorsrc_createVoiceDefinition(system->rm, (picoos_char *) voiceName);
    423     }
    424 
    425     return status;
    426 }
    427 
    428 /**
    429  * pico_addResourceToVoiceDefinition : Adds a mapping pair to a voice definition
    430  * @param    system : pointer to a pico_System struct
    431  * @param    *voiceName : pointer to the area containing the voice definition
    432  * @param    *resourceName : pointer to the area containing the resource name
    433  * @return  PICO_OK : successful
    434  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    435  * @callgraph
    436  * @callergraph
    437 */
    438 PICO_FUNC pico_addResourceToVoiceDefinition(
    439         pico_System system,
    440         const pico_Char *voiceName,
    441         const pico_Char *resourceName
    442         )
    443 {
    444     pico_Status status = PICO_OK;
    445 
    446     if (!is_valid_system_handle(system)) {
    447         status = PICO_ERR_INVALID_HANDLE;
    448     } else if (voiceName == NULL) {
    449         status = PICO_ERR_NULLPTR_ACCESS;
    450     } else if (picoos_strlen((picoos_char *) voiceName) == 0) {
    451         status = PICO_ERR_INVALID_ARGUMENT;
    452     } else if (resourceName == NULL) {
    453         status = PICO_ERR_NULLPTR_ACCESS;
    454     } else if (picoos_strlen((picoos_char *) resourceName) == 0) {
    455         status = PICO_ERR_INVALID_ARGUMENT;
    456     } else {
    457         picoos_emReset(system->common->em);
    458         status = picorsrc_addResourceToVoiceDefinition(system->rm, (picoos_char *) voiceName, (picoos_char *) resourceName);
    459     }
    460 
    461     return status;
    462 }
    463 
    464 /**
    465  * pico_releaseVoiceDefinition : Releases a voice definition
    466  * @param    system : pointer to a pico_System struct
    467  * @param    *voiceName : pointer to the area containing the voice definition
    468  * @return  PICO_OK : successful
    469  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    470  * @callgraph
    471  * @callergraph
    472 */
    473 PICO_FUNC pico_releaseVoiceDefinition(
    474         pico_System system,
    475         const pico_Char *voiceName
    476         )
    477 {
    478     pico_Status status = PICO_OK;
    479 
    480     if (!is_valid_system_handle(system)) {
    481         status = PICO_ERR_INVALID_HANDLE;
    482     } else if (voiceName == NULL) {
    483         status = PICO_ERR_NULLPTR_ACCESS;
    484     } else if (picoos_strlen((picoos_char *) voiceName) == 0) {
    485         status = PICO_ERR_INVALID_ARGUMENT;
    486     } else {
    487         picoos_emReset(system->common->em);
    488         status = picorsrc_releaseVoiceDefinition(system->rm, (picoos_char *) voiceName);
    489     }
    490 
    491     return status;
    492 }
    493 
    494 
    495 
    496 /* *** Engine creation and deletion functions *********************************/
    497 
    498 /**
    499  * pico_newEngine : Creates and initializes a new Pico engine
    500  * @param    system : pointer to a pico_System struct
    501  * @param    *voiceName : pointer to the area containing the voice definition
    502  * @param    *outEngine : pointer to the Pico engine handle
    503  * @return  PICO_OK : successful
    504  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    505  * @callgraph
    506  * @callergraph
    507 */
    508 PICO_FUNC pico_newEngine(
    509         pico_System system,
    510         const pico_Char *voiceName,
    511         pico_Engine *outEngine
    512         )
    513 {
    514     pico_Status status = PICO_OK;
    515 
    516     PICODBG_DEBUG(("creating engine for voice '%s'", (picoos_char *) voiceName));
    517 
    518     if (!is_valid_system_handle(system)) {
    519         status = PICO_ERR_INVALID_HANDLE;
    520     } else if (voiceName == NULL) {
    521         status = PICO_ERR_NULLPTR_ACCESS;
    522     } else if (picoos_strlen((picoos_char *) voiceName) == 0) {
    523         status = PICO_ERR_INVALID_ARGUMENT;
    524     } else if (outEngine == NULL) {
    525         status = PICO_ERR_NULLPTR_ACCESS;
    526     } else {
    527         picoos_emReset(system->common->em);
    528         if (system->engine == NULL) {
    529             *outEngine = (pico_Engine) picoctrl_newEngine(system->common->mm, system->rm, voiceName);
    530             if (*outEngine != NULL) {
    531                 system->engine = (picoctrl_Engine) *outEngine;
    532             } else {
    533                 status = picoos_emRaiseException(system->common->em, PICO_EXC_OUT_OF_MEM,
    534                             (picoos_char *) "out of memory creating new engine", NULL);
    535             }
    536         } else {
    537             status = picoos_emRaiseException(system->common->em, PICO_EXC_MAX_NUM_EXCEED,
    538                         NULL, (picoos_char *) "no more than %i engines", 1);
    539         }
    540     }
    541 
    542     return status;
    543 }
    544 
    545 /**
    546  * pico_disposeEngine : Disposes a Pico engine
    547  * @param    system : pointer to a pico_System struct
    548  * @param    *inoutEngine : pointer to the Pico engine handle
    549  * @return  PICO_OK : successful
    550  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    551  * @callgraph
    552  * @callergraph
    553 */
    554 PICO_FUNC pico_disposeEngine(
    555         pico_System system,
    556         pico_Engine *inoutEngine
    557         )
    558 {
    559     pico_Status status = PICO_OK;
    560 
    561     if (!is_valid_system_handle(system)) {
    562         status = PICO_ERR_INVALID_HANDLE;
    563     } else if (inoutEngine == NULL) {
    564         status = PICO_ERR_NULLPTR_ACCESS;
    565     } else if (!picoctrl_isValidEngineHandle(*((picoctrl_Engine *) inoutEngine))) {
    566         status = PICO_ERR_INVALID_HANDLE;
    567     } else {
    568         picoos_emReset(system->common->em);
    569         picoctrl_disposeEngine(system->common->mm, system->rm, (picoctrl_Engine *) inoutEngine);
    570         system->engine = NULL;
    571         status = picoos_emGetExceptionCode(system->common->em);
    572     }
    573 
    574     return status;
    575 }
    576 
    577 
    578 
    579 /* ****************************************************************************/
    580 /* Engine-level API functions                                                 */
    581 /* ****************************************************************************/
    582 
    583 /**
    584  * pico_putTextUtf8 : Puts UTF8 text into Pico text input buffer
    585  * @param    engine : pointer to a Pico engine handle
    586  * @param    *text : pointer to the text buffer
    587  * @param    textSize : text buffer size
    588  * @param    *bytesPut : pointer to variable to receive the number of bytes put
    589  * @return  PICO_OK : successful
    590  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    591  * @callgraph
    592  * @callergraph
    593  */
    594 PICO_FUNC pico_putTextUtf8(
    595         pico_Engine engine,
    596         const pico_Char *text,
    597         const pico_Int16 textSize,
    598         pico_Int16 *bytesPut)
    599 {
    600     pico_Status status = PICO_OK;
    601 
    602     if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
    603         status = PICO_ERR_INVALID_HANDLE;
    604     } else if (text == NULL) {
    605         status = PICO_ERR_NULLPTR_ACCESS;
    606     } else if (textSize < 0) {
    607         status = PICO_ERR_INVALID_ARGUMENT;
    608     } else if (bytesPut == NULL) {
    609         status = PICO_ERR_NULLPTR_ACCESS;
    610     } else {
    611         picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
    612         status = picoctrl_engFeedText((picoctrl_Engine) engine, (picoos_char *)text, textSize, bytesPut);
    613     }
    614 
    615     return status;
    616 }
    617 
    618 /**
    619  * pico_getData : Gets speech data from the engine.
    620  * @param    engine : pointer to a Pico engine handle
    621  * @param    *buffer : pointer to output buffer
    622  * @param    bufferSize : out buffer size
    623  * @param    *bytesReceived : pointer to a variable to receive the number of bytes received
    624  * @param    *outDataType : pointer to a variable to receive the type of buffer received
    625  * @return  PICO_OK : successful
    626  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    627  * @callgraph
    628  * @callergraph
    629 */
    630 PICO_FUNC pico_getData(
    631         pico_Engine engine,
    632         void *buffer,
    633         const pico_Int16 bufferSize,
    634         pico_Int16 *bytesReceived,
    635         pico_Int16 *outDataType
    636         )
    637 {
    638     pico_Status status = PICO_OK;
    639 
    640     if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
    641         status = PICO_STEP_ERROR;
    642     } else if (buffer == NULL) {
    643         status = PICO_STEP_ERROR;
    644     } else if (bufferSize < 0) {
    645         status = PICO_STEP_ERROR;
    646     } else if (bytesReceived == NULL) {
    647         status = PICO_STEP_ERROR;
    648     } else {
    649         picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
    650         status = picoctrl_engFetchOutputItemBytes((picoctrl_Engine) engine, (picoos_char *)buffer, bufferSize, bytesReceived);
    651         if ((status != PICO_STEP_IDLE) && (status != PICO_STEP_BUSY)) {
    652             status = PICO_STEP_ERROR;
    653         }
    654     }
    655 
    656     *outDataType = PICO_DATA_PCM_16BIT;
    657     return status;
    658 }
    659 
    660 /**
    661  * pico_resetEngine : Resets the engine
    662  * @param    engine : pointer to a Pico engine handle
    663  * @param resetMode : reset mode; one of PICO_RESET_FULL or PICO_RESET_SOFT
    664  * @return  PICO_OK : successful
    665  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    666  * @callgraph
    667  * @callergraph
    668 */
    669 PICO_FUNC pico_resetEngine(
    670         pico_Engine engine,
    671         pico_Int32 resetMode)
    672 {
    673     pico_Status status = PICO_OK;
    674 
    675     if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
    676         status = PICO_ERR_INVALID_HANDLE;
    677     } else {
    678         picoctrl_engResetExceptionManager((picoctrl_Engine) engine);
    679 
    680         resetMode = (PICO_RESET_SOFT == resetMode) ? PICO_RESET_SOFT : PICO_RESET_FULL;
    681 
    682         status = picoctrl_engReset((picoctrl_Engine) engine, (picoos_int32)resetMode);
    683     }
    684 
    685     return status;
    686 }
    687 
    688 /**
    689  * pico_getEngineStatusMessage : Returns the engine status or error description
    690  * @param    engine : pointer to a Pico engine handle
    691  * @param    errCode : error code
    692  * @param    outMessage : pointer to a memory area to receive the output message
    693  * @return  PICO_OK : successful
    694  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    695  * @callgraph
    696  * @callergraph
    697 */
    698 PICO_FUNC pico_getEngineStatusMessage(
    699         pico_Engine engine,
    700         pico_Status errCode,
    701         pico_Retstring outMessage
    702         )
    703 {
    704     pico_Status status = PICO_OK;
    705 
    706     PICODBG_DEBUG(("got error code %i", errCode));
    707 
    708     if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
    709         status = PICO_ERR_INVALID_HANDLE;
    710         if (outMessage != NULL) {
    711             picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'engine' not initialized", PICO_RETSTRINGSIZE);
    712         }
    713     } else if (outMessage == NULL) {
    714         status = PICO_ERR_NULLPTR_ACCESS;
    715     } else {
    716         picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
    717         if (picoos_emGetExceptionCode(common->em) == PICO_OK) {
    718             if (errCode == PICO_OK) {
    719                 picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "engine ok", PICO_RETSTRINGSIZE);
    720             } else {
    721                 /* exceptionManager was not informed yet; produce default message */
    722                 picoos_setErrorMsg((picoos_char *) outMessage, PICO_RETSTRINGSIZE, errCode, NULL, NULL, NULL);
    723             }
    724         } else {
    725             picoos_emGetExceptionMessage(common->em, (picoos_char *) outMessage, PICO_RETSTRINGSIZE);
    726         }
    727     }
    728 
    729     return status;
    730 }
    731 
    732 /**
    733  * pico_getNrEngineWarnings : Returns the number of warnings
    734  * @param    engine : pointer to a Pico engine handle
    735  * @param    *outNrOfWarnings: pointer to a variable to receive the number of warnings
    736  * @return  PICO_OK : successful
    737  * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    738  * @callgraph
    739  * @callergraph
    740 */
    741 PICO_FUNC pico_getNrEngineWarnings(
    742         pico_Engine engine,
    743         pico_Int32 *outNrOfWarnings
    744         )
    745 {
    746     pico_Status status = PICO_OK;
    747 
    748     if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
    749         status = PICO_ERR_INVALID_HANDLE;
    750         if (outNrOfWarnings != NULL) {
    751             *outNrOfWarnings = 0;
    752         }
    753     } else if (outNrOfWarnings == NULL) {
    754         status = PICO_ERR_NULLPTR_ACCESS;
    755     } else {
    756         picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
    757         *outNrOfWarnings = picoos_emGetNumOfWarnings(common->em);
    758     }
    759 
    760     return status;
    761 }
    762 
    763 /**
    764      * pico_getEngineWarning : Returns a description of a warning
    765      * @param    engine : pointer to a Pico engine handle
    766      * @param    warningIndex : warning index
    767      * @param    *outCode: pointer to a variable to receive the warning code
    768      * @param    outMessage: pointer to a memory area to receive the warning description
    769      * @return  PICO_OK : successful
    770      * @return     PICO_ERR_INVALID_HANDLE, PICO_ERR_NULLPTR_ACCESS : errors
    771      * @callgraph
    772      * @callergraph
    773 */
    774 PICO_FUNC pico_getEngineWarning(
    775         pico_Engine engine,
    776         const pico_Int32 warningIndex,
    777         pico_Status *outCode,
    778         pico_Retstring outMessage
    779         )
    780 {
    781     pico_Status status = PICO_OK;
    782 
    783     if (!picoctrl_isValidEngineHandle((picoctrl_Engine) engine)) {
    784         status = PICO_ERR_INVALID_HANDLE;
    785         if (outMessage != NULL) {
    786             picoos_strlcpy((picoos_char *) outMessage, (picoos_char *) "'engine' not initialized", PICO_RETSTRINGSIZE);
    787         }
    788     } else if (warningIndex < 0) {
    789         status = PICO_ERR_INDEX_OUT_OF_RANGE;
    790     } else if ((outCode == NULL) || (outMessage == NULL)) {
    791         status = PICO_ERR_NULLPTR_ACCESS;
    792     } else {
    793         picoos_Common common = picoctrl_engGetCommon((picoctrl_Engine) engine);
    794         *outCode = picoos_emGetWarningCode(common->em, warningIndex);
    795         picoos_emGetWarningMessage(common->em, warningIndex, (picoos_char *) outMessage, (picoos_uint16) PICO_RETSTRINGSIZE);
    796     }
    797 
    798     return status;
    799 }
    800 
    801 #ifdef __cplusplus
    802 }
    803 #endif
    804 
    805 
    806 /* end */
    807