summaryrefslogtreecommitdiffstats
path: root/lib/picopam.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/picopam.c')
-rw-r--r--lib/picopam.c4803
1 files changed, 4803 insertions, 0 deletions
diff --git a/lib/picopam.c b/lib/picopam.c
new file mode 100644
index 0000000..02e5cc2
--- /dev/null
+++ b/lib/picopam.c
@@ -0,0 +1,4803 @@
+/*
+ * 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.
+ */
+/**
+ * @file picopam.c
+ *
+ * Phonetic to Acoustic Mapping PU - Implementation
+ *
+ * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
+ * All rights reserved.
+ *
+ * History:
+ * - 2009-04-20 -- initial version
+ *
+ */
+
+#include "picodefs.h"
+#include "picoos.h"
+#include "picodbg.h"
+#include "picodata.h"
+#include "picopam.h"
+#include "picokdt.h"
+#include "picokpdf.h"
+#include "picoktab.h"
+#include "picokdbg.h"
+#include "picodsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if 0
+}
+#endif
+
+#define PICOPAM_IN_BUFF_SIZE PICODATA_BUFSIZE_PAM /*input buffer size for PAM */
+#define PICOPAM_OUT_PAM_SIZE PICODATA_BUFSIZE_PAM /*output buffer size for PAM*/
+#define PICOPAM_DT_NRLFZ 5 /* nr of lfz decision trees per phoneme */
+#define PICOPAM_DT_NRMGC 5 /* nr of mgc decision trees per phoneme */
+#define PICOPAM_NRSTPF 5 /* nr of states per phone */
+
+#define PICOPAM_COLLECT 0
+#define PICOPAM_SCHEDULE 1
+#define PICOPAM_IMMEDIATE 2
+#define PICOPAM_FORWARD 3
+#define PICOPAM_FORWARD_FORCE_TERM 4
+#define PICOPAM_PROCESS 5
+#define PICOPAM_PLAY 6
+#define PICOPAM_FEED 7
+
+#define PICOPAM_CONTINUE 100
+#define PICOPAM_GOTO_SCHEDULE 1
+#define PICOPAM_FLUSH_RECEIVED 6
+#define PICOPAM_GOTO_FEED 7
+#define PICOPAM_PRE_SYLL_ENDED 10
+
+#define PICOPAM_BREAK_ADD_SIZE 4 /*syllable feature vector increment dued to BREAK and SILENCE*/
+#define PICOPAM_VECT_SIZE 64+PICOPAM_BREAK_ADD_SIZE /*syllable feature vector size (bytes)*/
+#define PICOPAM_INVEC_SIZE 60 /*phone feature vector size */
+#define PICOPAM_MAX_SYLL_PER_SENT 100 /*maximum number of syllables per sentece*/
+#define PICOPAM_MAX_PH_PER_SENT 400 /*maximum number of phonemes per sentece*/
+#define PICOPAM_MAX_ITEM_PER_SENT 255 /*maximum number of attached items per sentence*/
+#define PICOPAM_MAX_ITEM_SIZE_PER_SENT 4096 /*maximum size of attached items per sentence*/
+
+#define PICOPAM_READY 20 /*PAM could start backward processing*/
+#define PICOPAM_MORE 21 /*PAM has still to collect */
+#define PICOPAM_NA 22 /*PAM has not to deal with this item*/
+#define PICOPAM_ERR 23 /*input item is not a valid item*/
+
+/*sentence types:cfr pam_map_sentence_type*/
+#define PICOPAM_DECLARATIVE 0
+#define PICOPAM_INTERROGATIVE 1
+#define PICOPAM_EXCLAMATIVE 2
+
+#define PICOPAM_T 0
+#define PICOPAM_P 1
+#define PICOPAM_p 2
+#define PICOPAM_Y 3
+
+#if 1
+#define PAM_PHR2_WITH_PR1 1 /*deal with PHR2 boundaries as with PHR1*/
+#else
+#define PAM_PHR2_WITH_PR3 1 /*deal with PHR2 boundaries as with PHR3*/
+#endif
+
+#define PICOPAM_DONT_CARE_VALUE 250 /*don't care value for tree printout */
+#define PICOPAM_DONT_CARE_VAL 10 /*don't care value for tree feeding */
+#define PICOPAM_PH_DONT_CARE_VAL 7 /*don't care value for tree feeding (phonetic)*/
+
+#define PICOPAM_MAX_STATES_PER_PHONE 5 /*number of states per phone */
+#define PICOPAM_STATE_SIZE_IN_ITEM 6 /*size of a state in frame item */
+#define PICOPAM_FRAME_ITEM_SIZE 4+PICOPAM_MAX_STATES_PER_PHONE*PICOPAM_STATE_SIZE_IN_ITEM
+
+#define PICOPAM_DIR_FORW 0 /*forward adapter processing*/
+#define PICOPAM_DIR_BACK 1 /*backward adapter processing*/
+#define PICOPAM_DIR_SIL 2 /*final silence attributes*/
+
+#define PICOPAM_SYLL_PAUSE 0 /*syllable but containing a pause phone*/
+#define PICOPAM_SYLL_SYLL 1 /*a real syllable with phonemes*/
+
+#define PICOPAM_EVENT_P_BOUND 0 /*primary boundary*/
+#define PICOPAM_EVENT_S_BOUND 1 /*secondary boundary*/
+#define PICOPAM_EVENT_W_BOUND 3 /*word boundary*/
+#define PICOPAM_EVENT_SYLL 4 /*syllable*/
+
+/* ----- CONSTANTS FOR BREAK COMMAND SUPPORT ----- */
+#define PICOPAM_PWIDX_SBEG 0
+#define PICOPAM_PWIDX_PHR1 1
+#define PICOPAM_PWIDX_PHR2 2
+#define PICOPAM_PWIDX_SEND 3
+#define PICOPAM_PWIDX_DEFA 4
+#define PICOPAM_PWIDX_SIZE 5
+
+/*----------------------------------------------------------------*/
+/*structure related to the feature vectors for feeding the trees */
+/*NOTE : the same data structure is used to manage the syllables */
+/* Using the first 8 fields for marking the boundaries */
+/* and using the last 4 bytes as follows */
+/* byte 61 : 1st attached non PAM item id(0=no item attached) */
+/* in the "sSyllItemOffs" data structure */
+/* byte 62 : last attached non PAM item id(0=no item attached)*/
+/* in the "sSyllItemOffs" data structure */
+/* byte 63..64 : offset of the start of the syllable in */
+/* the "sPhIds" data structure */
+typedef struct
+{
+ picopal_uint8 phoneV[PICOPAM_VECT_SIZE];
+} sFtVect, *pSftVect;
+
+/*----------------------------------------------------------
+ Name : pam_subobj
+ Function: subobject definition for the pam processing
+ Shortcut: pam
+ ---------------------------------------------------------*/
+typedef struct pam_subobj
+{
+ /*----------------------PU voice management------------------------------*/
+ /* picorsrc_Voice voice; */
+ /*----------------------PU state management------------------------------*/
+ picoos_uint8 procState; /* where to take up work at next processing step */
+ picoos_uint8 retState; /* where to go back from feed state at next p.s. */
+ picoos_uint8 needMoreInput; /* more data necessary to start processing */
+ /*----------------------PU input management------------------------------*/
+ picoos_uint8 inBuf[PICOPAM_IN_BUFF_SIZE]; /* internal input buffer */
+ picoos_uint16 inBufSize; /* actually allocated size */
+ picoos_uint16 inReadPos, inWritePos; /* next pos to read/write from/to inBuf*/
+ /*----------------------PU output management-----------------------------*/
+ picoos_uint8 outBuf[PICOPAM_OUT_PAM_SIZE]; /* internal output buffer */
+ picoos_uint16 outBufSize; /* actually allocated size */
+ picoos_uint16 outReadPos, outWritePos; /* next pos to read/write from/to outBuf*/
+ /*---------------------- adapter working buffers --------------------*/
+ picoos_uint8 *sPhFeats; /*feature vector for a single phone */
+ sFtVect *sSyllFeats; /*Syllable feature vector set for the
+ full sentence */
+ picoos_uint8 *sPhIds; /*phone ids for the full sentence */
+ picoos_uint8 *sSyllItems; /*items attached to the syllable */
+ picoos_int16 *sSyllItemOffs;/*offset of items attached to the syllable*/
+ /*---------------------- adapter general variables ---------------------*/
+ picoos_int16 nTotalPhonemes; /*number of phonemes in the sentence*/
+ picoos_int16 nCurrPhoneme; /*current phoneme in the sentence */
+ picoos_int16 nSyllPhoneme; /*current phoneme in the syllable */
+ picoos_int16 nCurrSyllable; /*current syllable in the sentence */
+ picoos_int16 nTotalSyllables; /*number of syllables in the sentence -> J1*/
+ picoos_uint8 nLastAttachedItemId;/*last attached item id*/
+ picoos_uint8 nCurrAttachedItem; /*current attached item*/
+ picoos_int16 nAttachedItemsSize; /*total size of the attached items*/
+ picoos_uint8 sType; /*Sentence type*/
+ picoos_uint8 pType; /*Phrase type*/
+ picoos_single pMod; /*pitch modifier*/
+ picoos_single dMod; /*Duration modifier*/
+ picoos_single dRest; /*Duration modifier rest*/
+ /*---------------------- adapter specific component variables ----------*/
+ picoos_uint8 a3_overall_syllable; /* A3 */
+ picoos_uint8 a3_primary_phrase_syllable;
+ picoos_uint8 b4_b5_syllable; /* B4,B5 */
+ picoos_uint8 b6_b7_syllable; /* B6,B7 */
+ picoos_uint8 b6_b7_state;
+ picoos_uint8 b8_b9_stressed_syllable; /* B8,B9 */
+ picoos_uint8 b10_b11_accented_syllable; /* B10,B11 */
+ picoos_uint8 b12_b13_syllable; /* B12,B13 */
+ picoos_uint8 b12_b13_state;
+ picoos_uint8 b14_b15_syllable; /* B14,B15 */
+ picoos_uint8 b14_b15_state;
+ picoos_uint8 b17_b19_syllable; /* B17,B19 */
+ picoos_uint8 b17_b19_state;
+ picoos_uint8 b18_b20_b21_syllable; /* B18,B20,B21 */
+ picoos_uint8 b18_b20_b21_state;
+ picoos_uint8 c3_overall_syllable; /* C3 */
+ picoos_uint8 c3_primary_phrase_syllable;
+ picoos_uint8 d2_syllable_in_word; /* D2 */
+ picoos_uint8 d2_prev_syllable_in_word;
+ picoos_uint8 d2_current_primary_phrase_word;
+ picoos_int8 e1_syllable_word_start; /* E1 */
+ picoos_int8 e1_syllable_word_end;
+ picoos_uint8 e1_content;
+ picoos_int8 e2_syllable_word_start; /* E2 */
+ picoos_int8 e2_syllable_word_end;
+ picoos_uint8 e3_e4_word; /* E3,E4 */
+ picoos_uint8 e3_e4_state;
+ picoos_uint8 e5_e6_content_word; /* E5,E6 */
+ picoos_uint8 e5_e6_content;
+ picoos_uint8 e7_e8_word; /* E7,E8 */
+ picoos_uint8 e7_e8_content;
+ picoos_uint8 e7_e8_state;
+ picoos_uint8 e9_e11_word; /* E9,E11 */
+ picoos_uint8 e9_e11_saw_word;
+ picoos_uint8 e9_e11_state;
+ picoos_uint8 e10_e12_e13_word; /* E10,E12,E13 */
+ picoos_uint8 e10_e12_e13_state;
+ picoos_uint8 e10_e12_e13_saw_word;
+ picoos_uint8 f2_overall_word; /* F2 */
+ picoos_uint8 f2_word_syllable;
+ picoos_uint8 f2_next_word_syllable;
+ picoos_uint8 f2_current_primary_phrase_word;
+ picoos_int8 g1_current_secondary_phrase_syllable; /*G1 */
+ picoos_int8 g1_current_syllable;
+ picoos_int8 g2_current_secondary_phrase_word; /*G2 */
+ picoos_int8 g2_current_word;
+ picoos_uint8 h1_current_secondary_phrase_syll; /*H1 */
+ picoos_uint8 h2_current_secondary_phrase_word; /*H2 */
+ picoos_uint8 h3_h4_current_secondary_phrase_word; /*H3,H4 */
+ picoos_uint8 h5_current_phrase_type; /*H5 */
+
+ picoos_uint8 h5_syllable; /* H5 */
+ picoos_uint8 h5_state;
+
+ picoos_uint8 i1_secondary_phrase_syllable; /*I1 */
+ picoos_uint8 i1_next_secondary_phrase_syllable;
+ picoos_uint8 i2_secondary_phrase_word; /*I2 */
+ picoos_uint8 i2_next_secondary_phrase_word;
+ picoos_uint8 j1_utterance_syllable; /*J1 */
+ picoos_uint8 j2_utterance_word; /*J2 */
+ picoos_uint8 j3_utterance_sec_phrases; /*J3 */
+ /*---------------------- constant data -------------------*/
+ picoos_uint16 sil_weights[PICOPAM_PWIDX_SIZE][PICOPAM_MAX_STATES_PER_PHONE];
+ /*---------------------- LINGWARE related data -------------------*/
+ picokdt_DtPAM dtdur; /* dtdur knowledge base */
+ picokdt_DtPAM dtlfz[PICOPAM_DT_NRLFZ]; /* dtlfz knowledge bases */
+ picokdt_DtPAM dtmgc[PICOPAM_DT_NRMGC]; /* dtmgc knowledge bases */
+ /*---------------------- Pdfs related data -------------------*/
+ picokpdf_PdfDUR pdfdur; /* pdfdur knowledge base */
+ picokpdf_PdfMUL pdflfz; /* pdflfz knowledge base */
+ /*---------------------- Tree traversal related data -------------------*/
+ picoos_uint16 durIndex;
+ picoos_uint8 numFramesState[PICOPAM_DT_NRLFZ];
+ picoos_uint16 lf0Index[PICOPAM_DT_NRLFZ];
+ picoos_uint16 mgcIndex[PICOPAM_DT_NRMGC];
+ /*---------------------- temps for updating the feature vector ---------*/
+ picoos_uint16 phonDur;
+ picoos_single phonF0[PICOPAM_DT_NRLFZ];
+ /*---------------------- Phones related data -------------------*/
+ picoktab_Phones tabphones;
+} pam_subobj_t;
+
+
+/* ----- CONSTANTS FOR FEATURE VECTOR BUILDING (NOT PREFIXED WITH "PICOPAM_" FOR BREVITY) ----- */
+#define P1 0 /*field 1 of the input vector*/
+#define P2 1
+#define P3 2
+#define P4 3
+#define P5 4
+#define P6 5
+#define P7 6
+#define bnd 6 /*boundary type item associated to the syllable = P7 */
+#define P8 7
+#define A3 8
+#define B1 9
+#define B2 10
+#define B3 11
+#define B4 12
+#define B5 13
+#define B6 14
+#define B7 15
+#define B8 16
+#define B9 17
+#define B10 18
+#define B11 19
+#define B12 20
+#define B13 21
+#define B14 22
+#define B15 23
+#define B16 24
+#define B17 25
+#define B18 26
+#define B19 27
+#define B20 28
+#define B21 29
+#define C3 30
+#define D2 31
+#define E1 32
+#define E2 33
+#define E3 34
+#define E4 35
+#define E5 36
+#define E6 37
+#define E7 38
+#define E8 39
+#define E9 40
+#define E10 41
+#define E11 42
+#define E12 43
+#define E13 44
+#define F2 45
+#define G1 46
+#define G2 47
+#define H1 48
+#define H2 49
+#define H3 50
+#define H4 51
+#define H5 52
+#define I1 53
+#define I2 54
+#define J1 55
+#define J2 56
+#define J3 57
+#define DUR 58 /*duration component*/
+#define F0 59 /*F0 component*/
+#define ITM 60 /*Item Offset into sSyllItems item list*/
+#define itm 61 /*second byte of the Item Offset */
+#define FID 62 /*Phoneme offset in the sPhIds phoneme list*/
+#define fid 63 /*second byte of the Phoneme offset */
+#define Min 64 /*offset to min syllable duration (uint 16,pauses)*/
+#define Max 66 /*offset to max syllable duration (uint 16,pauses)*/
+/* -------------------------------------------------------------------
+ PAM feature vector indices position changes,
+ ------------------------------------------------------------------- */
+#define T_B1 8
+#define T_B2 9
+#define T_B3 10
+#define T_B4 11
+#define T_B5 12
+#define T_B6 13
+#define T_B7 14
+#define T_B8 15
+#define T_B9 16
+#define T_B10 17
+#define T_B11 18
+#define T_B12 19
+#define T_B13 20
+#define T_B14 21
+#define T_B15 22
+#define T_B16 23
+#define T_B17 24
+#define T_B18 25
+#define T_B19 26
+#define T_B20 27
+#define T_B21 28
+#define T_E1 29
+#define T_E2 30
+#define T_E3 31
+#define T_E4 32
+#define T_E5 33
+#define T_E6 34
+#define T_E7 35
+#define T_E8 36
+#define T_E9 37
+#define T_E10 38
+#define T_E11 39
+#define T_E12 40
+#define T_E13 41
+#define T_A3 42
+#define T_C3 43
+#define T_D2 44
+#define T_F2 45
+#define T_G1 46
+#define T_I1 47
+#define T_G2 48
+#define T_I2 49
+#define T_H1 50
+#define T_H2 51
+#define T_H3 52
+#define T_H4 53
+#define T_H5 54
+
+/*------------------------------------------------------------------
+ Service routines :
+ ------------------------------------------------------------------*/
+static pico_status_t pam_initialize(register picodata_ProcessingUnit this);
+static pico_status_t pam_terminate(register picodata_ProcessingUnit this);
+static pico_status_t pam_allocate(picoos_MemoryManager mm, pam_subobj_t *pam);
+static void pam_deallocate(picoos_MemoryManager mm, pam_subobj_t *pam);
+static pico_status_t pam_subobj_deallocate(register picodata_ProcessingUnit this,
+ picoos_MemoryManager mm);
+/*------------------------------------------------------------------
+ Processing routines :
+ ------------------------------------------------------------------*/
+static picodata_step_result_t pam_step(register picodata_ProcessingUnit this,
+ picoos_int16 mode, picoos_uint16 * numBytesOutput);
+static pico_status_t pam_deal_with(const picoos_uint8 *item);
+/*Utility*/
+static picoos_uint8 pam_get_vowel_name(register picodata_ProcessingUnit this,
+ picoos_uint8 *item, picoos_uint8 *pos);
+static picoos_uint8 pam_get_pause_id(register picodata_ProcessingUnit this);
+
+static picoos_uint8 pam_map_sentence_type(picoos_uint8 iteminfo1,
+ picoos_uint8 iteminfo2);
+static picoos_uint8 pam_map_phrase_type(picoos_uint8 iteminfo1,
+ picoos_uint8 iteminfo2);
+
+/*Adapter*/
+static pico_status_t pam_reset_processors(register picodata_ProcessingUnit this);
+static pico_status_t pam_reset_processors_back(
+ register picodata_ProcessingUnit this);
+static pico_status_t pam_create_syllable(register picodata_ProcessingUnit this,
+ picoos_uint8 syllType, picoos_uint8 *sContent, picoos_uint8 sentType,
+ picoos_uint8 phType, picoos_uint8 uBoundType, picoos_uint16 uMin,
+ picoos_uint16 uMax);
+static pico_status_t pam_process_event_feature(
+ register picodata_ProcessingUnit this, picoos_uint8 nFeat,
+ picoos_uint8 event_type, picoos_uint8 direction);
+static pico_status_t pam_process_event(register picodata_ProcessingUnit this,
+ picoos_uint8 event_type, picoos_uint8 direction);
+static pico_status_t pam_adapter_forward_step(
+ register picodata_ProcessingUnit this, picoos_uint8 *itemBase);
+static pico_status_t pam_adapter_backward_step(
+ register picodata_ProcessingUnit this);
+static pico_status_t pam_do_pause(register picodata_ProcessingUnit this);
+static pico_status_t pam_adapter_do_pauses(register picodata_ProcessingUnit this);
+/*-------------- tree traversal ---------------------------------------*/
+static pico_status_t pam_expand_vector(register picodata_ProcessingUnit this);
+static picoos_uint8 pam_do_tree(register picodata_ProcessingUnit this,
+ const picokdt_DtPAM dtpam, const picoos_uint8 *invec,
+ const picoos_uint8 inveclen, picokdt_classify_result_t *dtres);
+static pico_status_t pam_get_f0(register picodata_ProcessingUnit this,
+ picoos_uint16 *lf0Index, picoos_uint8 nState, picoos_single *phonF0);
+static pico_status_t pam_get_duration(register picodata_ProcessingUnit this,
+ picoos_uint16 durIndex, picoos_uint16 *phonDur,
+ picoos_uint8 *numFramesState);
+static pico_status_t pam_update_vector(register picodata_ProcessingUnit this);
+/*-------------- FINAL ITEM FEEDING -----------------------------------------*/
+static pico_status_t pam_put_item(register picodata_ProcessingUnit this,
+ picoos_uint8 *outBuff, picoos_uint16 outWritePos,
+ picoos_uint8 *bytesWr);
+
+static pico_status_t pam_put_term(picoos_uint8 *outBuff,
+ picoos_uint16 outWritePos, picoos_uint8 *bytesWr);
+
+static pico_status_t is_pam_command(const picoos_uint8 *qItem);
+
+static void get_default_boundary_limit(picoos_uint8 uBoundType,
+ picoos_uint16 *uMinDur, picoos_uint16 *uMaxDur);
+
+/* -------------------------------------------------------------
+ * Pico System functions
+ * -------------------------------------------------------------
+ */
+
+/**
+ * allocation for PAM memory on pam PU
+ * @param mm : handle to engine memory manager
+ * @param pam : handle to a pam struct
+ * @return PICO_OK : allocation successful
+ * @return PICO_ERR_OTHER : allocation errors
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_allocate(picoos_MemoryManager mm, pam_subobj_t *pam)
+{
+ picoos_uint8 *data;
+ picoos_int16 *dataI;
+
+ pam->sSyllFeats = NULL;
+ pam->sPhIds = NULL;
+ pam->sPhFeats = NULL;
+ pam->sSyllItems = NULL;
+ pam->sSyllItemOffs = NULL;
+
+ /*-----------------------------------------------------------------
+ * PAM Local buffers ALLOCATION
+ ------------------------------------------------------------------*/
+ /*PAM Local buffers*/
+ data = (picopal_uint8 *) picoos_allocate(mm, sizeof(sFtVect)
+ * PICOPAM_MAX_SYLL_PER_SENT);
+ if (data == NULL)
+ return PICO_ERR_OTHER;
+ pam->sSyllFeats = (sFtVect*) data;
+
+ data = (picopal_uint8 *) picoos_allocate(mm, sizeof(picopal_uint8)
+ * PICOPAM_MAX_PH_PER_SENT);
+ if (data == NULL) {
+ pam_deallocate(mm, pam);
+ return PICO_ERR_OTHER;
+ }
+ pam->sPhIds = (picopal_uint8*) data;
+
+ data = (picopal_uint8 *) picoos_allocate(mm, sizeof(picopal_uint8)
+ * PICOPAM_VECT_SIZE);
+ if (data == NULL) {
+ pam_deallocate(mm, pam);
+ return PICO_ERR_OTHER;
+ }
+ pam->sPhFeats = (picopal_uint8*) data;
+
+ data = (picopal_uint8 *) picoos_allocate(mm, sizeof(picopal_uint8)
+ * PICOPAM_MAX_ITEM_SIZE_PER_SENT);
+ if (data == NULL) {
+ pam_deallocate(mm, pam);
+ return PICO_ERR_OTHER;
+ }
+ pam->sSyllItems = (picopal_uint8*) data;
+
+ dataI = (picoos_int16 *) picoos_allocate(mm, sizeof(picoos_int16)
+ * PICOPAM_MAX_ITEM_PER_SENT);
+ if (data == NULL) {
+ pam_deallocate(mm, pam);
+ return PICO_ERR_OTHER;
+ }
+ pam->sSyllItemOffs = (picoos_int16*) dataI;
+
+ return PICO_OK;
+}/*pam_allocate*/
+
+/**
+ * frees allocation for DSP memory on PAM PU
+ * @param mm : memory manager
+ * @param pam : pam PU internal sub-object
+ * @return void
+ * @remarks modified and inserted in sub obj removal PP 15.09.08
+ * @callgraph
+ * @callergraph
+ */
+static void pam_deallocate(picoos_MemoryManager mm, pam_subobj_t *pam)
+{
+ /*-----------------------------------------------------------------
+ * Memory de-allocations
+ * ------------------------------------------------------------------*/
+ if (pam->sSyllFeats != NULL)
+ picoos_deallocate(mm, (void *) &pam->sSyllFeats);
+ if (pam->sPhIds != NULL)
+ picoos_deallocate(mm, (void *) &pam->sPhIds);
+ if (pam->sPhFeats != NULL)
+ picoos_deallocate(mm, (void *) &pam->sPhFeats);
+ if (pam->sSyllItems != NULL)
+ picoos_deallocate(mm, (void *) &pam->sSyllItems);
+ if (pam->sSyllItemOffs != NULL)
+ picoos_deallocate(mm, (void *) &pam->sSyllItemOffs);
+
+}/*pam_deallocate*/
+
+/**
+ * initialization of a pam PU
+ * @param this : handle to a PU struct
+ * @return PICO_OK : init OK
+ * @return PICO_ERR_OTHER : error on getting pkbs addresses
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_initialize(register picodata_ProcessingUnit this)
+{
+ pico_status_t nI, nJ;
+ pam_subobj_t *pam;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ pam->inBufSize = PICOPAM_IN_BUFF_SIZE;
+ pam->outBufSize = PICOPAM_OUT_PAM_SIZE;
+ pam->inReadPos = 0;
+ pam->inWritePos = 0;
+ pam->outReadPos = 0;
+ pam->outWritePos = 0;
+ pam->needMoreInput = 0;
+ pam->procState = 0;
+
+ /*-----------------------------------------------------------------
+ * MANAGE INTERNAL INITIALIZATION
+ ------------------------------------------------------------------*/
+ /*init the syllable structure*/
+ for (nI = 0; nI < PICOPAM_MAX_SYLL_PER_SENT; nI++)
+ for (nJ = 0; nJ < PICOPAM_VECT_SIZE; nJ++)
+ pam->sSyllFeats[nI].phoneV[nJ] = 0;
+
+ for (nI = 0; nI < PICOPAM_MAX_PH_PER_SENT; nI++)
+ pam->sPhIds[nI] = 0;
+
+ for (nI = 0; nI < PICOPAM_VECT_SIZE; nI++)
+ pam->sPhFeats[nI] = 0;
+
+ for (nI = 0; nI < PICOPAM_MAX_ITEM_SIZE_PER_SENT; nI++)
+ pam->sSyllItems[nI] = 0;
+
+ for (nI = 0; nI < PICOPAM_MAX_ITEM_PER_SENT; nI++)
+ pam->sSyllItemOffs[nI] = 0;
+
+ /*Other variables*/
+ pam_reset_processors(this);
+ pam->nLastAttachedItemId = pam->nCurrAttachedItem = 0;
+ pam->nAttachedItemsSize = 0;
+
+ /*pitch and duration modifiers*/
+ pam->pMod = 1.0f;
+ pam->dMod = 1.0f;
+ pam->dRest = 0.0f;
+
+
+ /* constant tables */
+ {
+ picoos_uint8 i, j;
+ picoos_uint16 tmp_weights[PICOPAM_PWIDX_SIZE][PICOPAM_MAX_STATES_PER_PHONE] = {
+ {10, 10, 10, 10, 1 }, /*SBEG*/
+ { 1, 4, 8, 4, 1 }, /*PHR1*/
+ { 1, 4, 8, 4, 1 }, /*PHR2*/
+ { 1, 10, 10, 10, 10 },/*SEND*/
+ { 1, 1, 1, 1, 1 } /*DEFAULT*/
+ };
+ for (i = 0; i < PICOPAM_PWIDX_SIZE; i++) {
+ for (j = 0; j < PICOPAM_PWIDX_SIZE; j++) {
+ pam->sil_weights[j][j] = tmp_weights[i][j];
+ }
+ }
+ }
+/*-----------------------------------------------------------------
+ * MANAGE LINGWARE INITIALIZATION IF NEEDED
+ ------------------------------------------------------------------*/
+ /* kb dtdur */
+ pam->dtdur = picokdt_getDtPAM(this->voice->kbArray[PICOKNOW_KBID_DT_DUR]);
+ if (pam->dtdur == NULL) {
+ picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING, NULL,
+ NULL);
+ return PICO_ERR_OTHER;
+ }PICODBG_DEBUG(("got dtdur"));
+
+ /* kb dtlfz* */
+ pam->dtlfz[0] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_LFZ1]);
+ pam->dtlfz[1] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_LFZ2]);
+ pam->dtlfz[2] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_LFZ3]);
+ pam->dtlfz[3] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_LFZ4]);
+ pam->dtlfz[4] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_LFZ5]);
+ for (nI = 0; nI < PICOPAM_DT_NRLFZ; nI++) {
+ if (pam->dtlfz[nI] == NULL) {
+ picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
+ NULL, NULL);
+ return PICO_ERR_OTHER;
+ }PICODBG_DEBUG(("got dtlfz%d", nI+1));
+ }
+
+ /* kb dtmgc* */
+ pam->dtmgc[0] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_MGC1]);
+ pam->dtmgc[1] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_MGC2]);
+ pam->dtmgc[2] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_MGC3]);
+ pam->dtmgc[3] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_MGC4]);
+ pam->dtmgc[4] = picokdt_getDtPAM(
+ this->voice->kbArray[PICOKNOW_KBID_DT_MGC5]);
+ for (nI = 0; nI < PICOPAM_DT_NRMGC; nI++) {
+ if (pam->dtmgc[nI] == NULL) {
+ picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
+ NULL, NULL);
+ return PICO_ERR_OTHER;
+ }PICODBG_DEBUG(("got dtmgc%d", nI+1));
+ }
+
+ /* kb pdfdur* */
+ pam->pdfdur = picokpdf_getPdfDUR(
+ this->voice->kbArray[PICOKNOW_KBID_PDF_DUR]);
+ if (pam->pdfdur == NULL) {
+ picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING, NULL,
+ NULL);
+ return PICO_ERR_OTHER;
+ }PICODBG_DEBUG(("got pdfdur"));
+
+ /* kb pdflfz* */
+ pam->pdflfz = picokpdf_getPdfMUL(
+ this->voice->kbArray[PICOKNOW_KBID_PDF_LFZ]);
+ if (pam->pdflfz == NULL) {
+ picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING, NULL,
+ NULL);
+ return PICO_ERR_OTHER;
+ }PICODBG_DEBUG(("got pdflfz"));
+
+ /* kb tabphones */
+ pam->tabphones = picoktab_getPhones(
+ this->voice->kbArray[PICOKNOW_KBID_TAB_PHONES]);
+ if (pam->tabphones == NULL) {
+ picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING, NULL,
+ NULL);
+ return PICO_ERR_OTHER;
+ }PICODBG_DEBUG(("got tabphones"));
+
+ return PICO_OK;
+}/*pam_initialize*/
+
+/**
+ * termination of a pam PU
+ * @param this : handle to a pam PU struct
+ * @return PICO_OK
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_terminate(register picodata_ProcessingUnit this)
+{
+
+ pam_subobj_t *pam;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ return PICO_OK;
+}/*pam_terminate*/
+
+/**
+ * deallocaton of a pam PU
+ * @param this : handle to a pam PU struct
+ * @param mm : engine memory manager
+ * @return PICO_OK
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_subobj_deallocate(register picodata_ProcessingUnit this,
+ picoos_MemoryManager mm)
+{
+
+ pam_subobj_t* pam;
+
+ if (NULL != this) {
+ pam = (pam_subobj_t *) this->subObj;
+ mm = mm; /* avoid warning "var not used in this function"*/
+ /*-----------------------------------------------------------------
+ * Memory de-allocations
+ * ------------------------------------------------------------------*/
+ if (pam->sSyllFeats != NULL) {
+ picoos_deallocate(this->common->mm, (void *) &pam->sSyllFeats);
+ }
+ if (pam->sPhIds != NULL) {
+ picoos_deallocate(this->common->mm, (void *) &pam->sPhIds);
+ }
+ if (pam->sPhFeats != NULL) {
+ picoos_deallocate(this->common->mm, (void *) &pam->sPhFeats);
+ }
+ if (pam->sSyllItems != NULL) {
+ picoos_deallocate(this->common->mm, (void *) &pam->sSyllItems);
+ }
+ if (pam->sSyllItemOffs != NULL) {
+ picoos_deallocate(this->common->mm, (void *) &pam->sSyllItemOffs);
+ }
+ picoos_deallocate(this->common->mm, (void *) &this->subObj);
+ }
+
+ return PICO_OK;
+}/*pam_subobj_deallocate*/
+
+/**
+ * creates a new pam processing unit
+ * @param mm : engine memory manager
+ * @param common : engine common object pointer
+ * @param cbIn : pointer to input buffer
+ * @param cbOut : pointer to output buffer
+ * @param voice : pointer to voice structure
+ * @return this : pam PU handle if success
+ * @return NULL : if error
+ * @callgraph
+ * @callergraph
+ */
+picodata_ProcessingUnit picopam_newPamUnit(picoos_MemoryManager mm,
+ picoos_Common common, picodata_CharBuffer cbIn,
+ picodata_CharBuffer cbOut, picorsrc_Voice voice)
+{
+
+ register pam_subobj_t * pam;
+
+ picodata_ProcessingUnit this = picodata_newProcessingUnit(mm, common, cbIn,
+ cbOut, voice);
+ if (this == NULL) {
+ return NULL;
+ }
+ this->initialize = pam_initialize;
+
+ PICODBG_DEBUG(("picotok_newPamUnit -- set this->step to pam_step"));
+
+ this->step = pam_step;
+ this->terminate = pam_terminate;
+ this->subDeallocate = pam_subobj_deallocate;
+ this->subObj = picoos_allocate(mm, sizeof(pam_subobj_t));
+ if (this->subObj == NULL) {
+ PICODBG_ERROR(("Error in Pam Object allocation"));
+ picoos_deallocate(mm, (void*) &this);
+ return NULL;
+ };
+
+ /*-----------------------------------------------------------------
+ * Allocate internal memory for PAM (only at PU creation time)
+ * ------------------------------------------------------------------*/
+ pam = (pam_subobj_t *) this->subObj;
+ if (PICO_OK != pam_allocate(mm, pam)) {
+ PICODBG_ERROR(("Error in Pam buffers Allocation"));
+ picoos_deallocate(mm, (void *) &this->subObj);
+ picoos_deallocate(mm, (void *) &this);
+ return NULL;
+ }
+
+ /*-----------------------------------------------------------------
+ * Initialize memory for PAM (this may be re-used elsewhere, e.g.Reset)
+ * ------------------------------------------------------------------*/
+ if (PICO_OK != pam_initialize(this)) {
+ PICODBG_ERROR(("problem initializing the pam sub-object"));
+ }
+ return this;
+}/*picopam_newPamUnit*/
+
+/*-------------------------------------------------------------------------------
+ PROCESSING AND INTERNAL FUNCTIONS
+ --------------------------------------------------------------------------------*/
+
+/**
+ * initializes default duration limits for boundary items
+ * @param uBoundType : type of input boundary type
+ * @param *uMinDur, *uMaxDur : addresses of values to initialize
+ * @return void
+ * @remarks so far initializes to 0 both values; this will leave the values given by tree prediction
+ * @callgraph
+ * @callergraph
+ */
+static void get_default_boundary_limit(picoos_uint8 uBoundType,
+ picoos_uint16 *uMinDur, picoos_uint16 *uMaxDur)
+{
+ switch (uBoundType) {
+ case PICODATA_ITEMINFO1_BOUND_SBEG:
+ *uMinDur = 0;
+ *uMaxDur = 20;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_SEND:
+ *uMinDur = 550;
+ *uMaxDur = 650;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_TERM:
+ *uMinDur = 0;
+ *uMaxDur = 0;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_PHR0:
+ *uMinDur = 0;
+ *uMaxDur = 0;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_PHR1:
+ *uMinDur = 275;
+ *uMaxDur = 325;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_PHR2:
+ *uMinDur = 4;
+ *uMaxDur = 60;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_PHR3:
+ *uMinDur = 0;
+ *uMaxDur = 0;
+ break;
+ default:
+ break;
+ }
+
+}/*get_default_boundary_limit*/
+
+/**
+ * checks if "neededSize" is available on "nCurrPhoneme"
+ * @param pam : pam subobj
+ * @param neededSize : the requested size
+ * @return PICO_OK : size is available
+ * @return !=PICO_OK : size not available
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t check_phones_size(pam_subobj_t *pam,
+ picoos_int16 neededSize)
+{
+ if ((pam->nCurrPhoneme + neededSize) > PICOPAM_MAX_PH_PER_SENT - 1) {
+ return PICO_ERR_OTHER;
+ }
+ return PICO_OK;
+}/*check_phones_size*/
+
+/**
+ * checks if neededSize is available on "nCurrSyllable"
+ * @param pam : pam subobj
+ * @param neededSize : the requested size
+ * @return PICO_OK : size is available
+ * @return !=PICO_OK : size not available
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t check_syllables_size(pam_subobj_t *pam,
+ picoos_int16 neededSize)
+{
+ if ((pam->nCurrSyllable + neededSize) > PICOPAM_MAX_SYLL_PER_SENT - 1) {
+ return PICO_ERR_OTHER;
+ }
+ return PICO_OK;
+}/*check_syllables_size*/
+
+/**
+ * verifies that local storage has enough space to receive 1 item
+ * @param this : pointer to current PU struct
+ * @param item : pointer to current item head
+ * @return TRUE : resource limits would be reached during processing of input item
+ * @return FALSE : item could be processed normally
+ * @remarks item pointed to by *item should be already valid
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pamCheckResourceLimits(
+ register picodata_ProcessingUnit this, const picoos_uint8 *item)
+{
+ register pam_subobj_t * pam;
+ picodata_itemhead_t head;
+ pico_status_t sResult;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ sResult = TRUE; /*default : resource limits reached*/
+ head.type = item[0];
+ head.info1 = item[1];
+ head.info2 = item[2];
+ head.len = item[3];
+
+ switch (head.type) {
+ /*commands that generate syllables/phonemes*/
+ case PICODATA_ITEM_SYLLPHON:
+ if (pam->nCurrSyllable >= PICOPAM_MAX_SYLL_PER_SENT - 2) {
+ return sResult; /*no room for more syllables*/
+ }
+ if ((pam->nCurrPhoneme + head.len) >= PICOPAM_MAX_PH_PER_SENT - 2) {
+ return sResult; /*no room for more phoneme*/
+ }
+ break;
+ case PICODATA_ITEM_BOUND:
+ if ((head.info1 == PICODATA_ITEMINFO1_BOUND_SBEG) || (head.info1
+ == PICODATA_ITEMINFO1_BOUND_SEND) || (head.info1
+ == PICODATA_ITEMINFO1_BOUND_TERM) || (head.info1
+ == PICODATA_ITEMINFO1_BOUND_PHR1)
+#ifdef PAM_PHR2_WITH_PR1
+ || (head.info1 == PICODATA_ITEMINFO1_BOUND_PHR2)
+#endif
+ ) {
+
+ if (pam->nCurrSyllable >= PICOPAM_MAX_SYLL_PER_SENT - 2) {
+ return sResult; /*no room for more syllables*/
+ }
+ if ((pam->nCurrPhoneme + 1) >= PICOPAM_MAX_PH_PER_SENT - 2) {
+ return sResult; /*no room for more phoneme*/
+ }
+ }
+ break;
+
+ default:
+ /*all other commands has to be queued*/
+ if ((pam->nAttachedItemsSize + head.len)
+ >= PICOPAM_MAX_ITEM_SIZE_PER_SENT - 1) {
+ return sResult; /*no room for more items*/
+ }
+ break;
+ }
+ return FALSE; /*no resource limits apply to current item*/
+} /*pamCheckResourceLimits*/
+
+/**
+ * selects items to be sent to next PU immedately
+ * @param this : pointer to current PU struct
+ * @param item : pointer to current item head
+ * @return TRUE : item should be passed on next PU NOW
+ * @return FALSE : item should not be passed on next PU now but should be processed
+ * @remarks item pointed to by *item should be already valid
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_check_immediate(register picodata_ProcessingUnit this,
+ const picoos_uint8 *item)
+{
+ register pam_subobj_t * pam;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ if (pam->nCurrSyllable <= -1) {
+ if (item[0] == PICODATA_ITEM_SYLLPHON)
+ return FALSE;
+ if ((item[0] == PICODATA_ITEM_BOUND) && (item[1]
+ == PICODATA_ITEMINFO1_BOUND_SBEG))
+ return FALSE;
+ if (is_pam_command((picoos_uint8 *) item) == TRUE)
+ return FALSE;
+ return TRUE; /*no need to process data : send it*/
+ }
+ return FALSE; /*syllable struct not void : do standard processing*/
+
+} /*pam_check_immediate*/
+
+/**
+ * checks if the input item has to be queued in local storage for later resynch
+ * @param this : pointer to current PU struct
+ * @param item : pointer to current item head
+ * @return TRUE : item should be queued
+ * @return FALSE : item should not be queued
+ * @remarks item pointed to by *item should be already valid
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_hastobe_queued(register picodata_ProcessingUnit this,
+ const picoos_uint8 *item)
+{
+ register pam_subobj_t * pam;
+ picodata_itemhead_t head;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ head.type = item[0];
+ head.info1 = item[1];
+
+ switch (head.type) {
+ /*commands that generate syllables/phonemes*/
+ case PICODATA_ITEM_SYLLPHON:
+ return FALSE; /*no queue needed*/
+ break;
+ case PICODATA_ITEM_BOUND:
+ if ((head.info1 == PICODATA_ITEMINFO1_BOUND_PHR3)
+#ifdef PAM_PHR2_WITH_PR3
+ ||(head.info1==PICODATA_ITEMINFO1_BOUND_PHR2)
+#endif
+ || (head.info1 == PICODATA_ITEMINFO1_BOUND_PHR0)) {
+ return FALSE; /*no queue needed*/
+ }
+ break;
+
+ default:
+ /*all other items has to be queued*/
+ break;
+ }
+ return TRUE; /*item has to be queued*/
+} /*pam_hastobe_queued*/
+
+/**
+ * queue item in local storage for later resynch
+ * @param this : pointer to current PU struct
+ * @param item : pointer to current item head
+ * @return TRUE : item queued
+ * @return FALSE : item not queued because of errors
+ * @remarks item pointed to by *item should be already valid
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_queue(register picodata_ProcessingUnit this,
+ const picoos_uint8 *item)
+{
+ register pam_subobj_t * pam;
+ picodata_itemhead_t head;
+ picoos_uint8 nI;
+ pico_status_t sResult;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ sResult = TRUE; /*default : item queued*/
+ head.type = item[0];
+ head.info1 = item[1];
+ head.info2 = item[2];
+ head.len = item[3];
+
+ /*test condition on enough room to store current item in the "sSyllItems" area*/
+ if ((pam->nAttachedItemsSize + head.len + sizeof(picodata_itemhead_t))
+ >= PICOPAM_MAX_ITEM_SIZE_PER_SENT - 1) {
+ return FALSE; /*resource limit reached*/
+ }
+ /*store current offset*/
+ pam->sSyllItemOffs[pam->nLastAttachedItemId] = pam->nAttachedItemsSize;
+ /*store the item to the "sSyllItems" area*/
+ for (nI = 0; nI < (head.len + sizeof(picodata_itemhead_t)); nI++) {
+ pam->sSyllItems[pam->nAttachedItemsSize + nI] = item[nI];
+ }
+ /*increment the attached items area*/
+ pam->nAttachedItemsSize += nI;
+
+ /*increment id*/
+ pam->nLastAttachedItemId++;
+ /*set start(if not initialized) and end ids of queued items in sSyllFeats*/
+ if (pam->nCurrSyllable > -1) {
+ /*normal case : the item is attached to current syllable*/
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] == 0) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM]
+ = pam->nLastAttachedItemId;
+ }
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm]
+ = pam->nLastAttachedItemId;
+ } else {
+ /*special case : an item is requested to be queued even if no
+ syllables has been assigned to the sentence structure :
+ -->> use syll 0*/
+ if (pam->sSyllFeats[0].phoneV[ITM] == 0) {
+ pam->sSyllFeats[0].phoneV[ITM] = pam->nLastAttachedItemId;
+ }
+ pam->sSyllFeats[0].phoneV[itm] = pam->nLastAttachedItemId;
+ }
+ return TRUE; /*item queued successfully*/
+} /*pam_queue*/
+
+/**
+ * selects items to be dealth with by the PU processing
+ * @param item : pointer to current item head
+ * @return TRUE : item should be processed
+ * @return FALSE : item should not be processed (maybe it ontains commands or items for other PUs)
+ * @remarks item pointed to by *item should be already valid
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_deal_with(const picoos_uint8 *item)
+{
+ picodata_itemhead_t head;
+ pico_status_t sResult;
+ sResult = FALSE;
+ head.type = item[0];
+ head.info1 = item[1];
+ head.info2 = item[2];
+ head.len = item[3];
+ switch (head.type) {
+ case PICODATA_ITEM_SYLLPHON:
+ case PICODATA_ITEM_BOUND:
+ sResult = TRUE;
+ break;
+ default:
+ break;
+ }
+ return sResult;
+} /*pam_deal_with*/
+
+/**
+ * returns true if more items has to be produced for current syllable
+ * @param this : Pam object pointer
+ * @return TRUE : item is to be produced
+ * @return FALSE : item is not to be produced
+ * @remarks item pointed to by *item should be already valid
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 pamHasToProcess(register picodata_ProcessingUnit this)
+{
+ register pam_subobj_t * pam;
+ picoos_uint8 nCond1, nCond2, nCond3;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ /*conditions originating a "NOT to be processed" result */
+ nCond1 = pam->nCurrSyllable <= -1;
+ nCond2 = pam->nCurrSyllable >= pam->nTotalSyllables;
+ nCond3 = pam->nSyllPhoneme
+ >= pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3];
+
+ if ((nCond1) || (nCond2) || (nCond3))
+ return FALSE;
+
+ return TRUE;
+} /*pamHasToProcess*/
+
+/**
+ * modifies the process flags in order to point to next valid syllable phone or item to be produced
+ * @param this : Pam object pointer
+ * @return TRUE : item has to be produced
+ * @return FALSE : item has not to be produced
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pamUpdateProcess(register picodata_ProcessingUnit this)
+{
+ register pam_subobj_t * pam;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ if (pam->nCurrSyllable == -1) {
+ /*this to be able to manage sudden PU cleanup after FLUSH CMD*/
+ return PICO_OK;
+ }
+ /*check number of phonemes for current syllable*/
+ if (pam->nSyllPhoneme < pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3] - 1) {
+ pam->nSyllPhoneme++;
+ return PICO_OK;
+ }
+ if (pam->nSyllPhoneme == pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3] - 1) {
+ /*this helps in identifyng the end of syllable condition in PamHasToProcess*/
+ pam->nSyllPhoneme++;
+ }
+ /*previous syllable phonemes are complete: test if any items are tied to this syllable*/
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] > 0) {
+ /*there are items tied to this syllable*/
+ if (pam->nCurrAttachedItem == 0) {
+ /*if it is the first item to be regenerated initialize it*/
+ pam->nCurrAttachedItem
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM];
+ return PICO_OK;
+ } else {
+ /*not the first item : check if more*/
+ if (pam->nCurrAttachedItem
+ < pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm]) {
+ /*more tied items to be regenerated*/
+ pam->nCurrAttachedItem++;
+ return PICO_OK;
+ }
+ }
+ }
+ /*previous syllable phonemes and items are complete: switch to next syllable*/
+ if (pam->nCurrSyllable < pam->nTotalSyllables - 1) {
+ pam->nCurrSyllable++;
+ pam->nSyllPhoneme = 0;
+ pam->nCurrAttachedItem = 0;
+ return PICO_OK;
+ }
+ /*no more phonemes or items to be produced*/
+ pam->nCurrSyllable++;
+ pam->nSyllPhoneme = 0;
+ return PICO_ERR_OTHER;
+
+} /*pamUpdateProcess*/
+
+/**
+ * returns true if more items has to be popped for current syllable
+ * @param this : Pam object pointer
+ * @return TRUE : item has to be popped
+ * @return FALSE : item has not to be popped
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 pamHasToPop(register picodata_ProcessingUnit this)
+{
+ register pam_subobj_t * pam;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ /*Preliminary condition : at least 1 syllable*/
+ if (pam->nCurrSyllable <= -1)
+ return FALSE;
+
+ /*Preliminary condition : not maximum number of syllables*/
+ if (pam->nCurrSyllable >= pam->nTotalSyllables)
+ return FALSE;
+
+ /*Preliminary condition : start and end offset in current item > 0 */
+ if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] <= 0)
+ || (pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm] <= 0))
+ return FALSE;
+
+ /*Final condition : current popped item less or eq to maximum*/
+ if (pam->nCurrAttachedItem
+ > pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm])
+ return FALSE;
+
+ return TRUE;
+} /*pamHasToPop*/
+
+/**
+ * returns the address of an item to be popped from the current syllable queue
+ * @param this : Pam object pointer
+ * @return pop_address : item address
+ * @return NULL : item not poppable
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 *pamPopItem(register picodata_ProcessingUnit this)
+{
+ register pam_subobj_t * pam;
+ picoos_uint8 nItem;
+ if (NULL == this || NULL == this->subObj) {
+ return NULL;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ /*Preliminary condition : at least 1 syllable*/
+ if (pam->nCurrSyllable <= -1)
+ return NULL;
+
+ /*Preliminary condition : not maximum number of syllables*/
+ if (pam->nCurrSyllable >= pam->nTotalSyllables)
+ return NULL;
+
+ /*Preliminary condition : start and end offset in current item > 0 */
+ if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] <= 0)
+ || (pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm] <= 0))
+ return NULL;
+
+ /*Final condition : current popped item less than maximum*/
+ if (pam->nCurrAttachedItem
+ > pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm])
+ return NULL;
+
+ nItem = pam->nCurrAttachedItem;
+ /*please note : nItem-1 should match with actions performed in function "pam_queue(..)" */
+ return &(pam->sSyllItems[pam->sSyllItemOffs[nItem - 1]]);
+
+} /*pamPopItem*/
+
+/**
+ * returns the address of an item popped from the syllable 0 queue
+ * @param this : Pam object pointer
+ * @return pop_address : item address
+ * @return NULL : item not poppable
+ * @remarks the item is popped only if it has been inserted in the queue before the first
+ * @remarks item assigned to the syllable 0 i.e.
+ * @remarks AttachedItem<=pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm]-1
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 *pamPopAttachedSy0(register picodata_ProcessingUnit this)
+{
+ register pam_subobj_t * pam;
+ picoos_uint8 nItem;
+ if (NULL == this || NULL == this->subObj) {
+ return NULL;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ /*should be syllable 0*/
+ if (pam->nCurrSyllable != 0)
+ return NULL;
+
+ /*start and end offset in current item > 0 */
+ if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] <= 0)
+ || (pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm] <= 0))
+ return NULL;
+
+ /*if current popped item is > 0 test end condition*/
+ if (pam->nCurrAttachedItem > 0) {
+ /*Other condition : current popped item less than maximum*/
+ if (pam->nCurrAttachedItem
+ > pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm] - 1)
+ return NULL;
+ }
+ nItem = pam->nCurrAttachedItem;
+ return &(pam->sSyllItems[pam->sSyllItemOffs[nItem]]);
+
+} /*pamPopAttachedSy0*/
+
+/**
+ * pdf access for duration
+ * @param this : Pam object pointer
+ * @param durIndex : index of duration in the pdf
+ * @param phonDur : pointer to base of array where to store the duration values
+ * @param numFramesState : pointer to base of array where to store the number of frames per state
+ * @return PICO_OK : pdf retrieved
+ * @return PICO_ERR_OTHER : pdf not retrieved
+ * @remarks Modifies phonDur (the requested duration value)
+ * @remarks Modifies numFramesState (the requested number of frames per state (vector))
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_get_duration(register picodata_ProcessingUnit this,
+ picoos_uint16 durIndex, picoos_uint16 *phonDur,
+ picoos_uint8 *numFramesState)
+{
+ pam_subobj_t *pam;
+ picokpdf_PdfDUR pdf;
+ picoos_uint8 *durItem;
+ picoos_uint16 nFrameSize, nI;
+ picoos_single fValue;
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pdf = pam->pdfdur;
+ /*make the index 0 based*/
+ if (durIndex > 0)
+ durIndex--;
+
+ /* check */
+ if (durIndex > pdf->numframes - 1) {
+ PICODBG_ERROR(("PAM durPdf access error, index overflow -> index: %d , numframes: %d", durIndex, pdf->numframes));
+ return PICO_ERR_OTHER;
+ }
+ /* base pointer */
+ durItem = &(pdf->content[durIndex * pdf->vecsize]);
+ if (durItem == NULL) {
+ PICODBG_ERROR(("PAM durPdf access error , frame pointer = NULL"));
+ return PICO_ERR_OTHER;
+ }
+ nFrameSize = pdf->sampperframe / 16;
+ *phonDur = ((pdf->phonquant[((*durItem) & 0xF0) >> 4]) * nFrameSize);
+ numFramesState[0] = pdf->statequant[((*durItem) & 0x0F)];
+ durItem++;
+ numFramesState[1] = pdf->statequant[((*durItem) & 0xF0) >> 4];
+ numFramesState[2] = pdf->statequant[((*durItem) & 0x0F)];
+ durItem++;
+ numFramesState[3] = pdf->statequant[((*durItem) & 0xF0) >> 4];
+ numFramesState[4] = pdf->statequant[((*durItem) & 0x0F)];
+
+ /*modification of the duration information based on the duration modifier*/
+ *phonDur = (picoos_uint16) (((picoos_single) * phonDur) * pam->dMod);
+ for (nI = 0; nI < 5; nI++) {
+ fValue = pam->dRest + (picoos_single) numFramesState[nI] * pam->dMod;
+ numFramesState[nI] = (picoos_uint8) (fValue);
+ pam->dRest = fValue - (picoos_single) numFramesState[nI];
+ }
+ return PICO_OK;
+}/*pam_get_duration*/
+
+/**
+ * pdf access for pitch
+ * @param this : Pam object pointer
+ * @param lf0Index : pointer to variable to receive index of pitch in the pdf
+ * @param nI : number of the phone's state
+ * @param phonF0 : pointer to variable to receive the pitch value
+ * @return PICO_OK : pdf retrieved
+ * @return PICO_ERR_OTHER : pdf not retrieved
+ * @remarks Modifies phonDur (the requested duration value)
+ * @remarks Modifies phonF0 (the requested pitch value (scalar))
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_get_f0(register picodata_ProcessingUnit this,
+ picoos_uint16 *lf0Index, picoos_uint8 nI, picoos_single *phonF0)
+{
+ pam_subobj_t *pam;
+ picoos_uint8 *lfItem, numstreams;
+ picoos_uint16 lf0IndexOffset, sTemp;
+ picoos_single lfum, lfivar, lfz;
+
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ lf0IndexOffset = lf0Index[nI];
+
+ /*make the index 0 based*/
+ if (lf0IndexOffset > 0)
+ lf0IndexOffset--;
+
+ lf0IndexOffset += pam->pdflfz->stateoffset[nI];
+ if (lf0IndexOffset > pam->pdflfz->numframes - 1) {
+ PICODBG_ERROR(("PAM flfzPdf access error, index overflow -> index: %d , numframes: %d", lf0Index, pam->pdflfz->numframes));
+ return PICO_ERR_OTHER;
+ }
+ /* base pointer */
+ lf0IndexOffset *= pam->pdflfz->vecsize;
+
+ lfItem = &(pam->pdflfz->content[lf0IndexOffset]);
+ sTemp = (picoos_uint16) (((lfItem[1] << 8)) | lfItem[0]);
+
+ lfum = (picoos_single) (sTemp << (pam->pdflfz->meanpowUm[0]));
+ numstreams = 3;
+ lfivar = (picoos_single) (((picoos_uint16) lfItem[numstreams * 2])
+ << pam->pdflfz->ivarpow[0]);
+ lfz = (picoos_single) lfum / (picoos_single) lfivar;
+ lfz = (picoos_single) exp((double) lfz);
+ phonF0[nI] = (picoos_single) lfz;
+
+ /*pitch modoification*/
+ phonF0[nI] *= pam->pMod;
+ return PICO_OK;
+}/*pam_get_f0*/
+
+/**
+ * elementary rounding function
+ * @param fIn : (real) input value
+ * @return the rounded value
+ * @callgraph
+ * @callergraph
+ */
+static picoos_single f_round(picoos_single fIn)
+{
+ picoos_int32 iVal;
+ picoos_single fVal;
+
+ iVal = (picoos_int32) fIn;
+ fVal = (picoos_single) iVal;
+
+ if (fIn > (picoos_single) 0.0f) {
+ if ((fIn - fVal) < (picoos_single) 0.5f)
+ return fVal;
+ else
+ return fVal + (picoos_single) 1.0f;
+ } else {
+ if ((fVal - fIn) < (picoos_single) 0.5f)
+ return fVal;
+ else
+ return fVal - (picoos_single) 1.0f;
+ }
+}/*f_round*/
+
+/**
+ * updates the input vector for PAM
+ * @param this : Pam object pointer
+ * @return PICO_OK : update successful
+ * @return PICO_ERR_OTHER : errors on retrieving the PU pointer
+ * @remarks Modifies pam->sPhFeats[]
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_update_vector(register picodata_ProcessingUnit this)
+{
+ pam_subobj_t *pam;
+ picoos_uint8 numstates, nI;
+ picoos_single fDur, f0avg, f0quant, minf0, maxf0, durquant1, durquant2,
+ mindur, maxdur1, maxdur2;
+
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ /*default init*/
+ pam->sPhFeats[DUR] = 0;
+ pam->sPhFeats[F0] = 0;
+ /*
+ Hard coded parameters for quantization
+ */
+ numstates = PICOPAM_NRSTPF;
+ f0quant = 30.0f;
+ minf0 = 90.0f;
+ maxf0 = 360.0f;
+
+ durquant1 = 20.0f;
+ durquant2 = 100.0f;
+ mindur = 40.0f;
+ maxdur1 = 160.0f;
+ maxdur2 = 600.0f;
+ f0avg = 0.0f;
+ for (nI = 0; nI < numstates; nI++)
+ f0avg += pam->phonF0[nI];
+ f0avg /= (picoos_single) numstates;
+
+ f0avg = f_round(f0avg / f0quant) * f0quant;
+ if (f0avg < minf0)
+ f0avg = minf0;
+ if (f0avg > maxf0)
+ f0avg = maxf0;
+
+ /*make initial silence of sentence shorter (see also pam_put_item)*/
+ if ((pam->nCurrSyllable == 0) && (pam->nSyllPhoneme == 0)) {
+ pam->phonDur = 2 * 4;
+ }
+
+ fDur = (picoos_single) pam->phonDur;
+ fDur = f_round(fDur / durquant1) * durquant1;
+ if (fDur < mindur)
+ fDur = mindur;
+ if (fDur > maxdur1) {
+ fDur = f_round(fDur / durquant2) * durquant2;
+ if (fDur > maxdur2)
+ fDur = maxdur2;
+ }
+ pam->sPhFeats[DUR] = (picoos_uint8) (fDur / (picoos_single) 10.0f);
+ pam->sPhFeats[F0] = (picoos_uint8) (f0avg / (picoos_single) 10.0f);
+
+ return PICO_OK;
+}/*pam_update_vector*/
+
+/**
+ * compress a single feature in the range 0..9
+ * @param inVal : the value to be compressed
+ * @return compVal : the compressed value
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 pamCompressComponent(picoos_uint8 inVal)
+{
+ if (inVal <= 5)
+ return inVal;
+ if ((5 < inVal) && (inVal <= 10))
+ return 6;
+ if ((10 < inVal) && (inVal <= 20))
+ return 7;
+ if ((20 < inVal) && (inVal <= 30))
+ return 8;
+ return 9;
+}/*pamCompressComponent*/
+
+/**
+ * prepares the input vector for tree feeding
+ * @param this : Pam object pointer
+ * @return PICO_OK : vector expanded
+ * @return PICO_ERR_OTHER : errors on expansion or retrieving the PU pointer
+ * @remarks Modifies pam->sPhFeats[]
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_expand_vector(register picodata_ProcessingUnit this)
+{
+ pam_subobj_t *pam;
+ picoos_uint8 *inVect, *phonVect, *outVect, nI;
+ picoos_int16 nOffs, nOffs1, nLen;
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ inVect = &(pam->sSyllFeats[pam->nCurrSyllable].phoneV[0]);
+ phonVect = &(pam->sPhIds[0]);
+ outVect = &(pam->sPhFeats[0]);
+ /*just copy back*/
+ for (nI = 0; nI < PICOPAM_INVEC_SIZE; nI++)
+ outVect[nI] = inVect[nI];
+ /*now fill missing fields*/
+ picoos_mem_copy((void*) &(inVect[FID]), &nOffs, sizeof(nOffs));
+ /*offset to first phone of current syllable*/
+ nOffs = nOffs + pam->nSyllPhoneme; /*offset to current phone of current syllable*/
+ nLen = inVect[B3]; /*len of current syllable*/
+ if (pam->nSyllPhoneme >= nLen) {
+ /*error on addressing current phone*/
+ return PICO_ERR_OTHER;
+ }
+ /*previous of the previous phone*/
+ nOffs1 = nOffs - 2;
+ if (nOffs1 >= 0)
+ outVect[P1] = phonVect[nOffs1];
+ else
+ outVect[P1] = PICOPAM_PH_DONT_CARE_VAL;
+ /*previous phone*/
+ nOffs1 = nOffs - 1;
+ if (nOffs1 >= 0)
+ outVect[P2] = phonVect[nOffs1];
+ else
+ outVect[P2] = PICOPAM_PH_DONT_CARE_VAL;
+ /*^current phone*/
+ outVect[P3] = phonVect[nOffs];
+
+ /*next phone*/
+ nOffs1 = nOffs + 1;
+ if (nOffs1 < pam->nTotalPhonemes)
+ outVect[P4] = phonVect[nOffs1];
+ else
+ outVect[P4] = PICOPAM_PH_DONT_CARE_VAL;
+ /*next of the next phone*/
+ nOffs1 = nOffs + 2;
+ if (nOffs1 < pam->nTotalPhonemes)
+ outVect[P5] = phonVect[nOffs1];
+ else
+ outVect[P5] = PICOPAM_PH_DONT_CARE_VAL;
+ /*pos of curr phone with respect to left syllable boundary*/
+ outVect[P6] = pam->nSyllPhoneme + 1;
+ /*pos of curr phone with respect to right syllable boundary*/
+ outVect[P7] = nLen - pam->nSyllPhoneme;
+ /*is current phone in consonant syllable boundary? (1:yes)*/
+ if (pam->nSyllPhoneme < inVect[P8])
+ outVect[P8] = 1;
+ else
+ outVect[P8] = 0;
+ return PICO_OK;
+}/*pam_expand_vector*/
+
+/**
+ * compresses the input vector for PAM
+ * @param this : Pam object pointer
+ * @return PICO_OK : compression successful
+ * @return PICO_ERR_OTHER : errors on retrieving the PU pointer
+ * @remarks Modifies pam->sPhFeats[]
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pamCompressVector(register picodata_ProcessingUnit this)
+{
+ pam_subobj_t *pam;
+ picoos_uint8 *outVect, nI;
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ outVect = &(pam->sPhFeats[0]);
+ for (nI = 0; nI < PICOPAM_INVEC_SIZE; nI++) {
+ switch (nI) {
+ case P1:
+ case P2:
+ case P3:
+ case P4:
+ case P5:
+ case B1:
+ case B2:
+ case B16:
+ case E1:
+ case H5:
+ /*don't do any compression*/
+ break;
+ default:
+ /*do compression*/
+ if (outVect[nI] != PICOPAM_DONT_CARE_VALUE)
+ outVect[nI] = pamCompressComponent(outVect[nI]);
+ else
+ outVect[nI] = PICOPAM_DONT_CARE_VAL;
+ break;
+ }
+ }
+ return PICO_OK;
+}/*pamCompressVector*/
+
+/**
+ * reorganizes the input vector for PAM
+ * @param this : Pam object pointer
+ * @return PICO_OK : reorganization successful
+ * @return PICO_ERR_OTHER : errors on retrieving the PU pointer
+ * @remarks Modifies pam->sPhFeats[]
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pamReorgVector(register picodata_ProcessingUnit this)
+{
+ pam_subobj_t *pam;
+ picoos_uint8 *outVect, inVect[60], nI;
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ outVect = &(pam->sPhFeats[0]);
+ for (nI = 0; nI < PICOPAM_INVEC_SIZE; nI++) inVect[nI] = outVect[nI];
+ /*reorganize*/
+ for (nI = T_B1; nI <= T_H5; nI++) {
+ switch (nI) {
+ case T_B1:
+ outVect[T_B1] = inVect[B1];
+ break;
+ case T_B2:
+ outVect[T_B2] = inVect[B2];
+ break;
+ case T_B3:
+ outVect[T_B3] = inVect[B3];
+ break;
+ case T_B4:
+ outVect[T_B4] = inVect[B4];
+ break;
+ case T_B5:
+ outVect[T_B5] = inVect[B5];
+ break;
+ case T_B6:
+ outVect[T_B6] = inVect[B6];
+ break;
+ case T_B7:
+ outVect[T_B7] = inVect[B7];
+ break;
+ case T_B8:
+ outVect[T_B8] = inVect[B8];
+ break;
+ case T_B9:
+ outVect[T_B9] = inVect[B9];
+ break;
+ case T_B10:
+ outVect[T_B10] = inVect[B10];
+ break;
+ case T_B11:
+ outVect[T_B11] = inVect[B11];
+ break;
+ case T_B12:
+ outVect[T_B12] = inVect[B12];
+ break;
+ case T_B13:
+ outVect[T_B13] = inVect[B13];
+ break;
+ case T_B14:
+ outVect[T_B14] = inVect[B14];
+ break;
+ case T_B15:
+ outVect[T_B15] = inVect[B15];
+ break;
+ case T_B16:
+ outVect[T_B16] = inVect[B16];
+ break;
+ case T_B17:
+ outVect[T_B17] = inVect[B17];
+ break;
+ case T_B18:
+ outVect[T_B18] = inVect[B18];
+ break;
+ case T_B19:
+ outVect[T_B19] = inVect[B19];
+ break;
+ case T_B20:
+ outVect[T_B20] = inVect[B20];
+ break;
+ case T_B21:
+ outVect[T_B21] = inVect[B21];
+ break;
+
+ case T_E1:
+ outVect[T_E1] = inVect[E1];
+ break;
+ case T_E2:
+ outVect[T_E2] = inVect[E2];
+ break;
+ case T_E3:
+ outVect[T_E3] = inVect[E3];
+ break;
+ case T_E4:
+ outVect[T_E4] = inVect[E4];
+ break;
+ case T_E5:
+ outVect[T_E5] = inVect[E5];
+ break;
+ case T_E6:
+ outVect[T_E6] = inVect[E6];
+ break;
+ case T_E7:
+ outVect[T_E7] = inVect[E7];
+ break;
+ case T_E8:
+ outVect[T_E8] = inVect[E8];
+ break;
+ case T_E9:
+ outVect[T_E9] = inVect[E9];
+ break;
+ case T_E10:
+ outVect[T_E10] = inVect[E10];
+ break;
+ case T_E11:
+ outVect[T_E11] = inVect[E11];
+ break;
+ case T_E12:
+ outVect[T_E12] = inVect[E12];
+ break;
+ case T_E13:
+ outVect[T_E13] = inVect[E13];
+ break;
+
+ case T_A3:
+ outVect[T_A3] = inVect[A3];
+ break;
+ case T_C3:
+ outVect[T_C3] = inVect[C3];
+ break;
+ case T_D2:
+ outVect[T_D2] = inVect[D2];
+ break;
+ case T_F2:
+ outVect[T_F2] = inVect[F2];
+ break;
+
+ case T_G1:
+ outVect[T_G1] = inVect[G1];
+ break;
+ case T_I1:
+ outVect[T_I1] = inVect[I1];
+ break;
+
+ case T_G2:
+ outVect[T_G2] = inVect[G2];
+ break;
+ case T_I2:
+ outVect[T_I2] = inVect[I2];
+ break;
+
+ case T_H1:
+ outVect[T_H1] = inVect[H1];
+ break;
+ case T_H2:
+ outVect[T_H2] = inVect[H2];
+ break;
+ case T_H3:
+ outVect[T_H3] = inVect[H3];
+ break;
+ case T_H4:
+ outVect[T_H4] = inVect[H4];
+ break;
+ case T_H5:
+ outVect[T_H5] = inVect[H5];
+ break;
+ }
+ }
+ return PICO_OK;
+}/*pamReorgVector*/
+
+/**
+ * puts a PAM item into PU output buffer
+ * @param this : Pam object pointer
+ * @param outBuff : output buffer base pointer
+ * @param outWritePos : offset in output buffer
+ * @param *bytesWr : actual bytes written
+ * @return PICO_OK : put successful
+ * @return PICO_ERR_OTHER : errors on retrieving the PU pointer
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_put_item(register picodata_ProcessingUnit this,
+ picoos_uint8 *outBuff, picoos_uint16 outWritePos, picoos_uint8 *bytesWr)
+{
+ pam_subobj_t *pam;
+ picoos_uint8 *sDest, nI, nType, nIdx, fde;
+ picoos_uint32 pos, pos32;
+ picoos_int16 ft, dt;
+ picoos_uint16 uMinDur, uMaxDur;
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ sDest = &(outBuff[outWritePos]);
+ sDest[0] = PICODATA_ITEM_PHONE; /*Item type*/
+ sDest[1] = pam->sPhFeats[P3]; /*phonetic id*/
+ sDest[2] = PICOPAM_NRSTPF; /*number of states per phone*/
+ sDest[3] = sizeof(picoos_uint16) * PICOPAM_NRSTPF * 3; /*size of the item*/
+ pos = 4;
+ /*make initial silence of sentence shorter (see also UpdateVector)*/
+ if ((pam->nCurrSyllable == 0) && (pam->nSyllPhoneme == 0)) {
+ for (nI = 0; nI < PICOPAM_NRSTPF - 1; nI++)
+ pam->numFramesState[nI] = 0;
+ pam->numFramesState[nI] = 2;
+ } else {
+ /*manage silence syllables with prescribed durations*/
+ pos32 = Min;
+ picoos_read_mem_pi_uint16(pam->sSyllFeats[pam->nCurrSyllable].phoneV,
+ &pos32, &uMinDur);
+ pos32 = Max;
+ picoos_read_mem_pi_uint16(pam->sSyllFeats[pam->nCurrSyllable].phoneV,
+ &pos32, &uMaxDur);
+
+ if (uMaxDur > 0) {
+ /* Select weights*/
+ nType = pam->sSyllFeats[pam->nCurrSyllable].phoneV[bnd];
+ switch (nType) {
+ case PICODATA_ITEMINFO1_BOUND_SBEG:
+ nIdx = PICOPAM_PWIDX_SBEG;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_PHR1:
+ nIdx = PICOPAM_PWIDX_PHR1;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_PHR2:
+ nIdx = PICOPAM_PWIDX_PHR2;
+ break;
+ case PICODATA_ITEMINFO1_BOUND_SEND:
+ case PICODATA_ITEMINFO1_BOUND_TERM:
+ nIdx = PICOPAM_PWIDX_SEND;
+ break;
+ default:
+ nIdx = PICOPAM_PWIDX_DEFA;
+ break;
+ }
+ fde = 2;
+ ft = 0;
+ dt = 0;
+ picodata_transformDurations(
+ fde, /* 2's exponent of frame duration in ms, e.g. 2 for 4ms, 3 for 8ms */
+ PICOPAM_NRSTPF, /* number of states per phone */
+ &(pam->numFramesState[0]), /* estimated durations */
+ pam->sil_weights[nIdx], /* integer weights */
+ uMinDur, /* minimum target duration in ms */
+ uMaxDur, /* maximum target duration in ms */
+ ft, /* factor to be multiplied to get the target */
+ &dt /* in/out, rest in ms */
+ );
+ }
+ }
+ /*put data*/
+ for (nI = 0; nI < PICOPAM_NRSTPF; nI++) {
+ picoos_write_mem_pi_uint16(sDest, &pos,
+ (picoos_uint16) pam->numFramesState[nI]);
+ picoos_write_mem_pi_uint16(sDest, &pos,
+ (picoos_uint16) pam->lf0Index[nI]);
+ picoos_write_mem_pi_uint16(sDest, &pos,
+ (picoos_uint16) pam->mgcIndex[nI]);
+ }
+ *bytesWr = sizeof(picodata_itemhead_t) + sizeof(picoos_uint16)
+ * PICOPAM_NRSTPF * 3;
+ return PICO_OK;
+}/*pam_put_item*/
+
+/**
+ * puts a non PAM (queued) item into PU output buffer
+ * @param qItem : pointer to item to put
+ * @param outBuff : output buffer base pointer
+ * @param outWritePos : offset in output buffer
+ * @param *bytesWr : actual bytes written
+ * @return PICO_OK : put successful
+ * @return PICO_ERR_OTHER : errors on retrieving the PU pointer
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_put_qItem(picoos_uint8 *qItem, picoos_uint8 *outBuff,
+ picoos_uint16 outWritePos, picoos_uint8 *bytesWr)
+{
+ picoos_uint8 *sDest, nI;
+ sDest = &(outBuff[outWritePos]);
+ *bytesWr = sizeof(picodata_itemhead_t);
+ for (nI = 0; nI < (sizeof(picodata_itemhead_t) + qItem[3]); nI++) {
+ sDest[nI] = qItem[nI];
+ }
+ *bytesWr = nI;
+ return PICO_OK;
+}/*pam_put_qItem*/
+
+/**
+ * tells if an item is a PAM command (except play)
+ * @param qItem : input item to test
+ * @return TRUE : qItem is a PAM command (except play)
+ * @return FALSE : qItem not a PAM command
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t is_pam_command(const picoos_uint8 * qItem)
+{
+ switch (qItem[0]) {
+
+ case PICODATA_ITEM_CMD:
+ switch (qItem[1]) {
+ case PICODATA_ITEMINFO1_CMD_FLUSH:
+ /* flush is for all PU's and as such it is also for PAM*/
+ case PICODATA_ITEMINFO1_CMD_PITCH:
+ case PICODATA_ITEMINFO1_CMD_SPEED:
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+}/*is_pam_command*/
+
+/**
+ * tells if an item is a PAM PLAY command
+ * @param qItem : input item to test
+ * @return TRUE : qItem is a PAM PLAY command
+ * @return FALSE : qItem not a PAM PLAY command
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t is_pam_play_command(picoos_uint8 *qItem)
+{
+ switch (qItem[0]) {
+
+ case PICODATA_ITEM_CMD:
+ switch (qItem[1]) {
+ case PICODATA_ITEMINFO1_CMD_PLAY:
+ if (qItem[2] == PICODATA_ITEMINFO2_CMD_TO_PAM)
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+}/*is_pam_play_command*/
+
+/**
+ * command processor for PAM pu
+ * @param this : Pam item subobject
+ * @param qItem : input item pointer
+ * @return PICOPAM_FLUSH_RECEIVED : when a FLUSH is received
+ * @return PICOPAM_CONTINUE : normal command processing
+ * @return PICODATA_PU_ERROR : errors in accessing data
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pamDoCommand(register picodata_ProcessingUnit this,
+ picoos_uint8 *qItem)
+{
+ pam_subobj_t *pam;
+ picoos_single fValue;
+ picoos_uint16 nValue;
+ picoos_uint32 nPos;
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ if (qItem[0] == PICODATA_ITEM_CMD) {
+ switch (qItem[1]) {
+ case PICODATA_ITEMINFO1_CMD_FLUSH:
+ /* flush is for all PU's and as such it is also for PAM : implement the flush!!*/
+ pam_reset_processors(this);
+ pam->nLastAttachedItemId = pam->nCurrAttachedItem = 0;
+ pam->nAttachedItemsSize = 0;
+ return PICOPAM_FLUSH_RECEIVED;
+ break;
+
+ case PICODATA_ITEMINFO1_CMD_PITCH:
+ case PICODATA_ITEMINFO1_CMD_SPEED:
+ nPos = 4;
+ picoos_read_mem_pi_uint16(qItem, &nPos, &nValue);
+ if (qItem[2] == 'a') {
+ /*absloute modifier*/
+ fValue = (picoos_single) nValue / (picoos_single) 100.0f;
+ if (qItem[1] == PICODATA_ITEMINFO1_CMD_PITCH)
+ pam->pMod = fValue;
+ if (qItem[1] == PICODATA_ITEMINFO1_CMD_SPEED)
+ pam->dMod = (1.0f / fValue);
+ }
+ if (qItem[2] == 'r') {
+ /*relative modifier*/
+ fValue = (picoos_single) nValue / (picoos_single) 1000.0f;
+ if (qItem[1] == PICODATA_ITEMINFO1_CMD_PITCH)
+ pam->pMod *= (1.0f / fValue);
+ if (qItem[1] == PICODATA_ITEMINFO1_CMD_SPEED)
+ pam->dMod *= (1.0f / fValue);
+ }
+ return PICOPAM_CONTINUE;
+ break;
+
+ default:
+ break;
+ }/*end switch switch (qItem[1])*/
+ }/*end if (qItem[0]==PICODATA_ITEM_CMD)*/
+ return PICOPAM_CONTINUE;
+}/*pamDoCommand*/
+
+/**
+ * defines if an item has to be sent to following PUs
+ * @param qItem : input item pointer
+ * @return TRUE : item has to be transmitted to following PUs
+ * @return FALSE : item has to be consumed internallz on PAM
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t isItemToPut(picoos_uint8 *qItem)
+{
+ switch (qItem[0]) {
+ case PICODATA_ITEM_CMD:
+ /* is a command*/
+ if (PICODATA_ITEMINFO1_CMD_SPEED == qItem[1]) {
+ /* SPEED consumed here*/
+ return FALSE;
+ }
+ break;
+ case PICODATA_ITEM_BOUND:
+ switch (qItem[1]) {
+ case PICODATA_ITEMINFO1_BOUND_SBEG:
+ case PICODATA_ITEMINFO1_BOUND_PHR0:
+ case PICODATA_ITEMINFO1_BOUND_PHR1:
+ case PICODATA_ITEMINFO1_BOUND_PHR2:
+ case PICODATA_ITEMINFO1_BOUND_PHR3:
+ /*boudary items consumed here except SEND,TERM*/
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ /*all other items not explicitly mentioned here
+ are transmitted to next PUs*/
+ return TRUE;
+}/*isItemToPut*/
+
+/**
+ * pushes a boundary TERM item into some buffer
+ * @param outBuff : output buffer base pointer
+ * @param outWritePos : offset in output buffer
+ * @param *bytesWr : actual bytes written
+ * @return PICO_OK
+ * @remarks used while forcing TERM input items in forward processing
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_put_term(picoos_uint8 *outBuff,
+ picoos_uint16 outWritePos, picoos_uint8 *bytesWr)
+{
+ picoos_uint8 *sDest;
+ sDest = &(outBuff[outWritePos]);
+ sDest[0] = PICODATA_ITEM_BOUND; /*Item type*/
+ sDest[1] = PICODATA_ITEMINFO1_BOUND_TERM;
+ sDest[2] = PICODATA_ITEMINFO2_BOUNDTYPE_T;
+ sDest[3] = 0; /*item size*/
+ *bytesWr = 4;
+ return PICO_OK;
+}/*pam_put_term*/
+
+/**
+ * translates one full phone into a PHONE Item including DT Dur, F0 and CEP trees feature generation and traversal
+ * @param this : Pam item subobject pointer
+ * @return PICO_OK : processing successful
+ * @return PICODATA_PU_ERROR : error accessing PAM object
+ * @return !=PICO_OK : processing errors
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pamPhoneProcess(register picodata_ProcessingUnit this)
+{
+ pam_subobj_t *pam;
+ pico_status_t sResult;
+ picokdt_classify_result_t dTreeResult;
+ picoos_uint8 nI, bWr;
+
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ /*expands current phone in current syllable in the corresponding vector pam->sPhFeats[]*/
+ sResult = pam_expand_vector(this);
+ sResult = pamCompressVector(this);
+ sResult = pamReorgVector(this);
+
+ /*tree traversal for duration*/
+ if (!pam_do_tree(this, pam->dtdur, &(pam->sPhFeats[0]), PICOPAM_INVEC_SIZE,
+ &dTreeResult)) {
+ PICODBG_WARN(("problem using pam tree dtdur, using fallback value"));
+ dTreeResult.class = 0;
+ }
+ pam->durIndex = dTreeResult.class;
+ sResult = pam_get_duration(this, pam->durIndex, &(pam->phonDur),
+ &(pam->numFramesState[0]));
+
+ /*tree traversal for pitch*/
+ for (nI = 0; nI < PICOPAM_MAX_STATES_PER_PHONE; nI++) {
+ if (!pam_do_tree(this, pam->dtlfz[nI], &(pam->sPhFeats[0]),
+ PICOPAM_INVEC_SIZE, &dTreeResult)) {
+ PICODBG_WARN(("problem using pam tree lf0Tree, using fallback value"));
+ dTreeResult.class = 0;
+ }
+ pam->lf0Index[nI] = dTreeResult.class;
+ }
+
+ /*pdf access for pitch*/
+ for (nI = 0; nI < PICOPAM_MAX_STATES_PER_PHONE; nI++) {
+ sResult = pam_get_f0(this, &(pam->lf0Index[0]), nI, &(pam->phonF0[0]));
+ }
+
+ /*update vector with duration and pitch for cep tree traversal*/
+ sResult = pam_update_vector(this);
+ /*cep tree traversal*/
+ for (nI = 0; nI < PICOPAM_MAX_STATES_PER_PHONE; nI++) {
+
+ if (!pam_do_tree(this, pam->dtmgc[nI], &(pam->sPhFeats[0]),
+ PICOPAM_INVEC_SIZE, &dTreeResult)) {
+ PICODBG_WARN(("problem using pam tree lf0Tree, using fallback value"));
+ dTreeResult.class = 0;
+ }
+ pam->mgcIndex[nI] = dTreeResult.class;
+ }
+ /*put item to output buffer*/
+ sResult = pam_put_item(this, pam->outBuf, pam->outWritePos, &bWr);
+ if (sResult == PICO_OK)
+ pam->outWritePos += bWr;
+ else
+ return sResult;
+ return PICO_OK;
+}/*pamPhoneProcess*/
+
+/**
+ * manages first syllable attached items when seen before SBEG
+ * @param this : Pam item subobject pointer
+ * @return PICO_OK (0) : default return code --> means no more items to be processed before 1st syllable
+ * @return PICOPAM_GOTO_FEED : go to feed state after this
+ * @return PICOPAM_GOTO_SCHEDULE : flush received
+ * @return PICODATA_PU_ERROR : errors
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pamDoPreSyll(register picodata_ProcessingUnit this)
+{
+ pam_subobj_t *pam;
+ pico_status_t sResult;
+ picoos_uint8 bWr, nRc;
+ picoos_uint8 *qItem;
+ nRc = PICOPAM_PRE_SYLL_ENDED;
+ pam = (pam_subobj_t *) this->subObj;
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ /*regenerate initial items before the phonemes*/
+ if (((qItem = pamPopAttachedSy0(this)) != NULL) && !((qItem[0]
+ == PICODATA_ITEM_BOUND) && (qItem[1]
+ == PICODATA_ITEMINFO1_BOUND_SBEG))) {
+ if (isItemToPut(qItem)) {
+ pam_put_qItem(qItem, pam->outBuf, pam->outWritePos, &bWr);/*popped item has to be sent to next PU*/
+ pam->outWritePos += bWr;
+ nRc = PICOPAM_GOTO_FEED;
+ }
+
+ if (is_pam_command(qItem) == TRUE) {
+ nRc = pamDoCommand(this, qItem); /*popped item is a PAM command : do it NOW!!*/
+ if ((nRc == PICOPAM_FLUSH_RECEIVED) || (nRc == PICODATA_PU_ERROR)) {
+ /*FLUSH command RECEIVED or errors: stop ALL PROCESSING*/
+ return nRc;
+ }
+ }
+ pam->nCurrAttachedItem++;
+ if (nRc == 0)
+ return PICOPAM_CONTINUE;
+ else
+ return nRc;
+ }
+ /*SBEG item management*/
+ if ((qItem != NULL) && (qItem[0] == PICODATA_ITEM_BOUND) && (qItem[1]
+ == PICODATA_ITEMINFO1_BOUND_SBEG)) {
+ sResult = pam_put_qItem(qItem, pam->outBuf, pam->outWritePos, &bWr);
+ pam->outWritePos += bWr;
+ pam->nCurrAttachedItem++;
+ nRc = PICOPAM_GOTO_FEED;
+ }
+ return nRc;
+}/*pamDoPreSyll*/
+
+/**
+ * performs a step of the pam processing
+ * @param this : Pam item subobject pointer
+ * @param mode : mode for the PU
+ * @param *numBytesOutput : pointer to output number fo bytes produced
+ * @return PICODATA_PU_IDLE : nothing to do
+ * @return PICODATA_PU_BUSY : still tasks undergoing
+ * @return PICODATA_PU_ERROR : errors on processing
+ * @callgraph
+ * @callergraph
+ */
+static picodata_step_result_t pam_step(register picodata_ProcessingUnit this,
+ picoos_int16 mode, picoos_uint16 * numBytesOutput)
+{
+
+ register pam_subobj_t * pam;
+
+ pico_status_t sResult;
+ picoos_uint16 blen, numinb, numoutb;
+ pico_status_t rv;
+ picoos_uint8 bWr;
+ picoos_uint8 bForcedItem[4];
+ picoos_uint8 *qItem;
+
+ numinb = 0;
+ numoutb = 0;
+ rv = PICO_OK;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICODATA_PU_ERROR;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ mode = mode; /* avoid warning "var not used in this function"*/
+ /*Init number of output bytes*/
+ *numBytesOutput = 0;
+
+ while (1) { /* exit via return */
+
+ PICODBG_DEBUG(("pam_step -- doing state %i",pam->procState));
+
+ switch (pam->procState) {
+
+ case PICOPAM_COLLECT:
+ /* *************** item collector ***********************************/
+ /*collecting items from the PU input buffer*/
+ sResult = picodata_cbGetItem(this->cbIn,
+ &(pam->inBuf[pam->inWritePos]), pam->inBufSize
+ - pam->inWritePos, &blen);
+ if (sResult != PICO_OK) {
+ if (sResult == PICO_EOF) {
+ /*no items available : remain in state 0 and return idle*/
+ return PICODATA_PU_IDLE;
+ } else {
+ /*errors : remain in state 0 and return error*/
+ PICODBG_DEBUG(("pam_step(PICOPAM_COLLECT) -- Errors on item buffer input, status: %d",sResult));
+ return PICODATA_PU_ERROR;
+ }
+ }
+
+ PICODBG_DEBUG(("pam_step -- got item, status: %d",sResult));
+ sResult = picodata_is_valid_item(
+ &(pam->inBuf[pam->inWritePos]), blen);
+ if (sResult != TRUE) {
+ /*input item is not valid : consume the input item and stay in COLLECT*/
+ pam->inWritePos += blen;
+ pam->inReadPos += blen;
+ if (pam->inReadPos >= pam->inWritePos) {
+ pam->inReadPos = 0;
+ pam->inWritePos = 0;
+ }PICODBG_DEBUG(("pam_step -- item is not valid, type: %d",pam->inBuf[pam->inWritePos]));
+ return PICODATA_PU_BUSY;
+ }
+
+ /*update input write pointer + move to "schedule" state*/
+ pam->inWritePos += blen;
+ pam->procState = PICOPAM_SCHEDULE;
+ return PICODATA_PU_BUSY;
+
+ case PICOPAM_SCHEDULE:
+ /* check out if more items are available */
+ if (pam->inReadPos >= pam->inWritePos) {
+ /*no more items : back to collect state*/
+ pam->procState = PICOPAM_COLLECT;
+ return PICODATA_PU_BUSY;
+ }
+ /* we have one full valid item, with len>0 starting at
+ pam->inBuf[pam->inReadPos]; here we decide how to elaborate it */
+
+ /* PLAY management */
+ if (is_pam_play_command(&(pam->inBuf[pam->inReadPos])) == TRUE) {
+ /*consume the input item : it has been managed*/
+ pam->inReadPos += pam->inBuf[pam->inReadPos + 3]
+ + sizeof(picodata_itemhead_t);
+ if (pam->inReadPos >= pam->inWritePos) {
+ pam->inReadPos = 0;
+ pam->inWritePos = 0;
+ }
+ /*stay in schedule*/
+ return PICODATA_PU_BUSY;
+ }
+
+ if (pam_check_immediate(this, &(pam->inBuf[pam->inReadPos]))) {
+ /* item has to be sent to next PU NOW : switch to "immediate" state */
+ pam->procState = PICOPAM_IMMEDIATE;
+ return PICODATA_PU_BUSY;
+ }
+ if (pamCheckResourceLimits(this, &(pam->inBuf[pam->inReadPos]))) {
+ /* item would not fit into local buffers -->> free some space -->>
+ switch to "force term" state */
+ pam->procState = PICOPAM_FORWARD_FORCE_TERM;
+ return PICODATA_PU_BUSY;
+ }
+
+ if (pam_deal_with(&(pam->inBuf[pam->inReadPos]))) {
+ /* item has to be managed by the "forward" state : switch to forward state*/
+ pam->procState = PICOPAM_FORWARD;
+ return PICODATA_PU_BUSY;
+ }
+
+ if (pam_hastobe_queued(this, &(pam->inBuf[pam->inReadPos]))) {
+ /* item is not for PAM so it has to be queued internally */
+ pam_queue(this, &(pam->inBuf[pam->inReadPos]));
+ /*consume the input item : it has been queued*/
+ pam->inReadPos += pam->inBuf[pam->inReadPos + 3]
+ + sizeof(picodata_itemhead_t);
+ if (pam->inReadPos >= pam->inWritePos) {
+ pam->inReadPos = 0;
+ pam->inWritePos = 0;
+ }
+ return PICODATA_PU_BUSY;
+ }
+ /*if we get here something wrong happened. Being the the item valid,
+ switch to "immediate" state -> send it to next PU -> */
+ PICODBG_DEBUG(("pam_step (PICOPAM_SCHEDULE) -- unexpected item is sent to next PU !!"));
+ pam->procState = PICOPAM_IMMEDIATE;
+ return PICODATA_PU_BUSY;
+ break; /*PICOPAM_SCHEDULE*/
+
+ case PICOPAM_FORWARD:
+ /*we have one full valid item, with len>0 starting at pam->inBuf[pam->inReadPos].
+ furthermore this item should be in the set {BOUND,SYLL}.
+ No other items should arrive here*/
+ sResult = pam_adapter_forward_step(this,
+ &(pam->inBuf[pam->inReadPos]));
+ /*decide if this item has to be queued for later re-synchronization
+ normally this is only done for SEND/TERM items*/
+ if (pam_hastobe_queued(this, &(pam->inBuf[pam->inReadPos]))) {
+ /*item has to be queued iternally in local storage*/
+ pam_queue(this, &(pam->inBuf[pam->inReadPos]));
+ }
+ /*now assign next state according to Forward results*/
+ switch (sResult) {
+ case PICOPAM_READY:
+ pam->needMoreInput = FALSE;
+ /*consume the input item : it has already been stored*/
+ pam->inReadPos += pam->inBuf[pam->inReadPos + 3]
+ + sizeof(picodata_itemhead_t);
+ if (pam->inReadPos >= pam->inWritePos) {
+ pam->inReadPos = 0;
+ pam->inWritePos = 0;
+ }
+ /*activate backward processing*/
+ sResult = pam_adapter_backward_step(this);
+ if (sResult == PICO_OK) {
+ pam->procState = PICOPAM_PROCESS;
+ return PICODATA_PU_BUSY;
+ } else {
+ PICODBG_DEBUG(("pam_step (PICOPAM_FORWARD) -- wrong return from BackwardStep: %d -- Buffered sentence will be discarded",sResult));
+ pam_reset_processors(this);
+ pam->nLastAttachedItemId = pam->nCurrAttachedItem
+ = 0;
+ pam->nAttachedItemsSize = 0;
+
+ pam->procState = PICOPAM_SCHEDULE;
+ return PICODATA_PU_BUSY;
+ }
+ break;
+
+ case PICOPAM_MORE:
+ pam->needMoreInput = TRUE;
+ /*consume the input item : it has already been stored*/
+ pam->inReadPos += pam->inBuf[pam->inReadPos + 3]
+ + sizeof(picodata_itemhead_t);
+ if (pam->inReadPos >= pam->inWritePos) {
+ /*input is finished and PAM need more data :
+ clenaup input buffer + switch state back to "schedule state"
+ */
+ pam->inReadPos = 0;
+ pam->inWritePos = 0;
+ pam->procState = PICOPAM_SCHEDULE;
+ return PICODATA_PU_ATOMIC;
+ } else {
+ /*input is not finished and need more data :
+ remain in state "PICOPAM_FORWARD" */
+ return PICODATA_PU_ATOMIC;
+ }
+ break;
+
+ case PICOPAM_NA:
+ default:
+ /*this item has not been stored in internal buffers:
+ assign this item to the management of
+ "immediate" state*/
+ pam->procState = PICOPAM_IMMEDIATE;
+ return PICODATA_PU_BUSY;
+ break;
+ } /*end switch sResult*/
+ break; /*PICOPAM_FORWARD*/
+
+ case PICOPAM_FORWARD_FORCE_TERM:
+ /*we have one full valid item, with len>0
+ starting at pam->inBuf[pam->inReadPos] but we decided
+ to force a TERM item before, without losing the item in
+ inBuf[inReadPos] : --> generate a TERM item and do the
+ forward processing */
+ pam_put_term(bForcedItem, 0, &bWr);
+ sResult = pam_adapter_forward_step(this, &(bForcedItem[0]));
+ switch (sResult) {
+ case PICOPAM_READY:
+ pam_queue(this, &(bForcedItem[0]));
+ /*activate backward processing*/
+ sResult = pam_adapter_backward_step(this);
+ if (sResult == PICO_OK) {
+ pam->procState = PICOPAM_PROCESS;
+ return PICODATA_PU_BUSY;
+ } else {
+ PICODBG_DEBUG(("pam_step (PICOPAM_FORWARD_FORCE_TERM) -- wrong return from BackwardStep: %d -- Buffered sentence will be discarded",sResult));
+ pam_reset_processors(this);
+ pam->nLastAttachedItemId = pam->nCurrAttachedItem
+ = 0;
+ pam->nAttachedItemsSize = 0;
+
+ pam->procState = PICOPAM_SCHEDULE;
+ return PICODATA_PU_BUSY;
+ }
+ break;
+
+ default:
+ PICODBG_DEBUG(("pam_step (PICOPAM_FORWARD_FORCE_TERM) -- Forced a TERM but processing do not appear to end -- Buffered sentence will be discarded",sResult));
+ pam_reset_processors(this);
+ pam->nLastAttachedItemId = pam->nCurrAttachedItem = 0;
+ pam->nAttachedItemsSize = 0;
+
+ pam->procState = PICOPAM_SCHEDULE;
+ return PICODATA_PU_BUSY;
+ break;
+
+ } /*end switch sResult*/
+ break; /*PICOPAM_FORWARD_FORCE_TERM*/
+
+ case PICOPAM_PROCESS:
+
+ if ((PICOPAM_FRAME_ITEM_SIZE + 4) > (pam->outBufSize
+ - pam->outWritePos)) {
+ /*WARNING (buffer overflow): leave status unchanged until output buffer free */
+ return PICODATA_PU_BUSY;
+ }
+
+ if (pam->nCurrSyllable == 0) {
+ sResult = pamDoPreSyll(this);
+ if (sResult == PICOPAM_GOTO_FEED) {
+ /*
+ items pushed to output buffer :
+ switch to "feed" but then back
+ to "process"
+ */
+ pam->retState = PICOPAM_PROCESS;
+ pam->procState = PICOPAM_FEED;
+ return PICODATA_PU_BUSY;
+ }
+ if (sResult == PICOPAM_CONTINUE) {
+ /*
+ items processed (maybe commands) :
+ return (maybe we need to process other
+ items in pre_syll) and then back to "process"
+ */
+ pam->retState = PICOPAM_PROCESS;
+ pam->procState = PICOPAM_PROCESS;
+ return PICODATA_PU_BUSY;
+ }
+
+ if ((sResult == PICOPAM_FLUSH_RECEIVED) || (sResult
+ == PICODATA_PU_ERROR)) {
+ /*
+ items processed were a flush or
+ problems found: switch to "schedule"
+ and abort all processing
+ */
+ pam->retState = PICOPAM_SCHEDULE;
+ pam->procState = PICOPAM_SCHEDULE;
+ return PICODATA_PU_BUSY;
+ }
+ if (sResult == PICOPAM_PRE_SYLL_ENDED) {
+ /*
+ we get here when pam->nCurrSyllable==0 and
+ no more items to be processed before the syllable
+ */
+ sResult = sResult;
+ }
+ }
+
+ if (pamHasToProcess(this)) {
+ if (pamPhoneProcess(this) == PICO_OK) {
+ sResult = pamUpdateProcess(this);
+ pam->procState = PICOPAM_FEED; /*switch to feed*/
+ return PICODATA_PU_BUSY;
+ } else {
+ PICODBG_DEBUG(("pam_step(PICOPAM_PROCESS) --- NULL return from pamPhoneProcess"));
+ return PICODATA_PU_ERROR;
+ }
+ }
+
+ if (pamHasToPop(this) != FALSE) {
+ if ((qItem = pamPopItem(this)) == NULL) {
+ PICODBG_DEBUG(("pam_step(PICOPAM_PROCESS) --- NULL return from pamPopItem"));
+ return PICODATA_PU_ERROR;
+ }
+
+ if (isItemToPut(qItem)) {
+ /*popped item has to be sent to next PU*/
+ sResult = pam_put_qItem(qItem, pam->outBuf,
+ pam->outWritePos, &bWr);
+ if (sResult != PICO_OK) {
+ PICODBG_DEBUG(("pam_step(PICOPAM_PROCESS) --- Error on writing item to output buffer"));
+ return PICODATA_PU_ERROR;
+ }
+ pam->outWritePos += bWr; /*item write ok*/
+ pam->procState = PICOPAM_FEED; /*switch to feed*/
+ }
+
+ /*moved command processing here (after pam_put_qItem) because of FLUSH command could erase
+ * the syllable structure and make it impossible to transmit the flush to other PUs*/
+ if (is_pam_command(qItem) == TRUE) {
+ sResult = pamDoCommand(this, qItem); /*popped item is a PAM command : do it NOW!!*/
+ if ((sResult == PICOPAM_FLUSH_RECEIVED) || (sResult
+ == PICODATA_PU_ERROR)) {
+ pam->retState = PICOPAM_SCHEDULE;
+ pam->procState = PICOPAM_SCHEDULE; /*switch to schedule */
+ return PICODATA_PU_BUSY;
+ }
+ }
+ /*update PAM status: if more items attached to the current syllable
+ stay in current syllable, otherwise move to next syllable and switch
+ to processing phones */
+ sResult = pamUpdateProcess(this); /*both "doCommand" or "put" : update PAM status*/
+ return PICODATA_PU_BUSY;
+ } else {
+ pam->procState = PICOPAM_SCHEDULE; /*switch to schedule */
+ return PICODATA_PU_BUSY;
+ }
+
+ break; /*PICOPAM_PROCESS*/
+
+ case PICOPAM_IMMEDIATE:
+ /* *** item is output NOW!!! */
+ /*context: full valid item, with len> starting at pam->inBuf[pam->inReadPos]*/
+ numinb = PICODATA_ITEM_HEADSIZE
+ + pam->inBuf[pam->inReadPos + 3];
+ sResult = picodata_copy_item(&(pam->inBuf[pam->inReadPos]),
+ numinb, &(pam->outBuf[pam->outWritePos]),
+ pam->outBufSize - pam->outWritePos, &numoutb);
+
+ if (sResult == PICO_OK) {
+ pam->inReadPos += numinb;
+ if (pam->inReadPos >= pam->inWritePos) {
+ pam->inReadPos = 0;
+ pam->inWritePos = 0;
+ pam->needMoreInput = FALSE;
+ }
+ pam->outWritePos += numoutb;
+ pam->procState = PICOPAM_FEED; /*switch to FEED state*/
+ pam->retState = PICOPAM_SCHEDULE; /*back to SCHEDULE after FEED*/
+ } else {
+ /*
+ PICO_EXC_BUF_IGNORE
+ PICO_EXC_BUF_UNDERFLOW
+ PICO_EXC_BUF_OVERFLOW
+ */
+ PICODBG_DEBUG(("pam_step(PICOPAM_IMMEDIATE) --- wrong return from picodata_copy_item:%d",sResult));
+ return PICODATA_PU_ERROR;
+ }
+ return PICODATA_PU_BUSY;
+ break; /*PICOPAM_IMMEDIATE*/
+
+ case PICOPAM_FEED:
+ /* *************** item output/feeding ***********************************/
+ /*feeding items to PU output buffer*/
+ sResult = picodata_cbPutItem(this->cbOut,
+ &(pam->outBuf[pam->outReadPos]), pam->outWritePos
+ - pam->outReadPos, &numoutb);
+ PICODBG_DEBUG(("pam_step -- put item, status: %d",sResult));
+ if (PICO_OK == sResult) {
+
+ PICODATA_INFO_ITEM(this->voice->kbArray[PICOKNOW_KBID_DBG],
+ (picoos_uint8 *)"pam: ",
+ pam->outBuf + pam->outReadPos, pam->outBufSize);
+
+ pam->outReadPos += numoutb;
+ *numBytesOutput = numoutb;
+ if (pam->outReadPos >= pam->outWritePos) {
+ /*reset the output pointers*/
+ pam->outReadPos = 0;
+ pam->outWritePos = 0;
+ /*switch to appropriate state*/
+ switch (pam->retState) {
+ case PICOPAM_IMMEDIATE:
+ pam->procState = PICOPAM_IMMEDIATE;
+ pam->retState = PICOPAM_SCHEDULE;
+ return PICODATA_PU_BUSY;
+ break;
+ case PICOPAM_PLAY:
+ pam->procState = PICOPAM_PLAY;
+ pam->retState = PICOPAM_SCHEDULE;
+ return PICODATA_PU_BUSY;
+ break;
+ default:
+ break;
+ }
+ /*Define next state
+ a)process (if current sentence has more data to process)
+ b)schedule (no more data to process in current sentence)
+ NOTE : case b)also happens when dealing with non BOUND/SYLL items*/
+ if ((pamHasToProcess(this)) || (pamHasToPop(this))) {
+ pam->procState = PICOPAM_PROCESS;
+ } else {
+ pam->nCurrSyllable = -1;
+ pam_reset_processors(this);
+ pam->nLastAttachedItemId = pam->nCurrAttachedItem
+ = 0;
+ pam->nAttachedItemsSize = 0;
+
+ pam->nSyllPhoneme = 0;
+ pam->procState = PICOPAM_SCHEDULE;
+ }
+ }
+ return PICODATA_PU_BUSY;
+
+ } else if (PICO_EXC_BUF_OVERFLOW == sResult) {
+
+ PICODBG_DEBUG(("pam_step ** feeding, overflow, PICODATA_PU_OUT_FULL"));
+ return PICODATA_PU_OUT_FULL;
+
+ } else if ((PICO_EXC_BUF_UNDERFLOW == sResult)
+ || (PICO_ERR_OTHER == sResult)) {
+
+ PICODBG_DEBUG(("pam_step ** feeding problem, discarding item"));
+ pam->outReadPos = 0;
+ pam->outWritePos = 0;
+ pam->procState = PICOPAM_COLLECT;
+ return PICODATA_PU_ERROR;
+
+ }
+ break; /*PICOPAM_FEED*/
+
+ default:
+ /*NOT feeding items*/
+ sResult = PICO_EXC_BUF_IGNORE;
+ break;
+ }/*end switch*/
+ return PICODATA_PU_BUSY; /*check if there is more data to process after feeding*/
+
+ }/*end while*/
+ return PICODATA_PU_IDLE;
+}/*pam_step*/
+
+/**
+ * performs one step of a PamTree
+ * @param this : Pam item subobject pointer
+ * @param dtpam : the Pam decision tree
+ * @param *invec : the input vector pointer
+ * @param inveclen : length of the input vector
+ * @param *dtres : the classification result
+ * @return dtres->set : the result of tree traversal
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 pam_do_tree(register picodata_ProcessingUnit this,
+ const picokdt_DtPAM dtpam, const picoos_uint8 *invec,
+ const picoos_uint8 inveclen, picokdt_classify_result_t *dtres)
+{
+ picoos_uint8 okay;
+
+ okay = TRUE;
+ /* construct input vector, which is set in dtpam */
+ if (!picokdt_dtPAMconstructInVec(dtpam, invec, inveclen)) {
+ /* error constructing invec */
+ PICODBG_WARN(("problem with invec"));
+ picoos_emRaiseWarning(this->common->em, PICO_WARN_INVECTOR, NULL, NULL);
+ okay = FALSE;
+ }
+ /* classify */
+ if (okay && (!picokdt_dtPAMclassify(dtpam))) {
+ /* error doing classification */
+ PICODBG_WARN(("problem classifying"));
+ picoos_emRaiseWarning(this->common->em, PICO_WARN_CLASSIFICATION, NULL,
+ NULL);
+ okay = FALSE;
+ }
+ /* decompose */
+ if (okay && (!picokdt_dtPAMdecomposeOutClass(dtpam, dtres))) {
+ /* error decomposing */
+ PICODBG_WARN(("problem decomposing"));
+ picoos_emRaiseWarning(this->common->em, PICO_WARN_OUTVECTOR, NULL, NULL);
+ okay = FALSE;
+ }
+
+ PICODBG_TRACE(("dtpam output class: %d", dtres->class));
+
+ return dtres->set;
+}/*pam_do_tree*/
+
+/**
+ * returns the carrier vowel id inside a syllable
+ * @param this : Pam item subobject pointer
+ * @param item : the full syllable item
+ * @param *pos : pointer to the variable to receive the position of the carrier vowel
+ * @return the phonetic id for the carrier vowel inside the syllable
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 pam_get_vowel_name(register picodata_ProcessingUnit this,
+ picoos_uint8 *item, picoos_uint8 *pos)
+{
+ pam_subobj_t *pam;
+ picoos_uint8 *phon, nI, nCond1;
+ if (NULL == this || NULL == this->subObj) {
+ return 0;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ if (item == NULL)
+ return 0;
+ if (item[3] == 0)
+ return 0;
+ phon = &item[4];
+ for (nI = 0; nI < item[3]; nI++) {
+ nCond1 = picoktab_isSyllCarrier(pam->tabphones, phon[nI]);
+ if (nCond1) {
+ *pos = nI;
+ return phon[nI];
+ }
+ }
+ return 0;
+}/*pam_get_vowel_name */
+
+/**
+ * returns the pause phone id in the current ph.alphabet
+ * @param this : Pam sub object pointer
+ * @return the (numeric) phonetic id of the pause phone in current phonetic alphabet
+ * @return 0 : errors on getting the pam subobject pointer
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 pam_get_pause_id(register picodata_ProcessingUnit this)
+{
+ picoos_uint8 nVal1;
+ /*picoos_uint8 nVal2; */
+ pam_subobj_t *pam;
+ if (NULL == this || NULL == this->subObj) {
+ return 0;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ nVal1 = picoktab_getPauseID(pam->tabphones);
+ return nVal1;
+}/*pam_get_pause_id */
+
+/**
+ * returns the pam sentence type (declarative, interrogative...)
+ * @param iteminfo1 : the boundary item info 1
+ * @param iteminfo2 : the boundary item info 2
+ * @return the sentence type suitably encoded for trees
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 pam_map_sentence_type(picoos_uint8 iteminfo1,
+ picoos_uint8 iteminfo2)
+{
+ switch (iteminfo2) {
+ case PICODATA_ITEMINFO2_BOUNDTYPE_P:
+ return PICOPAM_DECLARATIVE;
+ case PICODATA_ITEMINFO2_BOUNDTYPE_T:
+ return PICOPAM_DECLARATIVE;
+ case PICODATA_ITEMINFO2_BOUNDTYPE_Q:
+ return PICOPAM_INTERROGATIVE;
+ case PICODATA_ITEMINFO2_BOUNDTYPE_E:
+ return PICOPAM_DECLARATIVE;
+ default:
+ return PICOPAM_DECLARATIVE;
+ }
+ iteminfo1 = iteminfo1; /* avoid warning "var not used in this function"*/
+ return PICOPAM_DECLARATIVE;
+}/*pam_map_sentence_type */
+
+/**
+ * returns the pam phrase type
+ * @param iteminfo1 : the boundary item info 1
+ * @param iteminfo2 : the boundary item info 2
+ * @return the phrase type suitably encoded for trees
+ * @callgraph
+ * @callergraph
+ */
+static picoos_uint8 pam_map_phrase_type(picoos_uint8 iteminfo1,
+ picoos_uint8 iteminfo2)
+{
+
+ switch (iteminfo2) {
+ case PICODATA_ITEMINFO2_BOUNDTYPE_P:
+ switch (iteminfo1) {
+ case PICODATA_ITEMINFO1_BOUND_PHR1:
+# ifdef PAM_PHR2_WITH_PR1
+ case PICODATA_ITEMINFO1_BOUND_PHR2:
+# endif
+ return PICOPAM_P; /*current_prhase type = "P" (encoded to 1) */
+ break;
+ case PICODATA_ITEMINFO1_BOUND_PHR3:
+# ifdef PAM_PHR2_WITH_PR3
+ case PICODATA_ITEMINFO1_BOUND_PHR2 :
+# endif
+ return PICOPAM_p; /*current_prhase type = "p" (encoded to 2) */
+ break;
+ case PICODATA_ITEMINFO1_BOUND_SBEG:
+ return PICOPAM_P; /*current_prhase type = "P" (encoded to 1) */
+ break;
+ default:
+ PICODBG_DEBUG(("Map pam_map_phrase_type : unexpected iteminfo1"));
+ return PICOPAM_P; /*current_prhase type = "P" (encoded to 1) */
+ break;
+ }
+ case PICODATA_ITEMINFO2_BOUNDTYPE_T:
+ return PICOPAM_T; /*current_prhase type = "T" (encoded to 0) */
+ break;
+ case PICODATA_ITEMINFO2_BOUNDTYPE_E:
+ return PICOPAM_T; /*current_prhase type = "T" (encoded to 0) */
+ break;
+ case PICODATA_ITEMINFO2_BOUNDTYPE_Q:
+ return PICOPAM_Y; /*current_prhase type = "T" (encoded to 0) */
+ break;
+ default:
+ PICODBG_DEBUG(("Map pam_map_phrase_type : unexpected iteminfo2"));
+ return PICOPAM_T; /*current_prhase type = "T" (encoded to 0) */
+ break;
+ }PICODBG_DEBUG(("Map pam_map_phrase_type : unexpected iteminfo2"));
+ return PICOPAM_T; /*current_prhase type = "T" (encoded to 0) */
+
+}/*pam_map_phrase_type */
+
+/**
+ * does the cleanup of the sub object processors flags at sentence start
+ * @param this : pointer to PAM PU sub object pointer
+ * @return PICO_OK : reset OK
+ * @return PICO_ERR_OTHER : errors on getting pam sub obj pointer
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_reset_processors(register picodata_ProcessingUnit this)
+{
+ pam_subobj_t *pam;
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ pam->nCurrSyllable = -1;
+ pam->nTotalPhonemes = pam->nSyllPhoneme = pam->nCurrPhoneme
+ = pam->nTotalSyllables = pam->sType = pam->pType = 0;
+ pam->dRest = 0.0f;
+ /*set all to 0*/
+ pam->a3_overall_syllable = pam->a3_primary_phrase_syllable = pam->b4_b5_syllable =
+ pam->b6_b7_syllable = pam->b6_b7_state = pam->b8_b9_stressed_syllable =
+ pam->b10_b11_accented_syllable = pam->b12_b13_syllable = pam->b12_b13_state =
+ pam->b14_b15_syllable = pam->b14_b15_state = pam->b17_b19_syllable =
+ pam->b17_b19_state = pam->b18_b20_b21_syllable = pam->b18_b20_b21_state =
+ pam->c3_overall_syllable= pam->c3_primary_phrase_syllable = pam->d2_syllable_in_word =
+ pam->d2_prev_syllable_in_word = pam->d2_current_primary_phrase_word = pam->e1_syllable_word_start =
+ pam->e1_syllable_word_end= pam->e1_content = pam->e2_syllable_word_start =
+ pam->e2_syllable_word_end= pam->e3_e4_word = pam->e3_e4_state =
+ pam->e5_e6_content_word = pam->e5_e6_content = pam->e7_e8_word =
+ pam->e7_e8_content = pam->e7_e8_state = pam->e9_e11_word =
+ pam->e9_e11_saw_word = pam->e9_e11_state = pam->e10_e12_e13_word =
+ pam->e10_e12_e13_state = pam->e10_e12_e13_saw_word = pam->f2_overall_word =
+ pam->f2_word_syllable = pam->f2_next_word_syllable = pam->f2_current_primary_phrase_word =
+ pam->g1_current_secondary_phrase_syllable = pam->g1_current_syllable =
+ pam->g2_current_secondary_phrase_word = pam->g2_current_word =
+ pam->h1_current_secondary_phrase_syll = pam->h2_current_secondary_phrase_word =
+ pam->h3_h4_current_secondary_phrase_word = pam->h5_current_phrase_type =
+ pam->h5_syllable = pam->h5_state = pam->i1_secondary_phrase_syllable =
+ pam->i1_next_secondary_phrase_syllable = pam->i2_secondary_phrase_word =
+ pam->i2_next_secondary_phrase_word = pam->j1_utterance_syllable =
+ pam->j2_utterance_word = pam->j3_utterance_sec_phrases = 0;
+ /*Override 0 with 1*/
+ pam->b4_b5_syllable = pam->b17_b19_syllable = pam->b18_b20_b21_syllable =
+ pam->e9_e11_word = pam->e10_e12_e13_word = pam->e7_e8_word =
+ pam->h2_current_secondary_phrase_word = 1;
+ /*Override 0 with -1*/
+ pam->e1_syllable_word_start = pam->e1_syllable_word_end = pam->e2_syllable_word_start =
+ pam->e2_syllable_word_end = -1;
+
+ return PICO_OK;
+}/*pam_reset_processors*/
+
+/**
+ * does the cleanup of the sub object processors flags before the backward step
+ * @param this : pointer to PAM PU sub object pointer
+ * @return PICO_OK : reset OK
+ * @return PICO_ERR_OTHER : errors on getting pam sub obj pointer
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_reset_processors_back(
+ register picodata_ProcessingUnit this)
+{
+ pam_subobj_t *pam;
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ /*set all to 0*/
+ pam->a3_overall_syllable
+ = pam->a3_primary_phrase_syllable
+ = pam->b4_b5_syllable
+ = pam->b6_b7_syllable
+ = pam->b6_b7_state
+ = pam->b8_b9_stressed_syllable
+ = pam->b10_b11_accented_syllable
+ = pam->b12_b13_syllable
+ = pam->b12_b13_state
+ = pam->b14_b15_syllable
+ = pam->b14_b15_state
+ = pam->b17_b19_syllable
+ = pam->b17_b19_state
+ = pam->b18_b20_b21_syllable
+ = pam->b18_b20_b21_state
+ = pam->c3_overall_syllable
+ = pam->c3_primary_phrase_syllable
+ = pam->d2_syllable_in_word
+ = pam->d2_prev_syllable_in_word
+ = pam->d2_current_primary_phrase_word
+ = pam->e1_syllable_word_start
+ = pam->e1_syllable_word_end
+ = pam->e1_content
+ = pam->e2_syllable_word_start
+ = pam->e2_syllable_word_end
+ = pam->e3_e4_word
+ = pam->e3_e4_state
+ = pam->e5_e6_content_word
+ = pam->e5_e6_content
+ = pam->e7_e8_word
+ = pam->e7_e8_content
+ = pam->e7_e8_state
+ = pam->e9_e11_word
+ = pam->e9_e11_saw_word
+ = pam->e9_e11_state
+ = pam->e10_e12_e13_word
+ = pam->e10_e12_e13_state
+ = pam->e10_e12_e13_saw_word
+ = pam->f2_overall_word
+ = pam->f2_word_syllable
+ = pam->f2_next_word_syllable
+ = pam->f2_current_primary_phrase_word
+ = pam->g1_current_secondary_phrase_syllable
+ = pam->g1_current_syllable
+ = pam->g2_current_secondary_phrase_word
+ = pam->g2_current_word
+ = pam->h1_current_secondary_phrase_syll
+ = pam->h2_current_secondary_phrase_word
+ = pam->h3_h4_current_secondary_phrase_word
+ = pam->h5_current_phrase_type
+ = pam->h5_state
+ = pam->i1_secondary_phrase_syllable
+ = pam->i1_next_secondary_phrase_syllable
+ = pam->i2_secondary_phrase_word
+ = pam->i2_next_secondary_phrase_word
+ = 0;
+ /*Override 0 with 1*/
+ pam->b4_b5_syllable = pam->b17_b19_syllable = pam->b18_b20_b21_syllable
+ = pam->e9_e11_word = pam->e10_e12_e13_word = pam->e7_e8_word
+ = pam->h2_current_secondary_phrase_word = 1;
+ /*Override 0 with -1*/
+ pam->e1_syllable_word_start = pam->e1_syllable_word_end
+ = pam->e2_syllable_word_start = pam->e2_syllable_word_end = -1;
+
+ return PICO_OK;
+}/*pam_reset_processors_back*/
+
+/**
+ * processes an input event for a specific feature
+ * @param this : pointer to PAM PU sub object pointer
+ * @param nFeat : feature column to process
+ * @param event_type : event id among syll/boundprim/boundsec/boundword
+ * @param direction : forward(0)/backward(1)
+ * @return PICO_OK : process OK
+ * @return PICO_ERR_OTHER : errors on getting pam sub obj pointer
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_process_event_feature(
+ register picodata_ProcessingUnit this, picoos_uint8 nFeat,
+ picoos_uint8 event_type, picoos_uint8 direction)
+{
+ picoos_uint8 sDest, nI;
+ picoos_uint16 syllCurr;
+ pam_subobj_t *pam;
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ syllCurr = pam->nCurrSyllable;
+ switch (nFeat) {
+ case A3:
+ /*processor for A3*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1]
+ == 1) || (pam->a3_primary_phrase_syllable >= 1)) {
+ if (pam->a3_overall_syllable < 1)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3]
+ = 0;
+ else
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3]
+ = pam->sSyllFeats[pam->nCurrSyllable
+ - 1].phoneV[B3];
+ } else {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3] = 0;
+ }
+ pam->a3_primary_phrase_syllable++;
+ pam->a3_overall_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->a3_primary_phrase_syllable = 0;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ /*do nothing*/
+ break;
+ }
+ break;
+ case B1:
+ case B2:
+ case B3:
+ /*done in createSyllable*/
+ break;
+ case B4:/*processor for B4,B5*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = B4;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = B5;
+ break;
+ default:
+ sDest = B4;
+ break;
+ }
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1] == 0) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->b4_b5_syllable;
+ pam->b4_b5_syllable++;
+ } else {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest] = 0;
+ }
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND)) {
+ pam->b4_b5_syllable = 1;
+ }
+ break;
+ case B5:/*processor for B5 : done in B4*/
+ break;
+ case B6:/*processor for B6,B7*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = B6;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = B7;
+ break;
+ default:
+ sDest = B6;
+ break;
+ }
+ switch (pam->b6_b7_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = PICOPAM_DONT_CARE_VALUE;
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->b6_b7_syllable = 1;
+ pam->b6_b7_state = 1;
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->b6_b7_syllable;
+ pam->b6_b7_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->b6_b7_syllable = 1;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->b6_b7_state = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case B7:/*Done in B6*/
+ break;
+ case B8:/*processor for B8,B9*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = B8;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = B9;
+ break;
+ default:
+ sDest = B8;
+ break;
+ }
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->b8_b9_stressed_syllable;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] == 1)
+ pam->b8_b9_stressed_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->b8_b9_stressed_syllable = 0;
+ }
+
+ break;
+ case B9:/*done in B8*/
+ break;
+ case B10:/*processor for B10, B11*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = B10;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = B11;
+ break;
+ default:
+ sDest = B10;
+ break;
+ }
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->b10_b11_accented_syllable;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] == 1)
+ pam->b10_b11_accented_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->b10_b11_accented_syllable = 0;
+ }
+ break;
+ case B11:/*done in B10*/
+ break;
+ case B12:/*processor for B12,B13*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = B12;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = B13;
+ break;
+ default:
+ sDest = B12;
+ break;
+ }
+ switch (pam->b12_b13_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] == 0)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = PICOPAM_DONT_CARE_VALUE;
+ else {
+ pam->b12_b13_syllable = 0;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->b12_b13_state = 1;
+ }
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->b12_b13_syllable;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] == 1)
+ pam->b12_b13_syllable = 0;
+ else
+ pam->b12_b13_syllable++;
+ pam->b12_b13_state = 2;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->b12_b13_state = 0;
+ break;
+ case 2:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->b12_b13_syllable;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] == 1)
+ pam->b12_b13_syllable = 0;
+ else
+ pam->b12_b13_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->b12_b13_state = 0;
+
+ break;
+ default:
+ break;
+ }
+ break;
+ case B13:/*done in B12*/
+ break;
+
+ case B14:/*processor for B14, B15*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = B14;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = B15;
+ break;
+ default:
+ sDest = B14;
+ break;
+ }
+ switch (pam->b14_b15_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] == 0)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = PICOPAM_DONT_CARE_VALUE;
+ else {
+ pam->b14_b15_syllable = 0;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->b14_b15_state = 1;
+ }
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->b14_b15_syllable;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] == 1)
+ pam->b14_b15_syllable = 0;
+ else
+ pam->b14_b15_syllable++;
+ pam->b14_b15_state = 2;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->b14_b15_state = 0;
+ }
+ break;
+ case 2:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->b14_b15_syllable;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] == 1)
+ pam->b14_b15_syllable = 0;
+ else
+ pam->b14_b15_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->b14_b15_state = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case B15:/*Processor for B15 : done in B14*/
+ break;
+ case B16:/*done in createSyllable*/
+ break;
+ case B17:/*processor for B17, B19 unified */
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ switch (pam->b17_b19_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B17]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B19]
+ = pam->b17_b19_syllable;
+ pam->b17_b19_syllable++;
+ }
+ if (((event_type == PICOPAM_EVENT_P_BOUND)
+ || (event_type == PICOPAM_EVENT_S_BOUND))
+ && (pam->b17_b19_syllable > 1)) {
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->b17_b19_syllable = 1;
+ pam->b17_b19_state = 1;
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B17]
+ = pam->b17_b19_syllable;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B19]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->b17_b19_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->b17_b19_syllable = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ /*do nothing*/
+ break;
+ }
+ break;
+ case B18:/*processor for B18, B20, B21 unfied*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:/*do nothing*/
+ break;
+ case PICOPAM_DIR_BACK:
+ switch (pam->b18_b20_b21_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B18]
+ = PICOPAM_DONT_CARE_VALUE;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
+ == PICOPAM_DECLARATIVE) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
+ = pam->b18_b20_b21_syllable;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
+ = PICOPAM_DONT_CARE_VALUE;
+ } else {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
+ = pam->b18_b20_b21_syllable;
+ }
+ pam->b18_b20_b21_syllable++;
+ }
+ if (((event_type == PICOPAM_EVENT_P_BOUND)
+ || (event_type == PICOPAM_EVENT_S_BOUND))
+ && (pam->b18_b20_b21_syllable > 1)) {
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->b18_b20_b21_syllable = 1;
+ pam->b18_b20_b21_state = 1;
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B18]
+ = pam->b18_b20_b21_syllable;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->b18_b20_b21_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->b18_b20_b21_syllable = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ break;
+ case B19:/*processor for B19 : done in B17*/
+ break;
+ case B20:/*processor for B20 : done in B18*/
+ break;
+ case B21:/*processor for B21 : done in B18*/
+ break;
+ case C3:/*processor for C3*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ /*do nothing*/
+ break;
+ case PICOPAM_DIR_BACK:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1]
+ == 1) || (pam->c3_primary_phrase_syllable >= 1)) {
+ if (pam->c3_overall_syllable < 1)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3]
+ = 0;
+ else
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3]
+ = pam->sSyllFeats[pam->nCurrSyllable
+ + 1].phoneV[B3];
+ } else {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3] = 0;
+ }
+ pam->c3_primary_phrase_syllable++;
+ pam->c3_overall_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->c3_primary_phrase_syllable = 0;
+ }
+ break;
+ }
+ break;
+ case D2:/*processor for D2*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1]
+ == 1) || (pam->d2_current_primary_phrase_word
+ >= 1))
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[D2]
+ = pam->d2_prev_syllable_in_word;
+ else
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[D2] = 0;
+
+ pam->d2_syllable_in_word++;
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND)) {
+ pam->d2_current_primary_phrase_word = 1;
+ pam->d2_prev_syllable_in_word
+ = pam->d2_syllable_in_word;
+ pam->d2_syllable_in_word = 0;
+ /*pam->d2_current_primary_phrase_word++;*/
+ }
+ if ((event_type == PICOPAM_EVENT_P_BOUND)) {
+ pam->d2_current_primary_phrase_word = 0;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ /*do nothing*/
+ break;
+ }
+ break;
+ case E1:/*processor for E1*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW: /*remember : content syllable indicator already on P5*/
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->e1_syllable_word_start == -1)
+ pam->e1_syllable_word_start
+ = (picoos_int8) pam->nCurrSyllable;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] == 1)
+ pam->e1_content = 1;
+ pam->e1_syllable_word_end
+ = (picoos_int8) pam->nCurrSyllable;
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND)) {
+ if ((pam->e1_syllable_word_start != -1)
+ && (pam->e1_syllable_word_end != -1)) {
+ for (nI = pam->e1_syllable_word_start; nI
+ <= pam->e1_syllable_word_end; nI++)
+ pam->sSyllFeats[nI].phoneV[E1]
+ = pam->e1_content;
+ }
+ pam->e1_content = 0;
+ pam->e1_syllable_word_start = -1;
+ pam->e1_syllable_word_end = -1;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ /*do nothing*/
+ break;
+ }
+ break;
+ case E2:/*processor for E2*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->e2_syllable_word_start == -1)
+ pam->e2_syllable_word_start
+ = (picoos_int8) pam->nCurrSyllable;
+ pam->e2_syllable_word_end
+ = (picoos_int8) pam->nCurrSyllable;
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND)) {
+ if ((pam->e2_syllable_word_start != -1)
+ && (pam->e2_syllable_word_end != -1)) {
+ for (nI = pam->e2_syllable_word_start; nI
+ <= pam->e2_syllable_word_end; nI++)
+ pam->sSyllFeats[nI].phoneV[E2]
+ = pam->e2_syllable_word_end
+ - pam->e2_syllable_word_start
+ + 1;
+ }
+ pam->e1_content = 0;
+ pam->e2_syllable_word_start = -1;
+ pam->e2_syllable_word_end = -1;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ break;
+ }
+ break;
+ case E3:/*processor for E3,E4*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = E3;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = E4;
+ break;
+ default:
+ sDest = E3;
+ break;
+ }
+ switch (pam->e3_e4_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = PICOPAM_DONT_CARE_VALUE;
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->e3_e4_word = 1;
+ pam->e3_e4_state = 1;
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->e3_e4_word;
+ if (event_type == PICOPAM_EVENT_S_BOUND)
+ pam->e3_e4_word = 1;
+ if (event_type == PICOPAM_EVENT_W_BOUND)
+ pam->e3_e4_word++;
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->e3_e4_state = 0;
+ break;
+ default:
+ break;
+ }
+ break;
+ case E4:/*processor for E4 : done in E3*/
+ break;
+ case E5:/*processor for E5,E6*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = E5;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = E6;
+ break;
+ default:
+ sDest = E5;
+ break;
+ }
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->e5_e6_content_word;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] == 1)
+ pam->e5_e6_content = 1;
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND)) {
+ if (pam->e5_e6_content == 1)
+ pam->e5_e6_content_word++;
+ pam->e5_e6_content = 0;
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->e5_e6_content_word = 0;
+ }
+ break;
+ case E6:/*processor for E6 : done in E5*/
+ break;
+ case E7:/*processor for E7,E8*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = E7;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = E8;
+ break;
+ default:
+ sDest = E7;
+ break;
+ }
+ switch (pam->e7_e8_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = PICOPAM_DONT_CARE_VALUE;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] == 1)
+ pam->e7_e8_content = 1;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->e7_e8_content = 0;
+ }
+
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND)) {
+ if (pam->e7_e8_content == 1) {
+ pam->e7_e8_word = 0;
+ pam->e7_e8_content = 0;
+ pam->e7_e8_state = 1;
+ }
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->e7_e8_word;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] == 1)
+ pam->e7_e8_content = 1;
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND)) {
+ if (pam->e7_e8_content == 1) {
+ pam->e7_e8_word = 0;
+ pam->e7_e8_content = 0;
+ } else {
+ pam->e7_e8_word++;
+ }
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->e7_e8_state = 0;
+ pam->e7_e8_content = 0; /*<<<<<< added */
+ }
+
+ default:
+ break;
+ }
+ break;
+ case E8:/*processor for E8 : done in E7*/
+ break;
+ case E9:
+ /*processor for E9, E11*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ switch (pam->e9_e11_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E9]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E11]
+ = pam->e9_e11_word;
+ pam->e9_e11_saw_word = 1; /*new variable, needs to be initialized to 0*/
+ }
+ if (event_type == PICOPAM_EVENT_W_BOUND)
+ pam->e9_e11_word++;
+ if (((event_type == PICOPAM_EVENT_P_BOUND)
+ || (event_type == PICOPAM_EVENT_S_BOUND))
+ && (pam->e9_e11_saw_word == 1)) { /* modified*/
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->e9_e11_word = 1;
+ else
+ pam->e9_e11_word++; /*modified*/
+ pam->e9_e11_state = 1;
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E9]
+ = pam->e9_e11_word;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E11]
+ = PICOPAM_DONT_CARE_VALUE;
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND)
+ || (event_type == PICOPAM_EVENT_S_BOUND))
+ pam->e9_e11_word++;
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->e9_e11_word = 1;
+ break;
+ default:
+ break;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ /*do nothing*/
+ break;
+ }
+ break;
+ case E10:/*processor for E10, E12, E13 unified*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:/*do nothing*/
+ break;
+ case PICOPAM_DIR_BACK:
+ switch (pam->e10_e12_e13_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E10]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->e10_e12_e13_saw_word = 1;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
+ == PICOPAM_DECLARATIVE) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
+ = pam->e10_e12_e13_word;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
+ = PICOPAM_DONT_CARE_VALUE;
+ } else {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
+ = pam->e10_e12_e13_word;
+ }
+ }
+ if (event_type == PICOPAM_EVENT_W_BOUND)
+ pam->e10_e12_e13_word++;
+
+ /*if (((event_type==PICOPAM_EVENT_P_BOUND)||(event_type==PICOPAM_EVENT_S_BOUND))&&(pam->e10_e12_e13_word>1)) {*/
+ if (((event_type == PICOPAM_EVENT_P_BOUND)
+ || (event_type == PICOPAM_EVENT_S_BOUND))
+ && (pam->e10_e12_e13_saw_word > 0)) {
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->e10_e12_e13_word = 1;
+ else
+ pam->e10_e12_e13_word++;
+ pam->e10_e12_e13_state = 1;
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E10]
+ = pam->e10_e12_e13_word;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
+ = PICOPAM_DONT_CARE_VALUE;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
+ = PICOPAM_DONT_CARE_VALUE;
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND)
+ || (event_type == PICOPAM_EVENT_S_BOUND))
+ pam->e10_e12_e13_word++;
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->e10_e12_e13_word = 1;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ break;
+
+ case E11:/*processor for E11 : done in E9*/
+ break;
+ case E12:/*processor for E12 : done in E10*/
+ break;
+ case E13:/*processor for E13 : done in E10*/
+ break;
+
+ case F2:
+ switch (direction) {
+ case PICOPAM_DIR_FORW:/*do nothing*/
+ break;
+ case PICOPAM_DIR_BACK:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->f2_current_primary_phrase_word >= 1)/*at least second word in current primary phrase*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[F2]
+ = pam->f2_next_word_syllable;
+ else
+ /*first word in current primary phrase*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[F2] = 0;
+ pam->f2_word_syllable++;
+ }
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND)) {/*word - end : switch*/
+ pam->f2_next_word_syllable = pam->f2_word_syllable;
+ pam->f2_word_syllable = 0;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND)/*mark first word in current primary phrase*/
+ pam->f2_current_primary_phrase_word = 0;
+ else /*mark next word in current primary phrase(enables output in PICOPAM_EVENT_SYLL)*/
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND))
+ pam->f2_current_primary_phrase_word++;
+ break;
+ }
+ break;
+ case G1:
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->g1_current_secondary_phrase_syllable > 0)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[G1]
+ = pam->g1_current_secondary_phrase_syllable;
+ else
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[G1] = 0;
+ pam->g1_current_syllable++;
+ }
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->g1_current_secondary_phrase_syllable
+ = pam->g1_current_syllable;
+ pam->g1_current_syllable = 0;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->g1_current_secondary_phrase_syllable = 0;
+ pam->g1_current_syllable = 0;
+ }
+ case PICOPAM_DIR_BACK: /*do nothing*/
+ break;
+ }
+ break;
+ case G2:
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->g2_current_secondary_phrase_word > 0)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[G2]
+ = pam->g2_current_secondary_phrase_word;
+ else
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[G2] = 0;
+ }
+ if (event_type == PICOPAM_EVENT_W_BOUND)
+ pam->g2_current_word++;
+
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->g2_current_secondary_phrase_word
+ = pam->g2_current_word + 1;
+ pam->g2_current_word = 0;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->g2_current_secondary_phrase_word = 0;
+ pam->g2_current_word = 0;
+ }
+ break;
+ case PICOPAM_DIR_BACK: /*do nothing*/
+ break;
+ }
+ break;
+ case H1:
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->h1_current_secondary_phrase_syll++;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1]
+ = pam->h1_current_secondary_phrase_syll;
+ }
+ if ((event_type == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND))
+ pam->h1_current_secondary_phrase_syll = 0;
+ break;
+ case PICOPAM_DIR_BACK:
+ if (event_type == PICOPAM_EVENT_SYLL)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1]
+ = pam->h1_current_secondary_phrase_syll;
+ if (event_type == PICOPAM_EVENT_S_BOUND)
+ pam->h1_current_secondary_phrase_syll
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1];
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->h1_current_secondary_phrase_syll
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H1];
+ break;
+ }
+ break;
+ case H2:
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
+ = pam->h2_current_secondary_phrase_word;
+ }
+ if (event_type == PICOPAM_EVENT_W_BOUND) {
+ pam->h2_current_secondary_phrase_word++;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
+ = pam->h2_current_secondary_phrase_word;
+ }
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
+ = pam->h2_current_secondary_phrase_word + 1;
+ pam->h2_current_secondary_phrase_word = 0;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ if (pam->nCurrSyllable > 1)
+ pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H2]
+ = pam->h2_current_secondary_phrase_word + 1;
+ pam->h2_current_secondary_phrase_word = 0;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ if (event_type == PICOPAM_EVENT_SYLL)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
+ = pam->h2_current_secondary_phrase_word;
+ if (event_type == PICOPAM_EVENT_S_BOUND)
+ pam->h2_current_secondary_phrase_word
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2];
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ pam->h2_current_secondary_phrase_word
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H2];
+ break;
+ }
+ break;
+ case H3:/*processor for H3,H4 unified */
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ sDest = H3;
+ break;
+ case PICOPAM_DIR_BACK:
+ sDest = H4;
+ break;
+ default:
+ sDest = H3;
+ break;
+ }
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
+ = pam->h3_h4_current_secondary_phrase_word;
+ }
+ if ((event_type == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND))
+ pam->h3_h4_current_secondary_phrase_word++;
+ break;
+ case H4: /*processor for H4 : already in H3*/
+ break;
+
+ case H5:/*processor for H5*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ break;
+ case PICOPAM_DIR_BACK:
+ switch (pam->h5_state) {
+ case 0:
+ if (event_type == PICOPAM_EVENT_SYLL)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5];
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->h5_state = 1;
+ }
+ break;
+ case 1:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5]
+ == PICOPAM_P)
+ && (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1]
+ == 0))
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5]
+ = PICOPAM_p;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->h5_state = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case I1:/*processor for I1*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->i1_secondary_phrase_syllable++;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1]
+ = pam->i1_secondary_phrase_syllable;
+ }
+ if ((event_type == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND))
+ pam->i1_secondary_phrase_syllable = 0;
+ break;
+ case PICOPAM_DIR_BACK:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1]
+ = pam->i1_next_secondary_phrase_syllable;
+ }
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->i1_next_secondary_phrase_syllable
+ = pam->i1_secondary_phrase_syllable;
+ pam->i1_secondary_phrase_syllable
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1];
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->i1_next_secondary_phrase_syllable = 0;
+ pam->i1_secondary_phrase_syllable
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[I1];
+ }
+ break;
+ }
+ break;
+ case I2: /*processor for I2*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2]
+ = pam->i2_secondary_phrase_word;
+ }
+ if (event_type == PICOPAM_EVENT_W_BOUND)
+ pam->i2_secondary_phrase_word++;
+
+ if ((event_type == PICOPAM_EVENT_P_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND))
+ pam->i2_secondary_phrase_word = 1;
+
+ break;
+ case PICOPAM_DIR_BACK:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2]
+ = pam->i2_next_secondary_phrase_word;
+ }
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->i2_next_secondary_phrase_word
+ = pam->i2_secondary_phrase_word;
+ pam->i2_secondary_phrase_word
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2];
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->i2_next_secondary_phrase_word = 0;
+ pam->i2_secondary_phrase_word
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[I2];
+ }
+ break;
+ }
+ break;
+ case J1: /*processor for J1 */
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_SYLL) {
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1] != 1)
+ pam->j1_utterance_syllable++;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[J1]
+ = pam->j1_utterance_syllable;
+ break;
+ }
+ break;
+ case J2: /*processor for J2*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
+ == PICOPAM_EVENT_S_BOUND) || (event_type
+ == PICOPAM_EVENT_P_BOUND))
+ pam->j2_utterance_word++;
+ break;
+ case PICOPAM_DIR_BACK:
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[J2]
+ = pam->j2_utterance_word - 1;
+ break;
+ }
+ break;
+ case J3: /*processor for J3*/
+ switch (direction) {
+ case PICOPAM_DIR_FORW:
+ if (event_type == PICOPAM_EVENT_S_BOUND) {
+ pam->j3_utterance_sec_phrases++;
+ break;
+ }
+ if (event_type == PICOPAM_EVENT_P_BOUND) {
+ pam->j3_utterance_sec_phrases++;
+ break;
+ }
+ break;
+ case PICOPAM_DIR_BACK:
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[J3]
+ = pam->j3_utterance_sec_phrases - 1;
+ break;
+ }
+ break;
+ }
+ return PICO_OK;
+}/*pam_process_event_feature*/
+
+/**
+ * processes an input event spanning it to all column features
+ * @param this : pointer to PAM PU sub object pointer
+ * @param event_type : event id among syll/boundprim/boundsec/boundword
+ * @param direction : forward(0)/backward(1)
+ * @return PICO_OK : process OK
+ * @return PICO_ERR_OTHER : errors on getting pam sub obj pointer
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_process_event(register picodata_ProcessingUnit this,
+ picoos_uint8 event_type, picoos_uint8 direction)
+{
+ picoos_uint8 nFeat;
+ pico_status_t nResult;
+
+ pam_subobj_t *pam;
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ if (direction == PICOPAM_DIR_FORW) {
+ if (event_type == PICOPAM_EVENT_P_BOUND)
+ /*primary boundary*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P2] = 1;
+ if (event_type == PICOPAM_EVENT_S_BOUND)
+ /*secondary boundary*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P3] = 1;
+ if (event_type == PICOPAM_EVENT_W_BOUND)
+ /*word boundary*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P4] = 1;
+ }
+ for (nFeat = A3; nFeat <= J3; nFeat++) {
+ nResult = pam_process_event_feature(this, nFeat, event_type, direction);
+ if (nResult != PICO_OK)
+ return nResult;
+ }
+ return PICO_OK;
+}/*pam_process_event*/
+
+/**
+ * inserts a syllable inside the subobj sentence data struct.
+ * @param this : pointer to PAM PU sub object pointer
+ * @param syllType : the syllable type (pause/syllable)
+ * @param sContent : the item content
+ * @param sentType : the sentence type
+ * @param phType : the phrase type
+ * @param uBoundType : the boundary type (only for silence syllables)
+ * @param uMinDur, uMaxDur : the mimimum and maximum duration (only for silence syllables)
+ * @return PICO_OK : syllable creation successful
+ * @return PICO_ERR_OTHER : errors in one internal function (check_phones_size..)
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_create_syllable(register picodata_ProcessingUnit this,
+ picoos_uint8 syllType, picoos_uint8 *sContent, picoos_uint8 sentType,
+ picoos_uint8 phType, picoos_uint8 uBoundType, picoos_uint16 uMinDur,
+ picoos_uint16 uMaxDur)
+{
+ pam_subobj_t *pam;
+ picoos_uint8 nI;
+ picoos_uint8 pos;
+ /* picoos_uint8 *npUi16; */
+ picoos_uint32 pos32;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ pos = 0;
+ /*check buffer full condition on number of syllables*/
+ if (check_syllables_size(pam, 1) != PICO_OK) {
+ return PICO_ERR_OTHER;
+ }
+
+ if (syllType == PICOPAM_SYLL_PAUSE) {
+ /*check buffer full condition on number of phonemes*/
+ if (check_phones_size(pam, 1) != PICO_OK) {
+ return PICO_ERR_OTHER;
+ }
+ }
+ if (syllType == PICOPAM_SYLL_SYLL) {
+ /*check item availability*/
+ if (sContent == NULL) {
+ return PICO_ERR_OTHER;
+ }
+ /*check buffer full condition on number of phonemes*/
+ if (check_phones_size(pam, sContent[3]) != PICO_OK) {
+ return PICO_ERR_OTHER;
+ }
+ }
+
+ /*open new syllable*/
+ pam->nCurrSyllable = pam->nCurrSyllable + 1;
+ /*cleanup*/
+ for (nI = 0; nI < PICOPAM_VECT_SIZE; nI++) {
+ if (pam->nCurrSyllable > 0) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[nI] = 0;
+ } else {
+ if ((nI >= ITM) && (nI <= itm)) {
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[nI] > 0) {
+ /*do not cleanup "attached item offset" fields (ITM, itm):
+ an already existing attached item could be lost*/
+ } else {
+ /*cleanup "attached item offset"*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[nI] = 0;
+ }
+ } else {
+ /*cleanup all fields except "attached item offset" (ITM, itm)*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[nI] = 0;
+ }
+ }
+ }
+ /*set minimum and maximum duration values*/
+ if ((uMinDur == 0) && (uMaxDur == 0) && (syllType == PICOPAM_SYLL_PAUSE)) {
+ /*both 0 : use default duration limits for boundaries*/
+ get_default_boundary_limit(uBoundType, &uMinDur, &uMaxDur);
+ }
+ if (uMinDur > 0) {
+ pos32 = Min;
+ picoos_write_mem_pi_uint16(pam->sSyllFeats[pam->nCurrSyllable].phoneV,
+ &pos32, uMinDur);
+ }
+ if (uMaxDur > 0) {
+ pos32 = Max;
+ picoos_write_mem_pi_uint16(pam->sSyllFeats[pam->nCurrSyllable].phoneV,
+ &pos32, uMaxDur);
+ }
+ /*END OF BREAK COMMAND SUPPORT*/
+
+ if (syllType == PICOPAM_SYLL_PAUSE) {
+ /*initialize a pause syllable*/
+ if (sentType == PICOPAM_DECLARATIVE)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
+ = PICOPAM_DECLARATIVE;
+ if (sentType == PICOPAM_INTERROGATIVE)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
+ = PICOPAM_INTERROGATIVE;
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[bnd] = uBoundType;
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1] = 1; /*this means the syllable contains a pause-silence*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P8] = 1;
+
+ /*b1,b2,b9,b11,b13,b15,e1,e6,e8,e10 already set to 0*/
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B4]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B5]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B6]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B7]
+ = 1;
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B16]
+ = PICOPAM_PH_DONT_CARE_VAL; /*name of the vowel in the syllable = NONE */
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E2]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E3]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E4] = 1;
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5] = phType;
+
+ /*Store current phonetic codes in input phonetic string*/
+ pam->sPhIds[pam->nCurrPhoneme] = pam_get_pause_id(this);
+ picoos_mem_copy((void*) &pam->nCurrPhoneme,
+ &(pam->sSyllFeats[pam->nCurrSyllable].phoneV[FID]),
+ sizeof(pam->nCurrPhoneme));
+ pam->nCurrPhoneme++;
+ pam->nTotalPhonemes++;
+ /*add 1 to total number of syllables*/
+ pam->nTotalSyllables++;
+
+ return PICO_OK;
+ }
+ if (syllType == PICOPAM_SYLL_SYLL) {
+ /*initialize a real syllable*/
+ if (sContent[2] > PICODATA_ACC0)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] = 1; /*set content syllable indicator*/
+ if (sentType == PICOPAM_DECLARATIVE)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
+ = PICOPAM_DECLARATIVE;
+ if (sentType == PICOPAM_INTERROGATIVE)
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
+ = PICOPAM_INTERROGATIVE;
+
+ if ((sContent[2] >= PICODATA_ACC1) && (sContent[2] <= PICODATA_ACC4))
+ /*stressed*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] = 1;
+
+ if ((sContent[2] >= PICODATA_ACC1) && (sContent[2] <= PICODATA_ACC2))
+ /*accented*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] = 1;
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3] = sContent[3];/*len*/
+
+ if (pam->nCurrSyllable > 30)
+ pam->nCurrSyllable = pam->nCurrSyllable;
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B16] = pam_get_vowel_name(this,
+ sContent, &pos); /*name of the vowel in the syllable*/
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[P8] = pos; /*temp for storing the position of the vowel*/
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5] = phType;
+
+ /*Store current phonetic codes in input phonetic string*/
+ picoos_mem_copy((void*) &pam->nCurrPhoneme,
+ &(pam->sSyllFeats[pam->nCurrSyllable].phoneV[FID]),
+ sizeof(pam->nCurrPhoneme));
+ for (nI = 0; nI < sContent[3]; nI++)
+ pam->sPhIds[pam->nCurrPhoneme + nI] = sContent[4 + nI];
+ pam->nCurrPhoneme += nI;
+ pam->nTotalPhonemes += nI;
+ /*add 1 to total number of syllables*/
+ pam->nTotalSyllables++;
+ return PICO_OK;
+ }
+ /*if no SyllType has been identified -->> error*/
+ return PICO_ERR_OTHER;
+}/*pam_create_syllable*/
+
+/**
+ * performs the forward step of the PAM adapter
+ * @param this : pointer to PAM PU sub object pointer
+ * @param itemBase : pointer to current item
+ * @return PICOPAM_READY : forward step ok, the sentence is complete
+ * @return PICOPAM_MORE : forward step ok, but more data needed to complete the sentence
+ * @return PICO_ERR_OTHER : errors in one internal function (CreateSyllable..)
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_adapter_forward_step(
+ register picodata_ProcessingUnit this, picoos_uint8 *itemBase)
+{
+ register pam_subobj_t * pam;
+ pico_status_t sResult;
+ picoos_uint16 uMinDur, uMaxDur;
+ picoos_uint32 nPos;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ uMinDur = uMaxDur = 0; /*default 0 : not initialized*/
+ switch (itemBase[0]) {
+ case PICODATA_ITEM_BOUND:
+ /*received a boundary item*/
+ switch (itemBase[1]) {
+ case PICODATA_ITEMINFO1_BOUND_SBEG:
+ case PICODATA_ITEMINFO1_BOUND_PHR1:
+#ifdef PAM_PHR2_WITH_PR1
+ case PICODATA_ITEMINFO1_BOUND_PHR2:
+#endif
+ case PICODATA_ITEMINFO1_BOUND_SEND:
+ case PICODATA_ITEMINFO1_BOUND_TERM:
+ if (itemBase[3] == 2 * sizeof(picoos_uint16)) {
+ /*only when the item len duration is equal to 2 int16 --> get the values*/
+ nPos = 4;
+ picoos_read_mem_pi_uint16(itemBase, &nPos, &uMinDur);
+ picoos_read_mem_pi_uint16(itemBase, &nPos, &uMaxDur);
+ }
+ break;
+ default:
+ break;
+ }
+ switch (itemBase[1]) {
+ case PICODATA_ITEMINFO1_BOUND_SBEG:
+ /* received a sentence init boundary */
+ pam_reset_processors(this); /*reset all processor variables*/
+ pam->sType
+ = pam_map_sentence_type(itemBase[1], itemBase[2]);
+ pam->pType = pam_map_phrase_type(itemBase[1], itemBase[2]);
+ /*create silence syll and process P_BOUND event*/
+ sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
+ pam->sType, pam->pType, itemBase[1], uMinDur,
+ uMaxDur);
+ if (sResult != PICO_OK)
+ return sResult;
+ sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
+ PICOPAM_DIR_FORW);
+ if (sResult != PICO_OK)
+ return sResult;
+ return PICOPAM_MORE;
+ break;
+
+ case PICODATA_ITEMINFO1_BOUND_PHR1:
+#ifdef PAM_PHR2_WITH_PR1
+ case PICODATA_ITEMINFO1_BOUND_PHR2:
+#endif
+ /*received a primary boundary*/
+ pam->sType
+ = pam_map_sentence_type(itemBase[1], itemBase[2]);
+ pam->pType = pam_map_phrase_type(itemBase[1], itemBase[2]);
+ /*create silence syll and process P_BOUND event*/
+ sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
+ pam->sType, pam->pType, itemBase[1], uMinDur,
+ uMaxDur);
+ if (sResult != PICO_OK)
+ return sResult;
+ sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
+ PICOPAM_DIR_FORW);
+ if (sResult != PICO_OK)
+ return sResult;
+ return PICOPAM_MORE;
+ break;
+
+#ifdef PAM_PHR2_WITH_PR3
+ case PICODATA_ITEMINFO1_BOUND_PHR2 :
+#endif
+ case PICODATA_ITEMINFO1_BOUND_PHR3:
+ /*received a secondary boundary*/
+ /*process S_BOUND event*/
+ sResult = pam_process_event(this, PICOPAM_EVENT_S_BOUND,
+ PICOPAM_DIR_FORW);
+ /*determine new sentence and Phrase types for following syllables*/
+ pam->sType
+ = pam_map_sentence_type(itemBase[1], itemBase[2]);
+ pam->pType = pam_map_phrase_type(itemBase[1], itemBase[2]);
+ if (sResult != PICO_OK)
+ return sResult;
+ return PICOPAM_MORE;
+ break;
+
+ case PICODATA_ITEMINFO1_BOUND_PHR0:
+ /*received a word end boundary*/
+ /*process W_BOUND event*/
+ sResult = pam_process_event(this, PICOPAM_EVENT_W_BOUND,
+ PICOPAM_DIR_FORW);
+ if (sResult != PICO_OK)
+ return sResult;
+ return PICOPAM_MORE;
+ break;
+
+ case PICODATA_ITEMINFO1_BOUND_SEND:
+ /*received a SEND boundary*/
+ /*insert a new silence syllable and process P_BOUND event*/
+ /*create silence syll and process P_BOUND event*/
+ sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
+ pam->sType, pam->pType, itemBase[1], uMinDur,
+ uMaxDur);
+ if (sResult != PICO_OK)
+ return sResult;
+ sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
+ PICOPAM_DIR_FORW);
+ if (sResult != PICO_OK)
+ return sResult;
+ return PICOPAM_READY;
+ break;
+
+ case PICODATA_ITEMINFO1_BOUND_TERM:
+ /* received a flush boundary*/
+ if (pam->nCurrSyllable == -1) {
+ return PICOPAM_NA;
+ }
+ /*insert a new silence syllable and process P_BOUND event*/
+ /*create silence syll and process P_BOUND event*/
+ sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
+ pam->sType, pam->pType, itemBase[1], uMinDur,
+ uMaxDur);
+ if (sResult != PICO_OK)
+ return sResult;
+ sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
+ PICOPAM_DIR_FORW);
+ if (sResult != PICO_OK)
+ return sResult;
+ return PICOPAM_READY;
+ break;
+
+ default:
+ /*boundary type not known*/
+ return PICOPAM_NA;
+ break;
+ }/*end switch (itemBase[1])*/
+ break; /*end case PICODATA_ITEM_BOUND*/
+
+ case PICODATA_ITEM_SYLLPHON:
+ /*received a syllable item*/
+ /* ------------------------------------------------------------------
+ following code has to be used if we do expect
+ SYLL items arrive even without SBEG items starting the sentence.
+ this may happen after a term has been issued to make room in local storage.
+ */
+ if (pam->nCurrSyllable == -1) {
+ pam_reset_processors(this);
+ /*insert an SBEG with sType and pType taken from previous sentence*/
+ sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
+ pam->sType, pam->pType, PICODATA_ITEMINFO1_BOUND_SBEG,
+ 0, 0);
+ if (sResult != PICO_OK)
+ return sResult;
+ sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
+ PICOPAM_DIR_FORW);
+ if (sResult != PICO_OK)
+ return sResult;
+ }
+ /* ------------------------------------------------------------------*/
+ sResult = pam_create_syllable(this, PICOPAM_SYLL_SYLL, itemBase,
+ pam->sType, pam->pType, 0, 0, 0);
+ if (sResult != PICO_OK)
+ return sResult;
+ sResult = pam_process_event(this, PICOPAM_EVENT_SYLL,
+ PICOPAM_DIR_FORW);
+ if (sResult != PICO_OK)
+ return sResult;
+ return PICOPAM_MORE;
+ break;
+
+ default:
+ return PICOPAM_NA;
+ break;
+ }
+ return PICO_ERR_OTHER;
+}/*pam_adapter_forward_step*/
+
+/**
+ * performs the backward step of the PAM adapter
+ * @param this : pointer to PAM PU sub object pointer
+ * @return PICO_OK : backward step complete
+ * @return PICO_ERR_OTHER : errors on retrieving the PU pointer
+ * @remarks derived in some parts from the pam forward code
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_adapter_backward_step(
+ register picodata_ProcessingUnit this)
+{
+ register pam_subobj_t * pam;
+ picoos_uint8 nProcessed;
+ picoos_uint16 nSyll;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ /*Resets the processors for the backward step*/
+ pam_reset_processors_back(this);
+ /*Do the backward step*/
+ nSyll = pam->nCurrSyllable;
+ while (pam->nCurrSyllable >= 0) {
+ nProcessed = 0;
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P2] == 1) {
+ /*primary boundary*/
+ pam_process_event(this, PICOPAM_EVENT_P_BOUND, PICOPAM_DIR_BACK);
+ pam->nCurrSyllable--;
+ nProcessed = 1;
+ }
+ if ((nProcessed == 0)
+ && (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P3] == 1)) {
+ /*secondary boundary*/
+ pam_process_event(this, PICOPAM_EVENT_S_BOUND, PICOPAM_DIR_BACK);
+ pam_process_event(this, PICOPAM_EVENT_SYLL, PICOPAM_DIR_BACK);
+ pam->nCurrSyllable--;
+ nProcessed = 1;
+ }
+ if ((nProcessed == 0)
+ && (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P4] == 1)) {
+ /*word boundary*/
+ pam_process_event(this, PICOPAM_EVENT_W_BOUND, PICOPAM_DIR_BACK);
+ pam_process_event(this, PICOPAM_EVENT_SYLL, PICOPAM_DIR_BACK);
+ pam->nCurrSyllable--;
+ nProcessed = 1;
+ }
+ if (nProcessed == 0) {
+ /*non boundaried syllable*/
+ pam_process_event(this, PICOPAM_EVENT_SYLL, PICOPAM_DIR_BACK);
+ pam->nCurrSyllable--;
+ nProcessed = 0;
+ }
+ }/*end while (pam->nCurrSyllable>=0)*/
+ /*reset syllpointer to original value*/
+ pam->nCurrSyllable = nSyll;
+ /*Perform pause processing*/
+ pam_adapter_do_pauses(this);
+ pam->nCurrSyllable = 0;
+ pam->nSyllPhoneme = 0;
+
+ return PICO_OK;
+}/*pam_adapter_backward_step*/
+
+/**
+ * processes a pause (silence) syllable after backward processing
+ * @param this : pointer to PAM PU sub object pointer : processes a pause (silence) syllable after backward processing
+ * @return PICO_OK : backward step complete
+ * @return PICO_ERR_OTHER : errors on retrieving the PU pointer
+ * @remarks pam->nCurrSyllable should point to a pause item
+ * @remarks this function should be called after backward processing
+ * @remarks this function corresponds to initializing silence phonemes with
+ * @remarks values derived from previous or following syllables
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_do_pause(register picodata_ProcessingUnit this)
+{
+ picoos_uint16 syllCurr;
+ pam_subobj_t *pam;
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+ syllCurr = pam->nCurrSyllable;
+
+ /*processor for all features that can be inherited from previous syll (or word/phrase)*/
+ if (pam->nCurrSyllable > 0) {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B3];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B8]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B8];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B10]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B10];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B12]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B12];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B14]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B14];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B17]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B17];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B19]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B19];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B20];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B21];
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[D2]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E2];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[G1]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H1];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[G2]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H2];
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E5]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E5];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E7]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E7];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E9]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E9];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E11]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E11];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E12];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E13];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E13];
+
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H1];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H2];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H3]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H3];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H4]
+ = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H4];
+
+ } else {
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3]
+ =pam->sSyllFeats[pam->nCurrSyllable].phoneV[B8]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B10]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B12]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B14]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B17]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B19]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E5]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E9]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E11]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H3]
+ = 0;
+
+ /*init values different from 0*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H4]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[J3];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5] = PICOPAM_p;
+
+ }
+
+ /*processor for all features that can be inherited from next syll (or word/phrase)*/
+ if (pam->nCurrSyllable < pam->nTotalSyllables - 1) {
+ /*non last syllable*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3]
+ = pam->sSyllFeats[pam->nCurrSyllable + 1].phoneV[B3];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[F2]
+ = pam->sSyllFeats[pam->nCurrSyllable + 1].phoneV[E2];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1]
+ = pam->sSyllFeats[pam->nCurrSyllable + 1].phoneV[H1];
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2]
+ = pam->sSyllFeats[pam->nCurrSyllable + 1].phoneV[H2];
+ } else {
+ /*last syllable*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[F2]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1]
+ = pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2]
+ = 0;
+ }
+
+ /*Other fixed values derived from de-facto standard*/
+ pam->sSyllFeats[pam->nCurrSyllable].phoneV[B18] = 0;
+
+ return PICO_OK;
+}/*pam_do_pause*/
+
+/**
+ * performs the initialization of pause "syllables"
+ * @param this : pointer to PAM PU sub object pointer : processes a pause (silence) syllable after backward processing
+ * @return PICO_OK : pause processing successful
+ * @return PICO_ERR_OTHER : errors on retrieving the PU pointer
+ * @callgraph
+ * @callergraph
+ */
+static pico_status_t pam_adapter_do_pauses(register picodata_ProcessingUnit this)
+{
+ register pam_subobj_t * pam;
+ picoos_uint16 nSyll;
+
+ if (NULL == this || NULL == this->subObj) {
+ return PICO_ERR_OTHER;
+ }
+ pam = (pam_subobj_t *) this->subObj;
+
+ /*Do the pause processing*/
+ nSyll = pam->nCurrSyllable;
+ while (pam->nCurrSyllable >= 0) {
+ if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P2] == 1) {
+ /*pause processing*/
+ pam_do_pause(this);
+ }
+ pam->nCurrSyllable--;
+ }/*end while (pam->nCurrSyllable>=0)*/
+ /*reset syllpointer to original value*/
+ pam->nCurrSyllable = nSyll;
+ return PICOPAM_READY;
+}/*pam_adapter_do_pauses*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/* picopam.c end */