• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /**
17  * @file picopam.c
18  *
19  * Phonetic to Acoustic Mapping PU - Implementation
20  *
21  * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
22  * All rights reserved.
23  *
24  * History:
25  * - 2009-04-20 -- initial version
26  *
27  */
28 
29 #include "picodefs.h"
30 #include "picoos.h"
31 #include "picodbg.h"
32 #include "picodata.h"
33 #include "picopam.h"
34 #include "picokdt.h"
35 #include "picokpdf.h"
36 #include "picoktab.h"
37 #include "picokdbg.h"
38 #include "picodsp.h"
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 #if 0
44 }
45 #endif
46 
47 #define PICOPAM_IN_BUFF_SIZE PICODATA_BUFSIZE_PAM    /*input buffer size for PAM */
48 #define PICOPAM_OUT_PAM_SIZE PICODATA_BUFSIZE_PAM    /*output buffer size for PAM*/
49 #define PICOPAM_DT_NRLFZ    5    /* nr of lfz decision trees per phoneme */
50 #define PICOPAM_DT_NRMGC    5    /* nr of mgc decision trees per phoneme */
51 #define PICOPAM_NRSTPF      5    /* nr of states per phone */
52 
53 #define PICOPAM_COLLECT     0
54 #define PICOPAM_SCHEDULE    1
55 #define PICOPAM_IMMEDIATE   2
56 #define PICOPAM_FORWARD     3
57 #define PICOPAM_FORWARD_FORCE_TERM 4
58 #define PICOPAM_PROCESS     5
59 #define PICOPAM_PLAY        6
60 #define PICOPAM_FEED        7
61 
62 #define PICOPAM_CONTINUE       100
63 #define PICOPAM_GOTO_SCHEDULE  1
64 #define PICOPAM_FLUSH_RECEIVED 6
65 #define PICOPAM_GOTO_FEED      7
66 #define PICOPAM_PRE_SYLL_ENDED 10
67 
68 #define PICOPAM_BREAK_ADD_SIZE 4        /*syllable feature vector increment dued to BREAK and SILENCE*/
69 #define PICOPAM_VECT_SIZE 64+PICOPAM_BREAK_ADD_SIZE /*syllable feature vector size (bytes)*/
70 #define PICOPAM_INVEC_SIZE 60           /*phone feature vector size */
71 #define PICOPAM_MAX_SYLL_PER_SENT 100   /*maximum number of syllables per sentece*/
72 #define PICOPAM_MAX_PH_PER_SENT 400     /*maximum number of phonemes  per sentece*/
73 #define PICOPAM_MAX_ITEM_PER_SENT 255   /*maximum number of attached items per sentence*/
74 #define PICOPAM_MAX_ITEM_SIZE_PER_SENT 4096 /*maximum size of attached items per sentence*/
75 
76 #define PICOPAM_READY 20 /*PAM could start backward processing*/
77 #define PICOPAM_MORE  21 /*PAM has still to collect */
78 #define PICOPAM_NA    22 /*PAM has not to deal with this item*/
79 #define PICOPAM_ERR   23 /*input item is not a valid item*/
80 
81 /*sentence types:cfr pam_map_sentence_type*/
82 #define PICOPAM_DECLARATIVE   0
83 #define PICOPAM_INTERROGATIVE 1
84 #define PICOPAM_EXCLAMATIVE   2
85 
86 #define PICOPAM_T   0
87 #define PICOPAM_P   1
88 #define PICOPAM_p   2
89 #define PICOPAM_Y   3
90 
91 #if 1
92 #define PAM_PHR2_WITH_PR1 1 /*deal with PHR2 boundaries as with PHR1*/
93 #else
94 #define PAM_PHR2_WITH_PR3 1 /*deal with PHR2 boundaries as with PHR3*/
95 #endif
96 
97 #define PICOPAM_DONT_CARE_VALUE  250 /*don't care value for tree printout    */
98 #define PICOPAM_DONT_CARE_VAL    10  /*don't care value for tree feeding     */
99 #define PICOPAM_PH_DONT_CARE_VAL 7   /*don't care value for tree feeding (phonetic)*/
100 
101 #define PICOPAM_MAX_STATES_PER_PHONE 5 /*number of states per phone    */
102 #define PICOPAM_STATE_SIZE_IN_ITEM   6 /*size of a state in frame item */
103 #define PICOPAM_FRAME_ITEM_SIZE      4+PICOPAM_MAX_STATES_PER_PHONE*PICOPAM_STATE_SIZE_IN_ITEM
104 
105 #define PICOPAM_DIR_FORW 0 /*forward adapter processing*/
106 #define PICOPAM_DIR_BACK 1 /*backward adapter processing*/
107 #define PICOPAM_DIR_SIL  2 /*final silence attributes*/
108 
109 #define PICOPAM_SYLL_PAUSE  0 /*syllable but containing a pause phone*/
110 #define PICOPAM_SYLL_SYLL   1 /*a real syllable with phonemes*/
111 
112 #define PICOPAM_EVENT_P_BOUND 0 /*primary boundary*/
113 #define PICOPAM_EVENT_S_BOUND 1 /*secondary boundary*/
114 #define PICOPAM_EVENT_W_BOUND 3 /*word boundary*/
115 #define PICOPAM_EVENT_SYLL    4 /*syllable*/
116 
117 /* ----- CONSTANTS FOR BREAK COMMAND SUPPORT ----- */
118 #define PICOPAM_PWIDX_SBEG 0
119 #define PICOPAM_PWIDX_PHR1 1
120 #define PICOPAM_PWIDX_PHR2 2
121 #define PICOPAM_PWIDX_SEND 3
122 #define PICOPAM_PWIDX_DEFA 4
123 #define PICOPAM_PWIDX_SIZE 5
124 
125 /*----------------------------------------------------------------*/
126 /*structure related to the feature vectors for feeding the trees  */
127 /*NOTE : the same data structure is used to manage the syllables  */
128 /*       Using the first 8 fields for marking the boundaries      */
129 /*       and using the last 4 bytes as follows                    */
130 /*     byte 61 : 1st attached non PAM item id(0=no item attached) */
131 /*               in the "sSyllItemOffs" data structure            */
132 /*     byte 62 : last attached non PAM item id(0=no item attached)*/
133 /*               in the "sSyllItemOffs" data structure            */
134 /*     byte 63..64 : offset of the start of the syllable in       */
135 /*                   the "sPhIds" data structure                  */
136 typedef struct
137 {
138     picopal_uint8 phoneV[PICOPAM_VECT_SIZE];
139 } sFtVect, *pSftVect;
140 
141 /*----------------------------------------------------------
142  Name    :   pam_subobj
143  Function:   subobject definition for the pam processing
144  Shortcut:   pam
145  ---------------------------------------------------------*/
146 typedef struct pam_subobj
147 {
148     /*----------------------PU voice management------------------------------*/
149     /* picorsrc_Voice voice; */
150     /*----------------------PU state management------------------------------*/
151     picoos_uint8 procState; /* where to take up work at next processing step */
152     picoos_uint8 retState; /* where to go back from feed state at next p.s. */
153     picoos_uint8 needMoreInput; /* more data necessary to start processing   */
154     /*----------------------PU input management------------------------------*/
155     picoos_uint8 inBuf[PICOPAM_IN_BUFF_SIZE]; /* internal input buffer */
156     picoos_uint16 inBufSize; /* actually allocated size */
157     picoos_uint16 inReadPos, inWritePos; /* next pos to read/write from/to inBuf*/
158     /*----------------------PU output management-----------------------------*/
159     picoos_uint8 outBuf[PICOPAM_OUT_PAM_SIZE]; /* internal output buffer */
160     picoos_uint16 outBufSize; /* actually allocated size */
161     picoos_uint16 outReadPos, outWritePos; /* next pos to read/write from/to outBuf*/
162     /*---------------------- adapter working buffers    --------------------*/
163     picoos_uint8 *sPhFeats; /*feature vector for a single phone      */
164     sFtVect *sSyllFeats; /*Syllable feature vector set for the
165      full sentence                          */
166     picoos_uint8 *sPhIds; /*phone ids for the full sentence        */
167     picoos_uint8 *sSyllItems; /*items attached to the syllable         */
168     picoos_int16 *sSyllItemOffs;/*offset of items attached to the syllable*/
169     /*---------------------- adapter general variables ---------------------*/
170     picoos_int16 nTotalPhonemes; /*number of phonemes in the sentence*/
171     picoos_int16 nCurrPhoneme; /*current phoneme in the sentence   */
172     picoos_int16 nSyllPhoneme; /*current phoneme in the syllable   */
173     picoos_int16 nCurrSyllable; /*current syllable in the sentence  */
174     picoos_int16 nTotalSyllables; /*number of syllables in the sentence -> J1*/
175     picoos_uint8 nLastAttachedItemId;/*last attached item id*/
176     picoos_uint8 nCurrAttachedItem; /*current attached item*/
177     picoos_int16 nAttachedItemsSize; /*total size of the attached items*/
178     picoos_uint8 sType; /*Sentence type*/
179     picoos_uint8 pType; /*Phrase type*/
180     picoos_single pMod; /*pitch modifier*/
181     picoos_single dMod; /*Duration modifier*/
182     picoos_single dRest; /*Duration modifier rest*/
183     /*---------------------- adapter specific component variables ----------*/
184     picoos_uint8 a3_overall_syllable; /* A3 */
185     picoos_uint8 a3_primary_phrase_syllable;
186     picoos_uint8 b4_b5_syllable; /* B4,B5 */
187     picoos_uint8 b6_b7_syllable; /* B6,B7 */
188     picoos_uint8 b6_b7_state;
189     picoos_uint8 b8_b9_stressed_syllable; /* B8,B9 */
190     picoos_uint8 b10_b11_accented_syllable; /* B10,B11 */
191     picoos_uint8 b12_b13_syllable; /* B12,B13 */
192     picoos_uint8 b12_b13_state;
193     picoos_uint8 b14_b15_syllable; /* B14,B15 */
194     picoos_uint8 b14_b15_state;
195     picoos_uint8 b17_b19_syllable; /* B17,B19 */
196     picoos_uint8 b17_b19_state;
197     picoos_uint8 b18_b20_b21_syllable; /* B18,B20,B21 */
198     picoos_uint8 b18_b20_b21_state;
199     picoos_uint8 c3_overall_syllable; /* C3 */
200     picoos_uint8 c3_primary_phrase_syllable;
201     picoos_uint8 d2_syllable_in_word; /* D2 */
202     picoos_uint8 d2_prev_syllable_in_word;
203     picoos_uint8 d2_current_primary_phrase_word;
204     picoos_int8 e1_syllable_word_start; /* E1 */
205     picoos_int8 e1_syllable_word_end;
206     picoos_uint8 e1_content;
207     picoos_int8 e2_syllable_word_start; /* E2 */
208     picoos_int8 e2_syllable_word_end;
209     picoos_uint8 e3_e4_word; /* E3,E4 */
210     picoos_uint8 e3_e4_state;
211     picoos_uint8 e5_e6_content_word; /* E5,E6 */
212     picoos_uint8 e5_e6_content;
213     picoos_uint8 e7_e8_word; /* E7,E8 */
214     picoos_uint8 e7_e8_content;
215     picoos_uint8 e7_e8_state;
216     picoos_uint8 e9_e11_word; /* E9,E11 */
217     picoos_uint8 e9_e11_saw_word;
218     picoos_uint8 e9_e11_state;
219     picoos_uint8 e10_e12_e13_word; /* E10,E12,E13 */
220     picoos_uint8 e10_e12_e13_state;
221     picoos_uint8 e10_e12_e13_saw_word;
222     picoos_uint8 f2_overall_word; /* F2 */
223     picoos_uint8 f2_word_syllable;
224     picoos_uint8 f2_next_word_syllable;
225     picoos_uint8 f2_current_primary_phrase_word;
226     picoos_int8 g1_current_secondary_phrase_syllable; /*G1 */
227     picoos_int8 g1_current_syllable;
228     picoos_int8 g2_current_secondary_phrase_word; /*G2 */
229     picoos_int8 g2_current_word;
230     picoos_uint8 h1_current_secondary_phrase_syll; /*H1 */
231     picoos_uint8 h2_current_secondary_phrase_word; /*H2 */
232     picoos_uint8 h3_h4_current_secondary_phrase_word; /*H3,H4 */
233     picoos_uint8 h5_current_phrase_type; /*H5 */
234 
235     picoos_uint8 h5_syllable; /* H5 */
236     picoos_uint8 h5_state;
237 
238     picoos_uint8 i1_secondary_phrase_syllable; /*I1 */
239     picoos_uint8 i1_next_secondary_phrase_syllable;
240     picoos_uint8 i2_secondary_phrase_word; /*I2 */
241     picoos_uint8 i2_next_secondary_phrase_word;
242     picoos_uint8 j1_utterance_syllable; /*J1 */
243     picoos_uint8 j2_utterance_word; /*J2 */
244     picoos_uint8 j3_utterance_sec_phrases; /*J3 */
245     /*---------------------- constant data -------------------*/
246     picoos_uint16 sil_weights[PICOPAM_PWIDX_SIZE][PICOPAM_MAX_STATES_PER_PHONE];
247     /*---------------------- LINGWARE related data -------------------*/
248     picokdt_DtPAM dtdur; /* dtdur knowledge base */
249     picokdt_DtPAM dtlfz[PICOPAM_DT_NRLFZ]; /* dtlfz knowledge bases */
250     picokdt_DtPAM dtmgc[PICOPAM_DT_NRMGC]; /* dtmgc knowledge bases */
251     /*---------------------- Pdfs related data -------------------*/
252     picokpdf_PdfDUR pdfdur; /* pdfdur knowledge base */
253     picokpdf_PdfMUL pdflfz; /* pdflfz knowledge base */
254     /*---------------------- Tree traversal related data -------------------*/
255     picoos_uint16 durIndex;
256     picoos_uint8 numFramesState[PICOPAM_DT_NRLFZ];
257     picoos_uint16 lf0Index[PICOPAM_DT_NRLFZ];
258     picoos_uint16 mgcIndex[PICOPAM_DT_NRMGC];
259     /*---------------------- temps for updating the feature vector ---------*/
260     picoos_uint16 phonDur;
261     picoos_single phonF0[PICOPAM_DT_NRLFZ];
262     /*---------------------- Phones related data  -------------------*/
263     picoktab_Phones tabphones;
264 } pam_subobj_t;
265 
266 
267 /* ----- CONSTANTS FOR FEATURE VECTOR BUILDING (NOT PREFIXED WITH "PICOPAM_" FOR BREVITY) ----- */
268 #define  P1  0              /*field 1 of the input vector*/
269 #define  P2  1
270 #define  P3  2
271 #define  P4  3
272 #define  P5  4
273 #define  P6  5
274 #define  P7  6
275 #define  bnd 6              /*boundary type item associated to the syllable = P7 */
276 #define  P8  7
277 #define  A3  8
278 #define  B1  9
279 #define  B2  10
280 #define  B3  11
281 #define  B4  12
282 #define  B5  13
283 #define  B6  14
284 #define  B7  15
285 #define  B8  16
286 #define  B9  17
287 #define  B10 18
288 #define  B11 19
289 #define  B12 20
290 #define  B13 21
291 #define  B14 22
292 #define  B15 23
293 #define  B16 24
294 #define  B17 25
295 #define  B18 26
296 #define  B19 27
297 #define  B20 28
298 #define  B21 29
299 #define  C3  30
300 #define  D2  31
301 #define  E1  32
302 #define  E2  33
303 #define  E3  34
304 #define  E4  35
305 #define  E5  36
306 #define  E6  37
307 #define  E7  38
308 #define  E8  39
309 #define  E9  40
310 #define  E10 41
311 #define  E11 42
312 #define  E12 43
313 #define  E13 44
314 #define  F2  45
315 #define  G1  46
316 #define  G2  47
317 #define  H1  48
318 #define  H2  49
319 #define  H3  50
320 #define  H4  51
321 #define  H5  52
322 #define  I1  53
323 #define  I2  54
324 #define  J1  55
325 #define  J2  56
326 #define  J3  57
327 #define  DUR 58             /*duration component*/
328 #define  F0  59             /*F0 component*/
329 #define  ITM 60             /*Item Offset into sSyllItems item list*/
330 #define  itm 61             /*second byte of the Item Offset */
331 #define  FID 62             /*Phoneme offset in the sPhIds phoneme list*/
332 #define  fid 63             /*second byte of the Phoneme offset */
333 #define  Min 64             /*offset to min syllable duration (uint 16,pauses)*/
334 #define  Max 66             /*offset to max syllable duration (uint 16,pauses)*/
335 /* -------------------------------------------------------------------
336  PAM feature vector indices position changes,
337   ------------------------------------------------------------------- */
338 #define  T_B1  8
339 #define  T_B2  9
340 #define  T_B3  10
341 #define  T_B4  11
342 #define  T_B5  12
343 #define  T_B6  13
344 #define  T_B7  14
345 #define  T_B8  15
346 #define  T_B9  16
347 #define  T_B10 17
348 #define  T_B11 18
349 #define  T_B12 19
350 #define  T_B13 20
351 #define  T_B14 21
352 #define  T_B15 22
353 #define  T_B16 23
354 #define  T_B17 24
355 #define  T_B18 25
356 #define  T_B19 26
357 #define  T_B20 27
358 #define  T_B21 28
359 #define  T_E1  29
360 #define  T_E2  30
361 #define  T_E3  31
362 #define  T_E4  32
363 #define  T_E5  33
364 #define  T_E6  34
365 #define  T_E7  35
366 #define  T_E8  36
367 #define  T_E9  37
368 #define  T_E10 38
369 #define  T_E11 39
370 #define  T_E12 40
371 #define  T_E13 41
372 #define  T_A3  42
373 #define  T_C3  43
374 #define  T_D2  44
375 #define  T_F2  45
376 #define  T_G1  46
377 #define  T_I1  47
378 #define  T_G2  48
379 #define  T_I2  49
380 #define  T_H1  50
381 #define  T_H2  51
382 #define  T_H3  52
383 #define  T_H4  53
384 #define  T_H5  54
385 
386 /*------------------------------------------------------------------
387  Service routines :
388  ------------------------------------------------------------------*/
389 static pico_status_t pam_initialize(register picodata_ProcessingUnit this);
390 static pico_status_t pam_terminate(register picodata_ProcessingUnit this);
391 static pico_status_t pam_allocate(picoos_MemoryManager mm, pam_subobj_t *pam);
392 static void pam_deallocate(picoos_MemoryManager mm, pam_subobj_t *pam);
393 static pico_status_t pam_subobj_deallocate(register picodata_ProcessingUnit this,
394         picoos_MemoryManager mm);
395 /*------------------------------------------------------------------
396  Processing routines :
397  ------------------------------------------------------------------*/
398 static picodata_step_result_t pam_step(register picodata_ProcessingUnit this,
399         picoos_int16 mode, picoos_uint16 * numBytesOutput);
400 static pico_status_t pam_deal_with(const picoos_uint8 *item);
401 /*Utility*/
402 static picoos_uint8 pam_get_vowel_name(register picodata_ProcessingUnit this,
403         picoos_uint8 *item, picoos_uint8 *pos);
404 static picoos_uint8 pam_get_pause_id(register picodata_ProcessingUnit this);
405 
406 static picoos_uint8 pam_map_sentence_type(picoos_uint8 iteminfo1,
407         picoos_uint8 iteminfo2);
408 static picoos_uint8 pam_map_phrase_type(picoos_uint8 iteminfo1,
409         picoos_uint8 iteminfo2);
410 
411 /*Adapter*/
412 static pico_status_t pam_reset_processors(register picodata_ProcessingUnit this);
413 static pico_status_t pam_reset_processors_back(
414         register picodata_ProcessingUnit this);
415 static pico_status_t pam_create_syllable(register picodata_ProcessingUnit this,
416         picoos_uint8 syllType, picoos_uint8 *sContent, picoos_uint8 sentType,
417         picoos_uint8 phType, picoos_uint8 uBoundType, picoos_uint16 uMin,
418         picoos_uint16 uMax);
419 static pico_status_t pam_process_event_feature(
420         register picodata_ProcessingUnit this, picoos_uint8 nFeat,
421         picoos_uint8 event_type, picoos_uint8 direction);
422 static pico_status_t pam_process_event(register picodata_ProcessingUnit this,
423         picoos_uint8 event_type, picoos_uint8 direction);
424 static pico_status_t pam_adapter_forward_step(
425         register picodata_ProcessingUnit this, picoos_uint8 *itemBase);
426 static pico_status_t pam_adapter_backward_step(
427         register picodata_ProcessingUnit this);
428 static pico_status_t pam_do_pause(register picodata_ProcessingUnit this);
429 static pico_status_t pam_adapter_do_pauses(register picodata_ProcessingUnit this);
430 /*-------------- tree traversal ---------------------------------------*/
431 static pico_status_t pam_expand_vector(register picodata_ProcessingUnit this);
432 static picoos_uint8 pam_do_tree(register picodata_ProcessingUnit this,
433         const picokdt_DtPAM dtpam, const picoos_uint8 *invec,
434         const picoos_uint8 inveclen, picokdt_classify_result_t *dtres);
435 static pico_status_t pam_get_f0(register picodata_ProcessingUnit this,
436         picoos_uint16 *lf0Index, picoos_uint8 nState, picoos_single *phonF0);
437 static pico_status_t pam_get_duration(register picodata_ProcessingUnit this,
438         picoos_uint16 durIndex, picoos_uint16 *phonDur,
439         picoos_uint8 *numFramesState);
440 static pico_status_t pam_update_vector(register picodata_ProcessingUnit this);
441 /*-------------- FINAL ITEM FEEDING -----------------------------------------*/
442 static pico_status_t pam_put_item(register picodata_ProcessingUnit this,
443                 picoos_uint8 *outBuff, picoos_uint16 outWritePos,
444                 picoos_uint8 *bytesWr);
445 
446 static pico_status_t pam_put_term(picoos_uint8 *outBuff,
447         picoos_uint16 outWritePos, picoos_uint8 *bytesWr);
448 
449 static pico_status_t is_pam_command(const picoos_uint8 *qItem);
450 
451 static void get_default_boundary_limit(picoos_uint8 uBoundType,
452         picoos_uint16 *uMinDur, picoos_uint16 *uMaxDur);
453 
454 /* -------------------------------------------------------------
455  * Pico System functions
456  * -------------------------------------------------------------
457  */
458 
459 /**
460  * allocation for PAM memory on pam PU
461  * @param    mm : handle to engine memory manager
462  * @param    pam : handle to a pam struct
463  * @return  PICO_OK : allocation successful
464  * @return    PICO_ERR_OTHER : allocation errors
465  * @callgraph
466  * @callergraph
467  */
pam_allocate(picoos_MemoryManager mm,pam_subobj_t * pam)468 static pico_status_t pam_allocate(picoos_MemoryManager mm, pam_subobj_t *pam)
469 {
470     picoos_uint8 *data;
471     picoos_int16 *dataI;
472 
473     pam->sSyllFeats = NULL;
474     pam->sPhIds = NULL;
475     pam->sPhFeats = NULL;
476     pam->sSyllItems = NULL;
477     pam->sSyllItemOffs = NULL;
478 
479     /*-----------------------------------------------------------------
480      * PAM Local buffers ALLOCATION
481      ------------------------------------------------------------------*/
482     /*PAM Local buffers*/
483     data = (picopal_uint8 *) picoos_allocate(mm, sizeof(sFtVect)
484             * PICOPAM_MAX_SYLL_PER_SENT);
485     if (data == NULL)
486         return PICO_ERR_OTHER;
487     pam->sSyllFeats = (sFtVect*) data;
488 
489     data = (picopal_uint8 *) picoos_allocate(mm, sizeof(picopal_uint8)
490             * PICOPAM_MAX_PH_PER_SENT);
491     if (data == NULL) {
492         pam_deallocate(mm, pam);
493         return PICO_ERR_OTHER;
494     }
495     pam->sPhIds = (picopal_uint8*) data;
496 
497     data = (picopal_uint8 *) picoos_allocate(mm, sizeof(picopal_uint8)
498             * PICOPAM_VECT_SIZE);
499     if (data == NULL) {
500         pam_deallocate(mm, pam);
501         return PICO_ERR_OTHER;
502     }
503     pam->sPhFeats = (picopal_uint8*) data;
504 
505     data = (picopal_uint8 *) picoos_allocate(mm, sizeof(picopal_uint8)
506             * PICOPAM_MAX_ITEM_SIZE_PER_SENT);
507     if (data == NULL) {
508         pam_deallocate(mm, pam);
509         return PICO_ERR_OTHER;
510     }
511     pam->sSyllItems = (picopal_uint8*) data;
512 
513     dataI = (picoos_int16 *) picoos_allocate(mm, sizeof(picoos_int16)
514             * PICOPAM_MAX_ITEM_PER_SENT);
515     if (data == NULL) {
516         pam_deallocate(mm, pam);
517         return PICO_ERR_OTHER;
518     }
519     pam->sSyllItemOffs = (picoos_int16*) dataI;
520 
521     return PICO_OK;
522 }/*pam_allocate*/
523 
524 /**
525  * frees allocation for DSP memory on PAM PU
526  * @param    mm : memory manager
527  * @param    pam : pam PU internal sub-object
528  * @return   void
529  * @remarks  modified and inserted in sub obj removal PP 15.09.08
530  * @callgraph
531  * @callergraph
532  */
pam_deallocate(picoos_MemoryManager mm,pam_subobj_t * pam)533 static void pam_deallocate(picoos_MemoryManager mm, pam_subobj_t *pam)
534 {
535     /*-----------------------------------------------------------------
536      * Memory de-allocations
537      * ------------------------------------------------------------------*/
538     if (pam->sSyllFeats != NULL)
539         picoos_deallocate(mm, (void *) &pam->sSyllFeats);
540     if (pam->sPhIds != NULL)
541         picoos_deallocate(mm, (void *) &pam->sPhIds);
542     if (pam->sPhFeats != NULL)
543         picoos_deallocate(mm, (void *) &pam->sPhFeats);
544     if (pam->sSyllItems != NULL)
545         picoos_deallocate(mm, (void *) &pam->sSyllItems);
546     if (pam->sSyllItemOffs != NULL)
547         picoos_deallocate(mm, (void *) &pam->sSyllItemOffs);
548 
549 }/*pam_deallocate*/
550 
551 /**
552  * initialization of a pam PU
553  * @param    this : handle to a PU struct
554  * @return     PICO_OK : init OK
555  * @return    PICO_ERR_OTHER : error on getting pkbs addresses
556  * @callgraph
557  * @callergraph
558  */
pam_initialize(register picodata_ProcessingUnit this)559 static pico_status_t pam_initialize(register picodata_ProcessingUnit this)
560 {
561     pico_status_t nI, nJ;
562     pam_subobj_t *pam;
563 
564     if (NULL == this || NULL == this->subObj) {
565         return PICO_ERR_OTHER;
566     }
567     pam = (pam_subobj_t *) this->subObj;
568     pam->inBufSize = PICOPAM_IN_BUFF_SIZE;
569     pam->outBufSize = PICOPAM_OUT_PAM_SIZE;
570     pam->inReadPos = 0;
571     pam->inWritePos = 0;
572     pam->outReadPos = 0;
573     pam->outWritePos = 0;
574     pam->needMoreInput = 0;
575     pam->procState = 0;
576 
577     /*-----------------------------------------------------------------
578      * MANAGE INTERNAL INITIALIZATION
579      ------------------------------------------------------------------*/
580     /*init the syllable structure*/
581     for (nI = 0; nI < PICOPAM_MAX_SYLL_PER_SENT; nI++)
582         for (nJ = 0; nJ < PICOPAM_VECT_SIZE; nJ++)
583             pam->sSyllFeats[nI].phoneV[nJ] = 0;
584 
585     for (nI = 0; nI < PICOPAM_MAX_PH_PER_SENT; nI++)
586         pam->sPhIds[nI] = 0;
587 
588     for (nI = 0; nI < PICOPAM_VECT_SIZE; nI++)
589         pam->sPhFeats[nI] = 0;
590 
591     for (nI = 0; nI < PICOPAM_MAX_ITEM_SIZE_PER_SENT; nI++)
592         pam->sSyllItems[nI] = 0;
593 
594     for (nI = 0; nI < PICOPAM_MAX_ITEM_PER_SENT; nI++)
595         pam->sSyllItemOffs[nI] = 0;
596 
597     /*Other variables*/
598     pam_reset_processors(this);
599     pam->nLastAttachedItemId = pam->nCurrAttachedItem = 0;
600     pam->nAttachedItemsSize = 0;
601 
602     /*pitch and duration modifiers*/
603     pam->pMod = 1.0f;
604     pam->dMod = 1.0f;
605     pam->dRest = 0.0f;
606 
607 
608     /* constant tables */
609     {
610         picoos_uint8 i, j;
611         picoos_uint16 tmp_weights[PICOPAM_PWIDX_SIZE][PICOPAM_MAX_STATES_PER_PHONE] = {
612         {10, 10, 10, 10, 1 }, /*SBEG*/
613         { 1, 4, 8, 4, 1 }, /*PHR1*/
614         { 1, 4, 8, 4, 1 }, /*PHR2*/
615         { 1, 10, 10, 10, 10 },/*SEND*/
616         { 1, 1, 1, 1, 1 } /*DEFAULT*/
617         };
618         for (i = 0; i < PICOPAM_PWIDX_SIZE; i++) {
619             for (j = 0; j < PICOPAM_PWIDX_SIZE; j++) {
620                 pam->sil_weights[j][j] = tmp_weights[i][j];
621             }
622         }
623     }
624 /*-----------------------------------------------------------------
625      * MANAGE LINGWARE INITIALIZATION IF NEEDED
626      ------------------------------------------------------------------*/
627     /* kb dtdur */
628     pam->dtdur = picokdt_getDtPAM(this->voice->kbArray[PICOKNOW_KBID_DT_DUR]);
629     if (pam->dtdur == NULL) {
630         picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING, NULL,
631                 NULL);
632         return PICO_ERR_OTHER;
633     }PICODBG_DEBUG(("got dtdur"));
634 
635     /* kb dtlfz* */
636     pam->dtlfz[0] = picokdt_getDtPAM(
637             this->voice->kbArray[PICOKNOW_KBID_DT_LFZ1]);
638     pam->dtlfz[1] = picokdt_getDtPAM(
639             this->voice->kbArray[PICOKNOW_KBID_DT_LFZ2]);
640     pam->dtlfz[2] = picokdt_getDtPAM(
641             this->voice->kbArray[PICOKNOW_KBID_DT_LFZ3]);
642     pam->dtlfz[3] = picokdt_getDtPAM(
643             this->voice->kbArray[PICOKNOW_KBID_DT_LFZ4]);
644     pam->dtlfz[4] = picokdt_getDtPAM(
645             this->voice->kbArray[PICOKNOW_KBID_DT_LFZ5]);
646     for (nI = 0; nI < PICOPAM_DT_NRLFZ; nI++) {
647         if (pam->dtlfz[nI] == NULL) {
648             picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
649                     NULL, NULL);
650             return PICO_ERR_OTHER;
651         }PICODBG_DEBUG(("got dtlfz%d", nI+1));
652     }
653 
654     /* kb dtmgc* */
655     pam->dtmgc[0] = picokdt_getDtPAM(
656             this->voice->kbArray[PICOKNOW_KBID_DT_MGC1]);
657     pam->dtmgc[1] = picokdt_getDtPAM(
658             this->voice->kbArray[PICOKNOW_KBID_DT_MGC2]);
659     pam->dtmgc[2] = picokdt_getDtPAM(
660             this->voice->kbArray[PICOKNOW_KBID_DT_MGC3]);
661     pam->dtmgc[3] = picokdt_getDtPAM(
662             this->voice->kbArray[PICOKNOW_KBID_DT_MGC4]);
663     pam->dtmgc[4] = picokdt_getDtPAM(
664             this->voice->kbArray[PICOKNOW_KBID_DT_MGC5]);
665     for (nI = 0; nI < PICOPAM_DT_NRMGC; nI++) {
666         if (pam->dtmgc[nI] == NULL) {
667             picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING,
668                     NULL, NULL);
669             return PICO_ERR_OTHER;
670         }PICODBG_DEBUG(("got dtmgc%d", nI+1));
671     }
672 
673     /* kb pdfdur* */
674     pam->pdfdur = picokpdf_getPdfDUR(
675             this->voice->kbArray[PICOKNOW_KBID_PDF_DUR]);
676     if (pam->pdfdur == NULL) {
677         picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING, NULL,
678                 NULL);
679         return PICO_ERR_OTHER;
680     }PICODBG_DEBUG(("got pdfdur"));
681 
682     /* kb pdflfz* */
683     pam->pdflfz = picokpdf_getPdfMUL(
684             this->voice->kbArray[PICOKNOW_KBID_PDF_LFZ]);
685     if (pam->pdflfz == NULL) {
686         picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING, NULL,
687                 NULL);
688         return PICO_ERR_OTHER;
689     }PICODBG_DEBUG(("got pdflfz"));
690 
691     /* kb tabphones */
692     pam->tabphones = picoktab_getPhones(
693             this->voice->kbArray[PICOKNOW_KBID_TAB_PHONES]);
694     if (pam->tabphones == NULL) {
695         picoos_emRaiseException(this->common->em, PICO_EXC_KB_MISSING, NULL,
696                 NULL);
697         return PICO_ERR_OTHER;
698     }PICODBG_DEBUG(("got tabphones"));
699 
700     return PICO_OK;
701 }/*pam_initialize*/
702 
703 /**
704  * termination of a pam PU
705  * @param    this : handle to a pam PU struct
706  * @return PICO_OK
707  * @callgraph
708  * @callergraph
709  */
pam_terminate(register picodata_ProcessingUnit this)710 static pico_status_t pam_terminate(register picodata_ProcessingUnit this)
711 {
712 
713     pam_subobj_t *pam;
714 
715     if (NULL == this || NULL == this->subObj) {
716         return PICO_ERR_OTHER;
717     }
718     pam = (pam_subobj_t *) this->subObj;
719 
720     return PICO_OK;
721 }/*pam_terminate*/
722 
723 /**
724  * deallocaton of a pam PU
725  * @param    this : handle to a pam PU struct
726  * @param    mm : engine memory manager
727  * @return  PICO_OK
728  * @callgraph
729  * @callergraph
730  */
pam_subobj_deallocate(register picodata_ProcessingUnit this,picoos_MemoryManager mm)731 static pico_status_t pam_subobj_deallocate(register picodata_ProcessingUnit this,
732         picoos_MemoryManager mm)
733 {
734 
735     pam_subobj_t* pam;
736 
737     if (NULL != this) {
738         pam = (pam_subobj_t *) this->subObj;
739         mm = mm; /* avoid warning "var not used in this function"*/
740         /*-----------------------------------------------------------------
741          * Memory de-allocations
742          * ------------------------------------------------------------------*/
743         if (pam->sSyllFeats != NULL) {
744             picoos_deallocate(this->common->mm, (void *) &pam->sSyllFeats);
745         }
746         if (pam->sPhIds != NULL) {
747             picoos_deallocate(this->common->mm, (void *) &pam->sPhIds);
748         }
749         if (pam->sPhFeats != NULL) {
750             picoos_deallocate(this->common->mm, (void *) &pam->sPhFeats);
751         }
752         if (pam->sSyllItems != NULL) {
753             picoos_deallocate(this->common->mm, (void *) &pam->sSyllItems);
754         }
755         if (pam->sSyllItemOffs != NULL) {
756             picoos_deallocate(this->common->mm, (void *) &pam->sSyllItemOffs);
757         }
758         picoos_deallocate(this->common->mm, (void *) &this->subObj);
759     }
760 
761     return PICO_OK;
762 }/*pam_subobj_deallocate*/
763 
764 /**
765  * creates a new pam processing unit
766  * @param    mm    : engine memory manager
767  * @param    common : engine common object pointer
768  * @param    cbIn : pointer to input buffer
769  * @param    cbOut : pointer to output buffer
770  * @param    voice : pointer to voice structure
771  * @return this : pam PU handle if success
772  * @return    NULL : if error
773  * @callgraph
774  * @callergraph
775  */
picopam_newPamUnit(picoos_MemoryManager mm,picoos_Common common,picodata_CharBuffer cbIn,picodata_CharBuffer cbOut,picorsrc_Voice voice)776 picodata_ProcessingUnit picopam_newPamUnit(picoos_MemoryManager mm,
777         picoos_Common common, picodata_CharBuffer cbIn,
778         picodata_CharBuffer cbOut, picorsrc_Voice voice)
779 {
780 
781     register pam_subobj_t * pam;
782 
783     picodata_ProcessingUnit this = picodata_newProcessingUnit(mm, common, cbIn,
784             cbOut, voice);
785     if (this == NULL) {
786         return NULL;
787     }
788     this->initialize = pam_initialize;
789 
790     PICODBG_DEBUG(("picotok_newPamUnit -- set this->step to pam_step"));
791 
792     this->step = pam_step;
793     this->terminate = pam_terminate;
794     this->subDeallocate = pam_subobj_deallocate;
795     this->subObj = picoos_allocate(mm, sizeof(pam_subobj_t));
796     if (this->subObj == NULL) {
797         PICODBG_ERROR(("Error in Pam Object allocation"));
798         picoos_deallocate(mm, (void*) &this);
799         return NULL;
800     };
801 
802     /*-----------------------------------------------------------------
803      * Allocate internal memory for PAM (only at PU creation time)
804      * ------------------------------------------------------------------*/
805     pam = (pam_subobj_t *) this->subObj;
806     if (PICO_OK != pam_allocate(mm, pam)) {
807         PICODBG_ERROR(("Error in Pam buffers Allocation"));
808         picoos_deallocate(mm, (void *) &this->subObj);
809         picoos_deallocate(mm, (void *) &this);
810         return NULL;
811     }
812 
813     /*-----------------------------------------------------------------
814      * Initialize memory for PAM (this may be re-used elsewhere, e.g.Reset)
815      * ------------------------------------------------------------------*/
816     if (PICO_OK != pam_initialize(this)) {
817         PICODBG_ERROR(("problem initializing the pam sub-object"));
818     }
819     return this;
820 }/*picopam_newPamUnit*/
821 
822 /*-------------------------------------------------------------------------------
823  PROCESSING AND INTERNAL FUNCTIONS
824  --------------------------------------------------------------------------------*/
825 
826 /**
827  * initializes default duration limits for boundary items
828  * @param    uBoundType : type of input boundary type
829  * @param    *uMinDur, *uMaxDur : addresses of values to initialize
830  * @return  void
831  * @remarks    so far initializes to 0 both values; this will leave the values given by tree prediction
832  * @callgraph
833  * @callergraph
834  */
get_default_boundary_limit(picoos_uint8 uBoundType,picoos_uint16 * uMinDur,picoos_uint16 * uMaxDur)835 static void get_default_boundary_limit(picoos_uint8 uBoundType,
836         picoos_uint16 *uMinDur, picoos_uint16 *uMaxDur)
837 {
838     switch (uBoundType) {
839         case PICODATA_ITEMINFO1_BOUND_SBEG:
840             *uMinDur = 0;
841             *uMaxDur = 20;
842             break;
843         case PICODATA_ITEMINFO1_BOUND_SEND:
844             *uMinDur = 550;
845             *uMaxDur = 650;
846             break;
847         case PICODATA_ITEMINFO1_BOUND_TERM:
848             *uMinDur = 0;
849             *uMaxDur = 0;
850             break;
851         case PICODATA_ITEMINFO1_BOUND_PHR0:
852             *uMinDur = 0;
853             *uMaxDur = 0;
854             break;
855         case PICODATA_ITEMINFO1_BOUND_PHR1:
856             *uMinDur = 275;
857             *uMaxDur = 325;
858             break;
859         case PICODATA_ITEMINFO1_BOUND_PHR2:
860             *uMinDur = 4;
861             *uMaxDur = 60;
862             break;
863         case PICODATA_ITEMINFO1_BOUND_PHR3:
864             *uMinDur = 0;
865             *uMaxDur = 0;
866             break;
867         default:
868             break;
869     }
870 
871 }/*get_default_boundary_limit*/
872 
873 /**
874  * checks if "neededSize" is available on "nCurrPhoneme"
875  * @param    pam : pam subobj
876  * @param    neededSize : the requested size
877  * @return    PICO_OK : size is available
878  * @return    !=PICO_OK : size not available
879  * @callgraph
880  * @callergraph
881  */
check_phones_size(pam_subobj_t * pam,picoos_int16 neededSize)882 static pico_status_t check_phones_size(pam_subobj_t *pam,
883         picoos_int16 neededSize)
884 {
885     if ((pam->nCurrPhoneme + neededSize) > PICOPAM_MAX_PH_PER_SENT - 1) {
886         return PICO_ERR_OTHER;
887     }
888     return PICO_OK;
889 }/*check_phones_size*/
890 
891 /**
892  * checks if neededSize is available on "nCurrSyllable"
893  * @param    pam : pam subobj
894  * @param    neededSize : the requested size
895  * @return    PICO_OK : size is available
896  * @return    !=PICO_OK : size not available
897  * @callgraph
898  * @callergraph
899  */
check_syllables_size(pam_subobj_t * pam,picoos_int16 neededSize)900 static pico_status_t check_syllables_size(pam_subobj_t *pam,
901         picoos_int16 neededSize)
902 {
903     if ((pam->nCurrSyllable + neededSize) > PICOPAM_MAX_SYLL_PER_SENT - 1) {
904         return PICO_ERR_OTHER;
905     }
906     return PICO_OK;
907 }/*check_syllables_size*/
908 
909 /**
910  * verifies that local storage has enough space to receive 1 item
911  * @param    this : pointer to current PU struct
912  * @param    item : pointer to current item head
913  * @return    TRUE : resource limits would be reached during processing of input item
914  * @return    FALSE : item could be processed normally
915  * @remarks item pointed to by *item should be already valid
916  * @callgraph
917  * @callergraph
918  */
pamCheckResourceLimits(register picodata_ProcessingUnit this,const picoos_uint8 * item)919 static pico_status_t pamCheckResourceLimits(
920         register picodata_ProcessingUnit this, const picoos_uint8 *item)
921 {
922     register pam_subobj_t * pam;
923     picodata_itemhead_t head;
924     pico_status_t sResult;
925     if (NULL == this || NULL == this->subObj) {
926         return PICODATA_PU_ERROR;
927     }
928     pam = (pam_subobj_t *) this->subObj;
929     sResult = TRUE; /*default : resource limits reached*/
930     head.type = item[0];
931     head.info1 = item[1];
932     head.info2 = item[2];
933     head.len = item[3];
934 
935     switch (head.type) {
936         /*commands that generate syllables/phonemes*/
937         case PICODATA_ITEM_SYLLPHON:
938             if (pam->nCurrSyllable >= PICOPAM_MAX_SYLL_PER_SENT - 2) {
939                 return sResult; /*no room for more syllables*/
940             }
941             if ((pam->nCurrPhoneme + head.len) >= PICOPAM_MAX_PH_PER_SENT - 2) {
942                 return sResult; /*no room for more phoneme*/
943             }
944             break;
945         case PICODATA_ITEM_BOUND:
946             if ((head.info1 == PICODATA_ITEMINFO1_BOUND_SBEG) || (head.info1
947                     == PICODATA_ITEMINFO1_BOUND_SEND) || (head.info1
948                     == PICODATA_ITEMINFO1_BOUND_TERM) || (head.info1
949                     == PICODATA_ITEMINFO1_BOUND_PHR1)
950 #ifdef PAM_PHR2_WITH_PR1
951                     || (head.info1 == PICODATA_ITEMINFO1_BOUND_PHR2)
952 #endif
953             ) {
954 
955                 if (pam->nCurrSyllable >= PICOPAM_MAX_SYLL_PER_SENT - 2) {
956                     return sResult; /*no room for more syllables*/
957                 }
958                 if ((pam->nCurrPhoneme + 1) >= PICOPAM_MAX_PH_PER_SENT - 2) {
959                     return sResult; /*no room for more phoneme*/
960                 }
961             }
962             break;
963 
964         default:
965             /*all other commands has to be queued*/
966             if ((pam->nAttachedItemsSize + head.len)
967                     >= PICOPAM_MAX_ITEM_SIZE_PER_SENT - 1) {
968                 return sResult; /*no room for more items*/
969             }
970             break;
971     }
972     return FALSE; /*no resource limits apply to current item*/
973 } /*pamCheckResourceLimits*/
974 
975 /**
976  * selects items to be sent to next PU immedately
977  * @param    this : pointer to current PU struct
978  * @param    item : pointer to current item head
979  * @return    TRUE : item should be passed on next PU NOW
980  * @return    FALSE : item should not be passed on next PU now but should be processed
981  * @remarks item pointed to by *item should be already valid
982  * @callgraph
983  * @callergraph
984  */
pam_check_immediate(register picodata_ProcessingUnit this,const picoos_uint8 * item)985 static pico_status_t pam_check_immediate(register picodata_ProcessingUnit this,
986         const picoos_uint8 *item)
987 {
988     register pam_subobj_t * pam;
989     if (NULL == this || NULL == this->subObj) {
990         return PICODATA_PU_ERROR;
991     }
992     pam = (pam_subobj_t *) this->subObj;
993 
994     if (pam->nCurrSyllable <= -1) {
995         if (item[0] == PICODATA_ITEM_SYLLPHON)
996             return FALSE;
997         if ((item[0] == PICODATA_ITEM_BOUND) && (item[1]
998                 == PICODATA_ITEMINFO1_BOUND_SBEG))
999             return FALSE;
1000         if (is_pam_command((picoos_uint8 *) item) == TRUE)
1001             return FALSE;
1002         return TRUE; /*no need to process data : send it*/
1003     }
1004     return FALSE; /*syllable struct not void : do standard processing*/
1005 
1006 } /*pam_check_immediate*/
1007 
1008 /**
1009  * checks if the input item has to be queued in local storage for later resynch
1010  * @param    this : pointer to current PU struct
1011  * @param    item : pointer to current item head
1012  * @return    TRUE : item should be queued
1013  * @return    FALSE : item should not be queued
1014  * @remarks item pointed to by *item should be already valid
1015  * @callgraph
1016  * @callergraph
1017  */
pam_hastobe_queued(register picodata_ProcessingUnit this,const picoos_uint8 * item)1018 static pico_status_t pam_hastobe_queued(register picodata_ProcessingUnit this,
1019         const picoos_uint8 *item)
1020 {
1021     register pam_subobj_t * pam;
1022     picodata_itemhead_t head;
1023     if (NULL == this || NULL == this->subObj) {
1024         return PICODATA_PU_ERROR;
1025     }
1026     pam = (pam_subobj_t *) this->subObj;
1027     head.type = item[0];
1028     head.info1 = item[1];
1029 
1030     switch (head.type) {
1031         /*commands that generate syllables/phonemes*/
1032         case PICODATA_ITEM_SYLLPHON:
1033             return FALSE; /*no queue needed*/
1034             break;
1035         case PICODATA_ITEM_BOUND:
1036             if ((head.info1 == PICODATA_ITEMINFO1_BOUND_PHR3)
1037 #ifdef PAM_PHR2_WITH_PR3
1038                     ||(head.info1==PICODATA_ITEMINFO1_BOUND_PHR2)
1039 #endif
1040                     || (head.info1 == PICODATA_ITEMINFO1_BOUND_PHR0)) {
1041                 return FALSE; /*no queue needed*/
1042             }
1043             break;
1044 
1045         default:
1046             /*all other items has to be queued*/
1047             break;
1048     }
1049     return TRUE; /*item has to be queued*/
1050 } /*pam_hastobe_queued*/
1051 
1052 /**
1053  * queue item in local storage for later resynch
1054  * @param    this : pointer to current PU struct
1055  * @param    item : pointer to current item head
1056  * @return    TRUE : item queued
1057  * @return    FALSE : item not queued because of errors
1058  * @remarks item pointed to by *item should be already valid
1059  * @callgraph
1060  * @callergraph
1061  */
pam_queue(register picodata_ProcessingUnit this,const picoos_uint8 * item)1062 static pico_status_t pam_queue(register picodata_ProcessingUnit this,
1063         const picoos_uint8 *item)
1064 {
1065     register pam_subobj_t * pam;
1066     picodata_itemhead_t head;
1067     picoos_uint8 nI;
1068     pico_status_t sResult;
1069     if (NULL == this || NULL == this->subObj) {
1070         return PICODATA_PU_ERROR;
1071     }
1072     pam = (pam_subobj_t *) this->subObj;
1073     sResult = TRUE; /*default : item queued*/
1074     head.type = item[0];
1075     head.info1 = item[1];
1076     head.info2 = item[2];
1077     head.len = item[3];
1078 
1079     /*test condition on enough room to store current item in the "sSyllItems" area*/
1080     if ((pam->nAttachedItemsSize + head.len + sizeof(picodata_itemhead_t))
1081             >= PICOPAM_MAX_ITEM_SIZE_PER_SENT - 1) {
1082         return FALSE; /*resource limit reached*/
1083     }
1084     /*store current offset*/
1085     pam->sSyllItemOffs[pam->nLastAttachedItemId] = pam->nAttachedItemsSize;
1086     /*store the item to the "sSyllItems" area*/
1087     for (nI = 0; nI < (head.len + sizeof(picodata_itemhead_t)); nI++) {
1088         pam->sSyllItems[pam->nAttachedItemsSize + nI] = item[nI];
1089     }
1090     /*increment the attached items area*/
1091     pam->nAttachedItemsSize += nI;
1092 
1093     /*increment id*/
1094     pam->nLastAttachedItemId++;
1095     /*set start(if not initialized) and end ids of queued items in sSyllFeats*/
1096     if (pam->nCurrSyllable > -1) {
1097         /*normal case : the item is attached to current syllable*/
1098         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] == 0) {
1099             pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM]
1100                     = pam->nLastAttachedItemId;
1101         }
1102         pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm]
1103                 = pam->nLastAttachedItemId;
1104     } else {
1105         /*special case : an item is requested to be queued even if no
1106          syllables has been assigned to the sentence structure :
1107          -->> use syll 0*/
1108         if (pam->sSyllFeats[0].phoneV[ITM] == 0) {
1109             pam->sSyllFeats[0].phoneV[ITM] = pam->nLastAttachedItemId;
1110         }
1111         pam->sSyllFeats[0].phoneV[itm] = pam->nLastAttachedItemId;
1112     }
1113     return TRUE; /*item queued successfully*/
1114 } /*pam_queue*/
1115 
1116 /**
1117  * selects items to be dealth with by the PU processing
1118  * @param    item : pointer to current item head
1119  * @return    TRUE : item should be processed
1120  * @return    FALSE : item should not be processed (maybe it ontains commands or items for other PUs)
1121  * @remarks item pointed to by *item should be already valid
1122  * @callgraph
1123  * @callergraph
1124  */
pam_deal_with(const picoos_uint8 * item)1125 static pico_status_t pam_deal_with(const picoos_uint8 *item)
1126 {
1127     picodata_itemhead_t head;
1128     pico_status_t sResult;
1129     sResult = FALSE;
1130     head.type = item[0];
1131     head.info1 = item[1];
1132     head.info2 = item[2];
1133     head.len = item[3];
1134     switch (head.type) {
1135         case PICODATA_ITEM_SYLLPHON:
1136         case PICODATA_ITEM_BOUND:
1137             sResult = TRUE;
1138             break;
1139         default:
1140             break;
1141     }
1142     return sResult;
1143 } /*pam_deal_with*/
1144 
1145 /**
1146  * returns true if more items has to be produced for current syllable
1147  * @param    this : Pam object pointer
1148  * @return    TRUE : item is to be produced
1149  * @return    FALSE : item is not to be produced
1150  * @remarks item pointed to by *item should be already valid
1151  * @callgraph
1152  * @callergraph
1153  */
pamHasToProcess(register picodata_ProcessingUnit this)1154 static picoos_uint8 pamHasToProcess(register picodata_ProcessingUnit this)
1155 {
1156     register pam_subobj_t * pam;
1157     picoos_uint8 nCond1, nCond2, nCond3;
1158 
1159     if (NULL == this || NULL == this->subObj) {
1160         return PICODATA_PU_ERROR;
1161     }
1162     pam = (pam_subobj_t *) this->subObj;
1163     /*conditions originating a "NOT to be processed" result */
1164     nCond1 = pam->nCurrSyllable <= -1;
1165     nCond2 = pam->nCurrSyllable >= pam->nTotalSyllables;
1166     nCond3 = pam->nSyllPhoneme
1167             >= pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3];
1168 
1169     if ((nCond1) || (nCond2) || (nCond3))
1170         return FALSE;
1171 
1172     return TRUE;
1173 } /*pamHasToProcess*/
1174 
1175 /**
1176  * modifies the process flags in order to point to next valid syllable phone or item to be produced
1177  * @param    this : Pam object pointer
1178  * @return    TRUE : item has to be produced
1179  * @return    FALSE : item has not to be produced
1180  * @callgraph
1181  * @callergraph
1182  */
pamUpdateProcess(register picodata_ProcessingUnit this)1183 static pico_status_t pamUpdateProcess(register picodata_ProcessingUnit this)
1184 {
1185     register pam_subobj_t * pam;
1186 
1187     if (NULL == this || NULL == this->subObj) {
1188         return PICODATA_PU_ERROR;
1189     }
1190     pam = (pam_subobj_t *) this->subObj;
1191 
1192     if (pam->nCurrSyllable == -1) {
1193         /*this to be able to manage sudden PU cleanup after FLUSH CMD*/
1194         return PICO_OK;
1195     }
1196     /*check number of phonemes for current syllable*/
1197     if (pam->nSyllPhoneme < pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3] - 1) {
1198         pam->nSyllPhoneme++;
1199         return PICO_OK;
1200     }
1201     if (pam->nSyllPhoneme == pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3] - 1) {
1202         /*this helps in identifyng the end of syllable condition in PamHasToProcess*/
1203         pam->nSyllPhoneme++;
1204     }
1205     /*previous syllable phonemes are complete: test if any items are tied to this syllable*/
1206     if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] > 0) {
1207         /*there are items tied to this syllable*/
1208         if (pam->nCurrAttachedItem == 0) {
1209             /*if it is the first item to be regenerated initialize it*/
1210             pam->nCurrAttachedItem
1211                     = pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM];
1212             return PICO_OK;
1213         } else {
1214             /*not the first item : check if more*/
1215             if (pam->nCurrAttachedItem
1216                     < pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm]) {
1217                 /*more tied items to be regenerated*/
1218                 pam->nCurrAttachedItem++;
1219                 return PICO_OK;
1220             }
1221         }
1222     }
1223     /*previous syllable phonemes and items are complete: switch to next syllable*/
1224     if (pam->nCurrSyllable < pam->nTotalSyllables - 1) {
1225         pam->nCurrSyllable++;
1226         pam->nSyllPhoneme = 0;
1227         pam->nCurrAttachedItem = 0;
1228         return PICO_OK;
1229     }
1230     /*no more phonemes or items to be produced*/
1231     pam->nCurrSyllable++;
1232     pam->nSyllPhoneme = 0;
1233     return PICO_ERR_OTHER;
1234 
1235 } /*pamUpdateProcess*/
1236 
1237 /**
1238  * returns true if more items has to be popped for current syllable
1239  * @param    this : Pam object pointer
1240  * @return    TRUE : item has to be popped
1241  * @return    FALSE : item has not to be popped
1242  * @callgraph
1243  * @callergraph
1244  */
pamHasToPop(register picodata_ProcessingUnit this)1245 static picoos_uint8 pamHasToPop(register picodata_ProcessingUnit this)
1246 {
1247     register pam_subobj_t * pam;
1248 
1249     if (NULL == this || NULL == this->subObj) {
1250         return PICODATA_PU_ERROR;
1251     }
1252     pam = (pam_subobj_t *) this->subObj;
1253 
1254     /*Preliminary condition : at least 1 syllable*/
1255     if (pam->nCurrSyllable <= -1)
1256         return FALSE;
1257 
1258     /*Preliminary condition : not maximum number of syllables*/
1259     if (pam->nCurrSyllable >= pam->nTotalSyllables)
1260         return FALSE;
1261 
1262     /*Preliminary condition : start and end offset in current item > 0 */
1263     if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] <= 0)
1264             || (pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm] <= 0))
1265         return FALSE;
1266 
1267     /*Final condition : current popped item less or eq to maximum*/
1268     if (pam->nCurrAttachedItem
1269             > pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm])
1270         return FALSE;
1271 
1272     return TRUE;
1273 } /*pamHasToPop*/
1274 
1275 /**
1276  * returns the address of an item to be popped from the current syllable queue
1277  * @param    this : Pam object pointer
1278  * @return    pop_address : item address
1279  * @return    NULL : item not poppable
1280  * @callgraph
1281  * @callergraph
1282  */
pamPopItem(register picodata_ProcessingUnit this)1283 static picoos_uint8 *pamPopItem(register picodata_ProcessingUnit this)
1284 {
1285     register pam_subobj_t * pam;
1286     picoos_uint8 nItem;
1287     if (NULL == this || NULL == this->subObj) {
1288         return NULL;
1289     }
1290     pam = (pam_subobj_t *) this->subObj;
1291 
1292     /*Preliminary condition : at least 1 syllable*/
1293     if (pam->nCurrSyllable <= -1)
1294         return NULL;
1295 
1296     /*Preliminary condition : not maximum number of syllables*/
1297     if (pam->nCurrSyllable >= pam->nTotalSyllables)
1298         return NULL;
1299 
1300     /*Preliminary condition : start and end offset in current item > 0 */
1301     if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] <= 0)
1302             || (pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm] <= 0))
1303         return NULL;
1304 
1305     /*Final condition : current popped item less than maximum*/
1306     if (pam->nCurrAttachedItem
1307             > pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm])
1308         return NULL;
1309 
1310     nItem = pam->nCurrAttachedItem;
1311     /*please note : nItem-1 should match with actions performed in function "pam_queue(..)" */
1312     return &(pam->sSyllItems[pam->sSyllItemOffs[nItem - 1]]);
1313 
1314 } /*pamPopItem*/
1315 
1316 /**
1317  * returns the address of an item popped from the syllable 0 queue
1318  * @param    this : Pam object pointer
1319  * @return    pop_address : item address
1320  * @return    NULL : item not poppable
1321  * @remarks the item is popped only if it has been inserted in the queue before the first
1322  * @remarks item assigned to the syllable 0 i.e.
1323  * @remarks AttachedItem<=pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm]-1
1324  * @callgraph
1325  * @callergraph
1326  */
pamPopAttachedSy0(register picodata_ProcessingUnit this)1327 static picoos_uint8 *pamPopAttachedSy0(register picodata_ProcessingUnit this)
1328 {
1329     register pam_subobj_t * pam;
1330     picoos_uint8 nItem;
1331     if (NULL == this || NULL == this->subObj) {
1332         return NULL;
1333     }
1334     pam = (pam_subobj_t *) this->subObj;
1335 
1336     /*should be syllable 0*/
1337     if (pam->nCurrSyllable != 0)
1338         return NULL;
1339 
1340     /*start and end offset in current item > 0 */
1341     if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[ITM] <= 0)
1342             || (pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm] <= 0))
1343         return NULL;
1344 
1345     /*if current popped item is > 0 test end condition*/
1346     if (pam->nCurrAttachedItem > 0) {
1347         /*Other condition : current popped item less than maximum*/
1348         if (pam->nCurrAttachedItem
1349                 > pam->sSyllFeats[pam->nCurrSyllable].phoneV[itm] - 1)
1350             return NULL;
1351     }
1352     nItem = pam->nCurrAttachedItem;
1353     return &(pam->sSyllItems[pam->sSyllItemOffs[nItem]]);
1354 
1355 } /*pamPopAttachedSy0*/
1356 
1357 /**
1358  * pdf access for duration
1359  * @param    this : Pam object pointer
1360  * @param    durIndex : index of duration in the pdf
1361  * @param    phonDur : pointer to base of array where to store the duration values
1362  * @param    numFramesState : pointer to base of array where to store the number of frames per state
1363  * @return    PICO_OK : pdf retrieved
1364  * @return    PICO_ERR_OTHER : pdf not retrieved
1365  * @remarks Modifies phonDur (the requested duration value)
1366  * @remarks Modifies numFramesState (the requested number of frames per state (vector))
1367  * @callgraph
1368  * @callergraph
1369  */
pam_get_duration(register picodata_ProcessingUnit this,picoos_uint16 durIndex,picoos_uint16 * phonDur,picoos_uint8 * numFramesState)1370 static pico_status_t pam_get_duration(register picodata_ProcessingUnit this,
1371         picoos_uint16 durIndex, picoos_uint16 *phonDur,
1372         picoos_uint8 *numFramesState)
1373 {
1374     pam_subobj_t *pam;
1375     picokpdf_PdfDUR pdf;
1376     picoos_uint8 *durItem;
1377     picoos_uint16 nFrameSize, nI;
1378     picoos_single fValue;
1379     pam = (pam_subobj_t *) this->subObj;
1380     if (NULL == this || NULL == this->subObj) {
1381         return PICODATA_PU_ERROR;
1382     }
1383     pdf = pam->pdfdur;
1384     /*make the index 0 based*/
1385     if (durIndex > 0)
1386         durIndex--;
1387 
1388     /* check */
1389     if (durIndex > pdf->numframes - 1) {
1390         PICODBG_ERROR(("PAM durPdf access error, index overflow -> index: %d , numframes: %d", durIndex, pdf->numframes));
1391         return PICO_ERR_OTHER;
1392     }
1393     /* base pointer */
1394     durItem = &(pdf->content[durIndex * pdf->vecsize]);
1395     if (durItem == NULL) {
1396         PICODBG_ERROR(("PAM durPdf access error , frame pointer = NULL"));
1397         return PICO_ERR_OTHER;
1398     }
1399     nFrameSize = pdf->sampperframe / 16;
1400     *phonDur = ((pdf->phonquant[((*durItem) & 0xF0) >> 4]) * nFrameSize);
1401     numFramesState[0] = pdf->statequant[((*durItem) & 0x0F)];
1402     durItem++;
1403     numFramesState[1] = pdf->statequant[((*durItem) & 0xF0) >> 4];
1404     numFramesState[2] = pdf->statequant[((*durItem) & 0x0F)];
1405     durItem++;
1406     numFramesState[3] = pdf->statequant[((*durItem) & 0xF0) >> 4];
1407     numFramesState[4] = pdf->statequant[((*durItem) & 0x0F)];
1408 
1409     /*modification of the duration information based on the duration modifier*/
1410     *phonDur = (picoos_uint16) (((picoos_single) * phonDur) * pam->dMod);
1411     for (nI = 0; nI < 5; nI++) {
1412         fValue = pam->dRest + (picoos_single) numFramesState[nI] * pam->dMod;
1413         numFramesState[nI] = (picoos_uint8) (fValue);
1414         pam->dRest = fValue - (picoos_single) numFramesState[nI];
1415     }
1416     return PICO_OK;
1417 }/*pam_get_duration*/
1418 
1419 /**
1420  * pdf access for pitch
1421  * @param    this : Pam object pointer
1422  * @param    lf0Index : pointer to variable to receive index of pitch in the pdf
1423  * @param    nI : number of the phone's state
1424  * @param    phonF0 : pointer to variable to receive the pitch value
1425  * @return    PICO_OK : pdf retrieved
1426  * @return    PICO_ERR_OTHER : pdf not retrieved
1427  * @remarks Modifies phonDur (the requested duration value)
1428  * @remarks Modifies phonF0 (the requested pitch value (scalar))
1429  * @callgraph
1430  * @callergraph
1431  */
pam_get_f0(register picodata_ProcessingUnit this,picoos_uint16 * lf0Index,picoos_uint8 nI,picoos_single * phonF0)1432 static pico_status_t pam_get_f0(register picodata_ProcessingUnit this,
1433         picoos_uint16 *lf0Index, picoos_uint8 nI, picoos_single *phonF0)
1434 {
1435     pam_subobj_t *pam;
1436     picoos_uint8 *lfItem, numstreams;
1437     picoos_uint16 lf0IndexOffset, sTemp;
1438     picoos_single lfum, lfivar, lfz;
1439 
1440     pam = (pam_subobj_t *) this->subObj;
1441     if (NULL == this || NULL == this->subObj) {
1442         return PICODATA_PU_ERROR;
1443     }
1444     lf0IndexOffset = lf0Index[nI];
1445 
1446     /*make the index 0 based*/
1447     if (lf0IndexOffset > 0)
1448         lf0IndexOffset--;
1449 
1450     lf0IndexOffset += pam->pdflfz->stateoffset[nI];
1451     if (lf0IndexOffset > pam->pdflfz->numframes - 1) {
1452         PICODBG_ERROR(("PAM flfzPdf access error, index overflow -> index: %d , numframes: %d", lf0Index, pam->pdflfz->numframes));
1453         return PICO_ERR_OTHER;
1454     }
1455     /* base pointer */
1456     lf0IndexOffset *= pam->pdflfz->vecsize;
1457 
1458     lfItem = &(pam->pdflfz->content[lf0IndexOffset]);
1459     sTemp = (picoos_uint16) (((lfItem[1] << 8)) | lfItem[0]);
1460 
1461     lfum = (picoos_single) (sTemp << (pam->pdflfz->meanpowUm[0]));
1462     numstreams = 3;
1463     lfivar = (picoos_single) (((picoos_uint16) lfItem[numstreams * 2])
1464             << pam->pdflfz->ivarpow[0]);
1465     lfz = (picoos_single) lfum / (picoos_single) lfivar;
1466     lfz = (picoos_single) exp((double) lfz);
1467     phonF0[nI] = (picoos_single) lfz;
1468 
1469     /*pitch modoification*/
1470     phonF0[nI] *= pam->pMod;
1471     return PICO_OK;
1472 }/*pam_get_f0*/
1473 
1474 /**
1475  * elementary rounding function
1476  * @param    fIn : (real) input value
1477  * @return    the rounded value
1478  * @callgraph
1479  * @callergraph
1480  */
f_round(picoos_single fIn)1481 static picoos_single f_round(picoos_single fIn)
1482 {
1483     picoos_int32 iVal;
1484     picoos_single fVal;
1485 
1486     iVal = (picoos_int32) fIn;
1487     fVal = (picoos_single) iVal;
1488 
1489     if (fIn > (picoos_single) 0.0f) {
1490         if ((fIn - fVal) < (picoos_single) 0.5f)
1491             return fVal;
1492         else
1493             return fVal + (picoos_single) 1.0f;
1494     } else {
1495         if ((fVal - fIn) < (picoos_single) 0.5f)
1496             return fVal;
1497         else
1498             return fVal - (picoos_single) 1.0f;
1499     }
1500 }/*f_round*/
1501 
1502 /**
1503  * updates the input vector for PAM
1504  * @param    this : Pam object pointer
1505  * @return    PICO_OK : update successful
1506  * @return    PICO_ERR_OTHER : errors on retrieving the PU pointer
1507  * @remarks Modifies pam->sPhFeats[]
1508  * @callgraph
1509  * @callergraph
1510  */
pam_update_vector(register picodata_ProcessingUnit this)1511 static pico_status_t pam_update_vector(register picodata_ProcessingUnit this)
1512 {
1513     pam_subobj_t *pam;
1514     picoos_uint8 numstates, nI;
1515     picoos_single fDur, f0avg, f0quant, minf0, maxf0, durquant1, durquant2,
1516             mindur, maxdur1, maxdur2;
1517 
1518     pam = (pam_subobj_t *) this->subObj;
1519     if (NULL == this || NULL == this->subObj) {
1520         return PICO_ERR_OTHER;
1521     }
1522     /*default init*/
1523     pam->sPhFeats[DUR] = 0;
1524     pam->sPhFeats[F0] = 0;
1525     /*
1526      Hard coded parameters for quantization
1527      */
1528     numstates = PICOPAM_NRSTPF;
1529     f0quant = 30.0f;
1530     minf0 = 90.0f;
1531     maxf0 = 360.0f;
1532 
1533     durquant1 = 20.0f;
1534     durquant2 = 100.0f;
1535     mindur = 40.0f;
1536     maxdur1 = 160.0f;
1537     maxdur2 = 600.0f;
1538     f0avg = 0.0f;
1539     for (nI = 0; nI < numstates; nI++)
1540         f0avg += pam->phonF0[nI];
1541     f0avg /= (picoos_single) numstates;
1542 
1543     f0avg = f_round(f0avg / f0quant) * f0quant;
1544     if (f0avg < minf0)
1545         f0avg = minf0;
1546     if (f0avg > maxf0)
1547         f0avg = maxf0;
1548 
1549     /*make initial silence of sentence shorter (see also pam_put_item)*/
1550     if ((pam->nCurrSyllable == 0) && (pam->nSyllPhoneme == 0)) {
1551         pam->phonDur = 2 * 4;
1552     }
1553 
1554     fDur = (picoos_single) pam->phonDur;
1555     fDur = f_round(fDur / durquant1) * durquant1;
1556     if (fDur < mindur)
1557         fDur = mindur;
1558     if (fDur > maxdur1) {
1559         fDur = f_round(fDur / durquant2) * durquant2;
1560         if (fDur > maxdur2)
1561             fDur = maxdur2;
1562     }
1563     pam->sPhFeats[DUR] = (picoos_uint8) (fDur / (picoos_single) 10.0f);
1564     pam->sPhFeats[F0] = (picoos_uint8) (f0avg / (picoos_single) 10.0f);
1565 
1566     return PICO_OK;
1567 }/*pam_update_vector*/
1568 
1569 /**
1570  * compress a single feature in the range 0..9
1571  * @param    inVal : the value to be compressed
1572  * @return    compVal : the compressed value
1573  * @callgraph
1574  * @callergraph
1575  */
pamCompressComponent(picoos_uint8 inVal)1576 static picoos_uint8 pamCompressComponent(picoos_uint8 inVal)
1577 {
1578     if (inVal <= 5)
1579         return inVal;
1580     if ((5 < inVal) && (inVal <= 10))
1581         return 6;
1582     if ((10 < inVal) && (inVal <= 20))
1583         return 7;
1584     if ((20 < inVal) && (inVal <= 30))
1585         return 8;
1586     return 9;
1587 }/*pamCompressComponent*/
1588 
1589 /**
1590  * prepares the input vector for tree feeding
1591  * @param    this : Pam object pointer
1592  * @return    PICO_OK : vector expanded
1593  * @return    PICO_ERR_OTHER : errors on expansion or retrieving the PU pointer
1594  * @remarks Modifies pam->sPhFeats[]
1595  * @callgraph
1596  * @callergraph
1597  */
pam_expand_vector(register picodata_ProcessingUnit this)1598 static pico_status_t pam_expand_vector(register picodata_ProcessingUnit this)
1599 {
1600     pam_subobj_t *pam;
1601     picoos_uint8 *inVect, *phonVect, *outVect, nI;
1602     picoos_int16 nOffs, nOffs1, nLen;
1603     pam = (pam_subobj_t *) this->subObj;
1604     if (NULL == this || NULL == this->subObj) {
1605         return PICODATA_PU_ERROR;
1606     }
1607     inVect = &(pam->sSyllFeats[pam->nCurrSyllable].phoneV[0]);
1608     phonVect = &(pam->sPhIds[0]);
1609     outVect = &(pam->sPhFeats[0]);
1610     /*just copy back*/
1611     for (nI = 0; nI < PICOPAM_INVEC_SIZE; nI++)
1612         outVect[nI] = inVect[nI];
1613     /*now fill missing fields*/
1614     picoos_mem_copy((void*) &(inVect[FID]), &nOffs, sizeof(nOffs));
1615     /*offset to first phone of current syllable*/
1616     nOffs = nOffs + pam->nSyllPhoneme; /*offset to current phone of current syllable*/
1617     nLen = inVect[B3]; /*len of current syllable*/
1618     if (pam->nSyllPhoneme >= nLen) {
1619         /*error on addressing current phone*/
1620         return PICO_ERR_OTHER;
1621     }
1622     /*previous of the previous phone*/
1623     nOffs1 = nOffs - 2;
1624     if (nOffs1 >= 0)
1625         outVect[P1] = phonVect[nOffs1];
1626     else
1627         outVect[P1] = PICOPAM_PH_DONT_CARE_VAL;
1628     /*previous  phone*/
1629     nOffs1 = nOffs - 1;
1630     if (nOffs1 >= 0)
1631         outVect[P2] = phonVect[nOffs1];
1632     else
1633         outVect[P2] = PICOPAM_PH_DONT_CARE_VAL;
1634     /*^current phone*/
1635     outVect[P3] = phonVect[nOffs];
1636 
1637     /*next phone*/
1638     nOffs1 = nOffs + 1;
1639     if (nOffs1 < pam->nTotalPhonemes)
1640         outVect[P4] = phonVect[nOffs1];
1641     else
1642         outVect[P4] = PICOPAM_PH_DONT_CARE_VAL;
1643     /*next of the next phone*/
1644     nOffs1 = nOffs + 2;
1645     if (nOffs1 < pam->nTotalPhonemes)
1646         outVect[P5] = phonVect[nOffs1];
1647     else
1648         outVect[P5] = PICOPAM_PH_DONT_CARE_VAL;
1649     /*pos of curr phone with respect to left syllable boundary*/
1650     outVect[P6] = pam->nSyllPhoneme + 1;
1651     /*pos of curr phone with respect to right syllable boundary*/
1652     outVect[P7] = nLen - pam->nSyllPhoneme;
1653     /*is current phone in consonant syllable boundary? (1:yes)*/
1654     if (pam->nSyllPhoneme < inVect[P8])
1655         outVect[P8] = 1;
1656     else
1657         outVect[P8] = 0;
1658     return PICO_OK;
1659 }/*pam_expand_vector*/
1660 
1661 /**
1662  * compresses the input vector for PAM
1663  * @param    this : Pam object pointer
1664  * @return    PICO_OK : compression successful
1665  * @return    PICO_ERR_OTHER : errors on retrieving the PU pointer
1666  * @remarks Modifies pam->sPhFeats[]
1667  * @callgraph
1668  * @callergraph
1669  */
pamCompressVector(register picodata_ProcessingUnit this)1670 static pico_status_t pamCompressVector(register picodata_ProcessingUnit this)
1671 {
1672     pam_subobj_t *pam;
1673     picoos_uint8 *outVect, nI;
1674     pam = (pam_subobj_t *) this->subObj;
1675     if (NULL == this || NULL == this->subObj) {
1676         return PICODATA_PU_ERROR;
1677     }
1678     outVect = &(pam->sPhFeats[0]);
1679     for (nI = 0; nI < PICOPAM_INVEC_SIZE; nI++) {
1680         switch (nI) {
1681             case P1:
1682             case P2:
1683             case P3:
1684             case P4:
1685             case P5:
1686             case B1:
1687             case B2:
1688             case B16:
1689             case E1:
1690             case H5:
1691                 /*don't do any compression*/
1692                 break;
1693             default:
1694                 /*do compression*/
1695                 if (outVect[nI] != PICOPAM_DONT_CARE_VALUE)
1696                     outVect[nI] = pamCompressComponent(outVect[nI]);
1697                 else
1698                     outVect[nI] = PICOPAM_DONT_CARE_VAL;
1699                 break;
1700         }
1701     }
1702     return PICO_OK;
1703 }/*pamCompressVector*/
1704 
1705 /**
1706  * reorganizes the input vector for PAM
1707  * @param    this : Pam object pointer
1708  * @return    PICO_OK : reorganization successful
1709  * @return    PICO_ERR_OTHER : errors on retrieving the PU pointer
1710  * @remarks Modifies pam->sPhFeats[]
1711  * @callgraph
1712  * @callergraph
1713  */
pamReorgVector(register picodata_ProcessingUnit this)1714 static pico_status_t pamReorgVector(register picodata_ProcessingUnit this)
1715 {
1716     pam_subobj_t *pam;
1717     picoos_uint8 *outVect, inVect[60], nI;
1718     pam = (pam_subobj_t *) this->subObj;
1719     if (NULL == this || NULL == this->subObj) {
1720         return PICODATA_PU_ERROR;
1721     }
1722     outVect = &(pam->sPhFeats[0]);
1723     for (nI = 0; nI < PICOPAM_INVEC_SIZE; nI++) inVect[nI] = outVect[nI];
1724     /*reorganize*/
1725     for (nI = T_B1; nI <= T_H5; nI++) {
1726         switch (nI) {
1727             case T_B1:
1728                 outVect[T_B1] = inVect[B1];
1729                 break;
1730             case T_B2:
1731                 outVect[T_B2] = inVect[B2];
1732                 break;
1733             case T_B3:
1734                 outVect[T_B3] = inVect[B3];
1735                 break;
1736             case T_B4:
1737                 outVect[T_B4] = inVect[B4];
1738                 break;
1739             case T_B5:
1740                 outVect[T_B5] = inVect[B5];
1741                 break;
1742             case T_B6:
1743                 outVect[T_B6] = inVect[B6];
1744                 break;
1745             case T_B7:
1746                 outVect[T_B7] = inVect[B7];
1747                 break;
1748             case T_B8:
1749                 outVect[T_B8] = inVect[B8];
1750                 break;
1751             case T_B9:
1752                 outVect[T_B9] = inVect[B9];
1753                 break;
1754             case T_B10:
1755                 outVect[T_B10] = inVect[B10];
1756                 break;
1757             case T_B11:
1758                 outVect[T_B11] = inVect[B11];
1759                 break;
1760             case T_B12:
1761                 outVect[T_B12] = inVect[B12];
1762                 break;
1763             case T_B13:
1764                 outVect[T_B13] = inVect[B13];
1765                 break;
1766             case T_B14:
1767                 outVect[T_B14] = inVect[B14];
1768                 break;
1769             case T_B15:
1770                 outVect[T_B15] = inVect[B15];
1771                 break;
1772             case T_B16:
1773                 outVect[T_B16] = inVect[B16];
1774                 break;
1775             case T_B17:
1776                 outVect[T_B17] = inVect[B17];
1777                 break;
1778             case T_B18:
1779                 outVect[T_B18] = inVect[B18];
1780                 break;
1781             case T_B19:
1782                 outVect[T_B19] = inVect[B19];
1783                 break;
1784             case T_B20:
1785                 outVect[T_B20] = inVect[B20];
1786                 break;
1787             case T_B21:
1788                 outVect[T_B21] = inVect[B21];
1789                 break;
1790 
1791             case T_E1:
1792                 outVect[T_E1] = inVect[E1];
1793                 break;
1794             case T_E2:
1795                 outVect[T_E2] = inVect[E2];
1796                 break;
1797             case T_E3:
1798                 outVect[T_E3] = inVect[E3];
1799                 break;
1800             case T_E4:
1801                 outVect[T_E4] = inVect[E4];
1802                 break;
1803             case T_E5:
1804                 outVect[T_E5] = inVect[E5];
1805                 break;
1806             case T_E6:
1807                 outVect[T_E6] = inVect[E6];
1808                 break;
1809             case T_E7:
1810                 outVect[T_E7] = inVect[E7];
1811                 break;
1812             case T_E8:
1813                 outVect[T_E8] = inVect[E8];
1814                 break;
1815             case T_E9:
1816                 outVect[T_E9] = inVect[E9];
1817                 break;
1818             case T_E10:
1819                 outVect[T_E10] = inVect[E10];
1820                 break;
1821             case T_E11:
1822                 outVect[T_E11] = inVect[E11];
1823                 break;
1824             case T_E12:
1825                 outVect[T_E12] = inVect[E12];
1826                 break;
1827             case T_E13:
1828                 outVect[T_E13] = inVect[E13];
1829                 break;
1830 
1831             case T_A3:
1832                 outVect[T_A3] = inVect[A3];
1833                 break;
1834             case T_C3:
1835                 outVect[T_C3] = inVect[C3];
1836                 break;
1837             case T_D2:
1838                 outVect[T_D2] = inVect[D2];
1839                 break;
1840             case T_F2:
1841                 outVect[T_F2] = inVect[F2];
1842                 break;
1843 
1844             case T_G1:
1845                 outVect[T_G1] = inVect[G1];
1846                 break;
1847             case T_I1:
1848                 outVect[T_I1] = inVect[I1];
1849                 break;
1850 
1851             case T_G2:
1852                 outVect[T_G2] = inVect[G2];
1853                 break;
1854             case T_I2:
1855                 outVect[T_I2] = inVect[I2];
1856                 break;
1857 
1858             case T_H1:
1859                 outVect[T_H1] = inVect[H1];
1860                 break;
1861             case T_H2:
1862                 outVect[T_H2] = inVect[H2];
1863                 break;
1864             case T_H3:
1865                 outVect[T_H3] = inVect[H3];
1866                 break;
1867             case T_H4:
1868                 outVect[T_H4] = inVect[H4];
1869                 break;
1870             case T_H5:
1871                 outVect[T_H5] = inVect[H5];
1872                 break;
1873         }
1874     }
1875     return PICO_OK;
1876 }/*pamReorgVector*/
1877 
1878 /**
1879  * puts a PAM item into PU output buffer
1880  * @param    this : Pam object pointer
1881  * @param    outBuff    : output buffer base pointer
1882  * @param    outWritePos : offset in output buffer
1883  * @param    *bytesWr : actual bytes written
1884  * @return    PICO_OK : put successful
1885  * @return    PICO_ERR_OTHER : errors on retrieving the PU pointer
1886  * @callgraph
1887  * @callergraph
1888  */
pam_put_item(register picodata_ProcessingUnit this,picoos_uint8 * outBuff,picoos_uint16 outWritePos,picoos_uint8 * bytesWr)1889 static pico_status_t pam_put_item(register picodata_ProcessingUnit this,
1890         picoos_uint8 *outBuff, picoos_uint16 outWritePos, picoos_uint8 *bytesWr)
1891 {
1892     pam_subobj_t *pam;
1893     picoos_uint8 *sDest, nI, nType, nIdx, fde;
1894     picoos_uint32 pos, pos32;
1895     picoos_int16 ft, dt;
1896     picoos_uint16 uMinDur, uMaxDur;
1897     pam = (pam_subobj_t *) this->subObj;
1898     if (NULL == this || NULL == this->subObj) {
1899         return PICODATA_PU_ERROR;
1900     }
1901     sDest = &(outBuff[outWritePos]);
1902     sDest[0] = PICODATA_ITEM_PHONE; /*Item type*/
1903     sDest[1] = pam->sPhFeats[P3]; /*phonetic id*/
1904     sDest[2] = PICOPAM_NRSTPF; /*number of states per phone*/
1905     sDest[3] = sizeof(picoos_uint16) * PICOPAM_NRSTPF * 3; /*size of the item*/
1906     pos = 4;
1907     /*make initial silence of sentence shorter (see also UpdateVector)*/
1908     if ((pam->nCurrSyllable == 0) && (pam->nSyllPhoneme == 0)) {
1909         for (nI = 0; nI < PICOPAM_NRSTPF - 1; nI++)
1910             pam->numFramesState[nI] = 0;
1911         pam->numFramesState[nI] = 2;
1912     } else {
1913         /*manage silence syllables with prescribed durations*/
1914         pos32 = Min;
1915         picoos_read_mem_pi_uint16(pam->sSyllFeats[pam->nCurrSyllable].phoneV,
1916                 &pos32, &uMinDur);
1917         pos32 = Max;
1918         picoos_read_mem_pi_uint16(pam->sSyllFeats[pam->nCurrSyllable].phoneV,
1919                 &pos32, &uMaxDur);
1920 
1921         if (uMaxDur > 0) {
1922             /* Select weights*/
1923             nType = pam->sSyllFeats[pam->nCurrSyllable].phoneV[bnd];
1924             switch (nType) {
1925                 case PICODATA_ITEMINFO1_BOUND_SBEG:
1926                     nIdx = PICOPAM_PWIDX_SBEG;
1927                     break;
1928                 case PICODATA_ITEMINFO1_BOUND_PHR1:
1929                     nIdx = PICOPAM_PWIDX_PHR1;
1930                     break;
1931                 case PICODATA_ITEMINFO1_BOUND_PHR2:
1932                     nIdx = PICOPAM_PWIDX_PHR2;
1933                     break;
1934                 case PICODATA_ITEMINFO1_BOUND_SEND:
1935                 case PICODATA_ITEMINFO1_BOUND_TERM:
1936                     nIdx = PICOPAM_PWIDX_SEND;
1937                     break;
1938                 default:
1939                     nIdx = PICOPAM_PWIDX_DEFA;
1940                     break;
1941             }
1942             fde = 2;
1943             ft = 0;
1944             dt = 0;
1945             picodata_transformDurations(
1946                     fde,            /* 2's exponent of frame duration in ms, e.g. 2 for 4ms, 3 for 8ms */
1947                     PICOPAM_NRSTPF, /* number of states per phone */
1948                     &(pam->numFramesState[0]), /* estimated durations */
1949                     pam->sil_weights[nIdx],  /* integer weights */
1950                     uMinDur,        /* minimum target duration in ms */
1951                     uMaxDur,        /* maximum target duration in ms */
1952                     ft,             /* factor to be multiplied to get the target */
1953                     &dt             /* in/out, rest in ms */
1954                     );
1955         }
1956     }
1957     /*put data*/
1958     for (nI = 0; nI < PICOPAM_NRSTPF; nI++) {
1959         picoos_write_mem_pi_uint16(sDest, &pos,
1960                 (picoos_uint16) pam->numFramesState[nI]);
1961         picoos_write_mem_pi_uint16(sDest, &pos,
1962                 (picoos_uint16) pam->lf0Index[nI]);
1963         picoos_write_mem_pi_uint16(sDest, &pos,
1964                 (picoos_uint16) pam->mgcIndex[nI]);
1965     }
1966     *bytesWr = sizeof(picodata_itemhead_t) + sizeof(picoos_uint16)
1967             * PICOPAM_NRSTPF * 3;
1968     return PICO_OK;
1969 }/*pam_put_item*/
1970 
1971 /**
1972  * puts a non PAM (queued) item into PU output buffer
1973  * @param    qItem : pointer to item to put
1974  * @param    outBuff    : output buffer base pointer
1975  * @param    outWritePos : offset in output buffer
1976  * @param    *bytesWr : actual bytes written
1977  * @return    PICO_OK : put successful
1978  * @return    PICO_ERR_OTHER : errors on retrieving the PU pointer
1979  * @callgraph
1980  * @callergraph
1981  */
pam_put_qItem(picoos_uint8 * qItem,picoos_uint8 * outBuff,picoos_uint16 outWritePos,picoos_uint8 * bytesWr)1982 static pico_status_t pam_put_qItem(picoos_uint8 *qItem, picoos_uint8 *outBuff,
1983         picoos_uint16 outWritePos, picoos_uint8 *bytesWr)
1984 {
1985     picoos_uint8 *sDest, nI;
1986     sDest = &(outBuff[outWritePos]);
1987     *bytesWr = sizeof(picodata_itemhead_t);
1988     for (nI = 0; nI < (sizeof(picodata_itemhead_t) + qItem[3]); nI++) {
1989         sDest[nI] = qItem[nI];
1990     }
1991     *bytesWr = nI;
1992     return PICO_OK;
1993 }/*pam_put_qItem*/
1994 
1995 /**
1996  * tells if an item is a PAM command (except play)
1997  * @param    qItem : input item to test
1998  * @return    TRUE : qItem is a PAM command (except play)
1999  * @return    FALSE : qItem not a PAM command
2000  * @callgraph
2001  * @callergraph
2002  */
is_pam_command(const picoos_uint8 * qItem)2003 static pico_status_t is_pam_command(const picoos_uint8 * qItem)
2004 {
2005     switch (qItem[0]) {
2006 
2007         case PICODATA_ITEM_CMD:
2008             switch (qItem[1]) {
2009                 case PICODATA_ITEMINFO1_CMD_FLUSH:
2010                     /* flush is for all PU's and as such it is also for PAM*/
2011                 case PICODATA_ITEMINFO1_CMD_PITCH:
2012                 case PICODATA_ITEMINFO1_CMD_SPEED:
2013                     return TRUE;
2014                     break;
2015                 default:
2016                     break;
2017             }
2018     }
2019     return FALSE;
2020 }/*is_pam_command*/
2021 
2022 /**
2023  * tells if an item is a PAM PLAY command
2024  * @param    qItem : input item to test
2025  * @return    TRUE : qItem is a PAM PLAY command
2026  * @return    FALSE : qItem not a PAM PLAY command
2027  * @callgraph
2028  * @callergraph
2029  */
is_pam_play_command(picoos_uint8 * qItem)2030 static pico_status_t is_pam_play_command(picoos_uint8 *qItem)
2031 {
2032     switch (qItem[0]) {
2033 
2034         case PICODATA_ITEM_CMD:
2035             switch (qItem[1]) {
2036                 case PICODATA_ITEMINFO1_CMD_PLAY:
2037                     if (qItem[2] == PICODATA_ITEMINFO2_CMD_TO_PAM)
2038                         return TRUE;
2039                     break;
2040                 default:
2041                     break;
2042             }
2043     }
2044     return FALSE;
2045 }/*is_pam_play_command*/
2046 
2047 /**
2048  * command processor for PAM pu
2049  * @param    this : Pam item subobject
2050  * @param    qItem : input item pointer
2051  * @return    PICOPAM_FLUSH_RECEIVED : when a FLUSH is received
2052  * @return    PICOPAM_CONTINUE : normal command processing
2053  * @return    PICODATA_PU_ERROR : errors in accessing data
2054  * @callgraph
2055  * @callergraph
2056  */
pamDoCommand(register picodata_ProcessingUnit this,picoos_uint8 * qItem)2057 static pico_status_t pamDoCommand(register picodata_ProcessingUnit this,
2058         picoos_uint8 *qItem)
2059 {
2060     pam_subobj_t *pam;
2061     picoos_single fValue;
2062     picoos_uint16 nValue;
2063     picoos_uint32 nPos;
2064     pam = (pam_subobj_t *) this->subObj;
2065     if (NULL == this || NULL == this->subObj) {
2066         return PICODATA_PU_ERROR;
2067     }
2068     if (qItem[0] == PICODATA_ITEM_CMD) {
2069         switch (qItem[1]) {
2070             case PICODATA_ITEMINFO1_CMD_FLUSH:
2071                 /* flush is for all PU's and as such it is also for PAM : implement the flush!!*/
2072                 pam_reset_processors(this);
2073                 pam->nLastAttachedItemId = pam->nCurrAttachedItem = 0;
2074                 pam->nAttachedItemsSize = 0;
2075                 return PICOPAM_FLUSH_RECEIVED;
2076                 break;
2077 
2078             case PICODATA_ITEMINFO1_CMD_PITCH:
2079             case PICODATA_ITEMINFO1_CMD_SPEED:
2080                 nPos = 4;
2081                 picoos_read_mem_pi_uint16(qItem, &nPos, &nValue);
2082                 if (qItem[2] == 'a') {
2083                     /*absloute modifier*/
2084                     fValue = (picoos_single) nValue / (picoos_single) 100.0f;
2085                     if (qItem[1] == PICODATA_ITEMINFO1_CMD_PITCH)
2086                         pam->pMod = fValue;
2087                     if (qItem[1] == PICODATA_ITEMINFO1_CMD_SPEED)
2088                         pam->dMod = (1.0f / fValue);
2089                 }
2090                 if (qItem[2] == 'r') {
2091                     /*relative modifier*/
2092                     fValue = (picoos_single) nValue / (picoos_single) 1000.0f;
2093                     if (qItem[1] == PICODATA_ITEMINFO1_CMD_PITCH)
2094                         pam->pMod *= (1.0f / fValue);
2095                     if (qItem[1] == PICODATA_ITEMINFO1_CMD_SPEED)
2096                         pam->dMod *= (1.0f / fValue);
2097                 }
2098                 return PICOPAM_CONTINUE;
2099                 break;
2100 
2101             default:
2102                 break;
2103         }/*end switch  switch (qItem[1])*/
2104     }/*end if (qItem[0]==PICODATA_ITEM_CMD)*/
2105     return PICOPAM_CONTINUE;
2106 }/*pamDoCommand*/
2107 
2108 /**
2109  * defines if an item has to be sent to following PUs
2110  * @param    qItem : input item pointer
2111  * @return    TRUE : item has to be transmitted to following PUs
2112  * @return    FALSE : item has to be consumed internallz on PAM
2113  * @callgraph
2114  * @callergraph
2115  */
isItemToPut(picoos_uint8 * qItem)2116 static pico_status_t isItemToPut(picoos_uint8 *qItem)
2117 {
2118     switch (qItem[0]) {
2119         case PICODATA_ITEM_CMD:
2120             /* is a command*/
2121             if (PICODATA_ITEMINFO1_CMD_SPEED == qItem[1]) {
2122                 /* SPEED consumed here*/
2123                 return FALSE;
2124             }
2125             break;
2126         case PICODATA_ITEM_BOUND:
2127             switch (qItem[1]) {
2128                 case PICODATA_ITEMINFO1_BOUND_SBEG:
2129                 case PICODATA_ITEMINFO1_BOUND_PHR0:
2130                 case PICODATA_ITEMINFO1_BOUND_PHR1:
2131                 case PICODATA_ITEMINFO1_BOUND_PHR2:
2132                 case PICODATA_ITEMINFO1_BOUND_PHR3:
2133                     /*boudary items consumed here except SEND,TERM*/
2134                     return FALSE;
2135                     break;
2136                 default:
2137                     break;
2138             }
2139             break;
2140         default:
2141             break;
2142     }
2143     /*all other items not explicitly mentioned here
2144      are transmitted to next PUs*/
2145     return TRUE;
2146 }/*isItemToPut*/
2147 
2148 /**
2149  * pushes a boundary TERM item into some buffer
2150  * @param    outBuff : output buffer base pointer
2151  * @param    outWritePos : offset in output buffer
2152  * @param    *bytesWr : actual bytes written
2153  * @return    PICO_OK
2154  * @remarks    used while forcing TERM input items in forward processing
2155  * @callgraph
2156  * @callergraph
2157  */
pam_put_term(picoos_uint8 * outBuff,picoos_uint16 outWritePos,picoos_uint8 * bytesWr)2158 static pico_status_t pam_put_term(picoos_uint8 *outBuff,
2159         picoos_uint16 outWritePos, picoos_uint8 *bytesWr)
2160 {
2161     picoos_uint8 *sDest;
2162     sDest = &(outBuff[outWritePos]);
2163     sDest[0] = PICODATA_ITEM_BOUND; /*Item type*/
2164     sDest[1] = PICODATA_ITEMINFO1_BOUND_TERM;
2165     sDest[2] = PICODATA_ITEMINFO2_BOUNDTYPE_T;
2166     sDest[3] = 0; /*item size*/
2167     *bytesWr = 4;
2168     return PICO_OK;
2169 }/*pam_put_term*/
2170 
2171 /**
2172  * translates one full phone into a PHONE Item including DT Dur, F0 and CEP trees feature generation and traversal
2173  * @param    this : Pam item subobject pointer
2174  * @return    PICO_OK : processing successful
2175  * @return    PICODATA_PU_ERROR : error accessing PAM object
2176  * @return    !=PICO_OK : processing errors
2177  * @callgraph
2178  * @callergraph
2179  */
pamPhoneProcess(register picodata_ProcessingUnit this)2180 static pico_status_t pamPhoneProcess(register picodata_ProcessingUnit this)
2181 {
2182     pam_subobj_t *pam;
2183     pico_status_t sResult;
2184     picokdt_classify_result_t dTreeResult;
2185     picoos_uint8 nI, bWr;
2186 
2187     pam = (pam_subobj_t *) this->subObj;
2188     if (NULL == this || NULL == this->subObj) {
2189         return PICODATA_PU_ERROR;
2190     }
2191     /*expands current phone in current syllable in the corresponding vector pam->sPhFeats[]*/
2192     sResult = pam_expand_vector(this);
2193     sResult = pamCompressVector(this);
2194     sResult = pamReorgVector(this);
2195 
2196     /*tree traversal for duration*/
2197     if (!pam_do_tree(this, pam->dtdur, &(pam->sPhFeats[0]), PICOPAM_INVEC_SIZE,
2198             &dTreeResult)) {
2199         PICODBG_WARN(("problem using pam tree dtdur, using fallback value"));
2200         dTreeResult.class = 0;
2201     }
2202     pam->durIndex = dTreeResult.class;
2203     sResult = pam_get_duration(this, pam->durIndex, &(pam->phonDur),
2204             &(pam->numFramesState[0]));
2205 
2206     /*tree traversal for pitch*/
2207     for (nI = 0; nI < PICOPAM_MAX_STATES_PER_PHONE; nI++) {
2208         if (!pam_do_tree(this, pam->dtlfz[nI], &(pam->sPhFeats[0]),
2209                 PICOPAM_INVEC_SIZE, &dTreeResult)) {
2210             PICODBG_WARN(("problem using pam tree lf0Tree, using fallback value"));
2211             dTreeResult.class = 0;
2212         }
2213         pam->lf0Index[nI] = dTreeResult.class;
2214     }
2215 
2216     /*pdf access for pitch*/
2217     for (nI = 0; nI < PICOPAM_MAX_STATES_PER_PHONE; nI++) {
2218         sResult = pam_get_f0(this, &(pam->lf0Index[0]), nI, &(pam->phonF0[0]));
2219     }
2220 
2221     /*update vector with duration and pitch for cep tree traversal*/
2222     sResult = pam_update_vector(this);
2223     /*cep tree traversal*/
2224     for (nI = 0; nI < PICOPAM_MAX_STATES_PER_PHONE; nI++) {
2225 
2226         if (!pam_do_tree(this, pam->dtmgc[nI], &(pam->sPhFeats[0]),
2227                 PICOPAM_INVEC_SIZE, &dTreeResult)) {
2228             PICODBG_WARN(("problem using pam tree lf0Tree, using fallback value"));
2229             dTreeResult.class = 0;
2230         }
2231         pam->mgcIndex[nI] = dTreeResult.class;
2232     }
2233     /*put item to output buffer*/
2234     sResult = pam_put_item(this, pam->outBuf, pam->outWritePos, &bWr);
2235     if (sResult == PICO_OK)
2236         pam->outWritePos += bWr;
2237     else
2238         return sResult;
2239     return PICO_OK;
2240 }/*pamPhoneProcess*/
2241 
2242 /**
2243  * manages first syllable attached items when seen before SBEG
2244  * @param    this  : Pam item subobject pointer
2245  * @return    PICO_OK (0) : default return code --> means no more items to be processed before 1st syllable
2246  * @return    PICOPAM_GOTO_FEED : go to feed state after this
2247  * @return    PICOPAM_GOTO_SCHEDULE : flush received
2248  * @return    PICODATA_PU_ERROR : errors
2249  * @callgraph
2250  * @callergraph
2251  */
pamDoPreSyll(register picodata_ProcessingUnit this)2252 static pico_status_t pamDoPreSyll(register picodata_ProcessingUnit this)
2253 {
2254     pam_subobj_t *pam;
2255     pico_status_t sResult;
2256     picoos_uint8 bWr, nRc;
2257     picoos_uint8 *qItem;
2258     nRc = PICOPAM_PRE_SYLL_ENDED;
2259     pam = (pam_subobj_t *) this->subObj;
2260     if (NULL == this || NULL == this->subObj) {
2261         return PICODATA_PU_ERROR;
2262     }
2263     /*regenerate initial items before the phonemes*/
2264     if (((qItem = pamPopAttachedSy0(this)) != NULL) && !((qItem[0]
2265             == PICODATA_ITEM_BOUND) && (qItem[1]
2266             == PICODATA_ITEMINFO1_BOUND_SBEG))) {
2267          if (isItemToPut(qItem)) {
2268             pam_put_qItem(qItem, pam->outBuf, pam->outWritePos, &bWr);/*popped item has to be sent to next PU*/
2269             pam->outWritePos += bWr;
2270             nRc = PICOPAM_GOTO_FEED;
2271         }
2272 
2273         if (is_pam_command(qItem) == TRUE) {
2274             nRc = pamDoCommand(this, qItem); /*popped item is a PAM command : do it NOW!!*/
2275             if ((nRc == PICOPAM_FLUSH_RECEIVED) || (nRc == PICODATA_PU_ERROR)) {
2276                 /*FLUSH command RECEIVED or errors: stop ALL PROCESSING*/
2277                 return nRc;
2278             }
2279         }
2280         pam->nCurrAttachedItem++;
2281         if (nRc == 0)
2282             return PICOPAM_CONTINUE;
2283         else
2284             return nRc;
2285     }
2286     /*SBEG item management*/
2287     if ((qItem != NULL) && (qItem[0] == PICODATA_ITEM_BOUND) && (qItem[1]
2288             == PICODATA_ITEMINFO1_BOUND_SBEG)) {
2289         sResult = pam_put_qItem(qItem, pam->outBuf, pam->outWritePos, &bWr);
2290         pam->outWritePos += bWr;
2291         pam->nCurrAttachedItem++;
2292         nRc = PICOPAM_GOTO_FEED;
2293     }
2294     return nRc;
2295 }/*pamDoPreSyll*/
2296 
2297 /**
2298  * performs a step of the pam processing
2299  * @param    this : Pam item subobject pointer
2300  * @param    mode : mode for the PU
2301  * @param    *numBytesOutput : pointer to output number fo bytes produced
2302  * @return    PICODATA_PU_IDLE : nothing to do
2303  * @return    PICODATA_PU_BUSY : still tasks undergoing
2304  * @return    PICODATA_PU_ERROR : errors on processing
2305  * @callgraph
2306  * @callergraph
2307  */
pam_step(register picodata_ProcessingUnit this,picoos_int16 mode,picoos_uint16 * numBytesOutput)2308 static picodata_step_result_t pam_step(register picodata_ProcessingUnit this,
2309         picoos_int16 mode, picoos_uint16 * numBytesOutput)
2310 {
2311 
2312     register pam_subobj_t * pam;
2313 
2314     pico_status_t sResult;
2315     picoos_uint16 blen, numinb, numoutb;
2316     pico_status_t rv;
2317     picoos_uint8 bWr;
2318     picoos_uint8 bForcedItem[4];
2319     picoos_uint8 *qItem;
2320 
2321     numinb = 0;
2322     numoutb = 0;
2323     rv = PICO_OK;
2324 
2325     if (NULL == this || NULL == this->subObj) {
2326         return PICODATA_PU_ERROR;
2327     }
2328     pam = (pam_subobj_t *) this->subObj;
2329     mode = mode; /* avoid warning "var not used in this function"*/
2330     /*Init number of output bytes*/
2331     *numBytesOutput = 0;
2332 
2333     while (1) { /* exit via return */
2334 
2335         PICODBG_DEBUG(("pam_step -- doing state %i",pam->procState));
2336 
2337         switch (pam->procState) {
2338 
2339             case PICOPAM_COLLECT:
2340                 /* *************** item collector ***********************************/
2341                 /*collecting items from the PU input buffer*/
2342                 sResult = picodata_cbGetItem(this->cbIn,
2343                         &(pam->inBuf[pam->inWritePos]), pam->inBufSize
2344                                 - pam->inWritePos, &blen);
2345                 if (sResult != PICO_OK) {
2346                     if (sResult == PICO_EOF) {
2347                         /*no items available : remain in state 0 and return idle*/
2348                         return PICODATA_PU_IDLE;
2349                     } else {
2350                         /*errors : remain in state 0 and return error*/
2351                         PICODBG_DEBUG(("pam_step(PICOPAM_COLLECT) -- Errors on item buffer input, status: %d",sResult));
2352                         return PICODATA_PU_ERROR;
2353                     }
2354                 }
2355 
2356                 PICODBG_DEBUG(("pam_step -- got item, status: %d",sResult));
2357                 sResult = picodata_is_valid_item(
2358                         &(pam->inBuf[pam->inWritePos]), blen);
2359                 if (sResult != TRUE) {
2360                     /*input item is not valid : consume the input item and stay in COLLECT*/
2361                     pam->inWritePos += blen;
2362                     pam->inReadPos += blen;
2363                     if (pam->inReadPos >= pam->inWritePos) {
2364                         pam->inReadPos = 0;
2365                         pam->inWritePos = 0;
2366                     }PICODBG_DEBUG(("pam_step -- item is not valid, type: %d",pam->inBuf[pam->inWritePos]));
2367                     return PICODATA_PU_BUSY;
2368                 }
2369 
2370                 /*update input write pointer + move to "schedule" state*/
2371                 pam->inWritePos += blen;
2372                 pam->procState = PICOPAM_SCHEDULE;
2373                 return PICODATA_PU_BUSY;
2374 
2375             case PICOPAM_SCHEDULE:
2376                 /* check out if more items are available */
2377                 if (pam->inReadPos >= pam->inWritePos) {
2378                     /*no more items : back to collect state*/
2379                     pam->procState = PICOPAM_COLLECT;
2380                     return PICODATA_PU_BUSY;
2381                 }
2382                 /* we have one full valid item, with len>0 starting at
2383                  pam->inBuf[pam->inReadPos]; here we decide how to elaborate it */
2384 
2385                 /* PLAY management */
2386                 if (is_pam_play_command(&(pam->inBuf[pam->inReadPos])) == TRUE) {
2387                     /*consume the input item : it has been managed*/
2388                     pam->inReadPos += pam->inBuf[pam->inReadPos + 3]
2389                             + sizeof(picodata_itemhead_t);
2390                     if (pam->inReadPos >= pam->inWritePos) {
2391                         pam->inReadPos = 0;
2392                         pam->inWritePos = 0;
2393                     }
2394                     /*stay in schedule*/
2395                     return PICODATA_PU_BUSY;
2396                 }
2397 
2398                 if (pam_check_immediate(this, &(pam->inBuf[pam->inReadPos]))) {
2399                     /* item has to be sent to next PU NOW : switch to "immediate" state */
2400                     pam->procState = PICOPAM_IMMEDIATE;
2401                     return PICODATA_PU_BUSY;
2402                 }
2403                 if (pamCheckResourceLimits(this, &(pam->inBuf[pam->inReadPos]))) {
2404                     /* item would not fit into local buffers -->> free some space -->>
2405                      switch to "force term" state */
2406                     pam->procState = PICOPAM_FORWARD_FORCE_TERM;
2407                     return PICODATA_PU_BUSY;
2408                 }
2409 
2410                 if (pam_deal_with(&(pam->inBuf[pam->inReadPos]))) {
2411                     /* item has to be managed by the "forward" state : switch to forward state*/
2412                     pam->procState = PICOPAM_FORWARD;
2413                     return PICODATA_PU_BUSY;
2414                 }
2415 
2416                 if (pam_hastobe_queued(this, &(pam->inBuf[pam->inReadPos]))) {
2417                     /* item is not for PAM so it has to be queued internally */
2418                     pam_queue(this, &(pam->inBuf[pam->inReadPos]));
2419                     /*consume the input item : it has been queued*/
2420                     pam->inReadPos += pam->inBuf[pam->inReadPos + 3]
2421                             + sizeof(picodata_itemhead_t);
2422                     if (pam->inReadPos >= pam->inWritePos) {
2423                         pam->inReadPos = 0;
2424                         pam->inWritePos = 0;
2425                     }
2426                     return PICODATA_PU_BUSY;
2427                 }
2428                 /*if we get here something wrong happened. Being the the item valid,
2429                  switch to "immediate" state -> send it to next PU -> */
2430                 PICODBG_DEBUG(("pam_step (PICOPAM_SCHEDULE) -- unexpected item is sent to next PU !!"));
2431                 pam->procState = PICOPAM_IMMEDIATE;
2432                 return PICODATA_PU_BUSY;
2433                 break; /*PICOPAM_SCHEDULE*/
2434 
2435             case PICOPAM_FORWARD:
2436                 /*we have one full valid item, with len>0 starting at pam->inBuf[pam->inReadPos].
2437                  furthermore this item should be in the set {BOUND,SYLL}.
2438                  No other items should arrive here*/
2439                 sResult = pam_adapter_forward_step(this,
2440                         &(pam->inBuf[pam->inReadPos]));
2441                 /*decide if this item has to be queued for later re-synchronization
2442                  normally this is only done for SEND/TERM items*/
2443                 if (pam_hastobe_queued(this, &(pam->inBuf[pam->inReadPos]))) {
2444                     /*item has to be queued iternally in local storage*/
2445                     pam_queue(this, &(pam->inBuf[pam->inReadPos]));
2446                 }
2447                 /*now assign next state according to Forward results*/
2448                 switch (sResult) {
2449                     case PICOPAM_READY:
2450                         pam->needMoreInput = FALSE;
2451                         /*consume the input item : it has already been stored*/
2452                         pam->inReadPos += pam->inBuf[pam->inReadPos + 3]
2453                                 + sizeof(picodata_itemhead_t);
2454                         if (pam->inReadPos >= pam->inWritePos) {
2455                             pam->inReadPos = 0;
2456                             pam->inWritePos = 0;
2457                         }
2458                         /*activate backward processing*/
2459                         sResult = pam_adapter_backward_step(this);
2460                         if (sResult == PICO_OK) {
2461                             pam->procState = PICOPAM_PROCESS;
2462                             return PICODATA_PU_BUSY;
2463                         } else {
2464                             PICODBG_DEBUG(("pam_step (PICOPAM_FORWARD) -- wrong return from BackwardStep: %d -- Buffered sentence will be discarded",sResult));
2465                             pam_reset_processors(this);
2466                             pam->nLastAttachedItemId = pam->nCurrAttachedItem
2467                                     = 0;
2468                             pam->nAttachedItemsSize = 0;
2469 
2470                             pam->procState = PICOPAM_SCHEDULE;
2471                             return PICODATA_PU_BUSY;
2472                         }
2473                         break;
2474 
2475                     case PICOPAM_MORE:
2476                         pam->needMoreInput = TRUE;
2477                         /*consume the input item : it has already been stored*/
2478                         pam->inReadPos += pam->inBuf[pam->inReadPos + 3]
2479                                 + sizeof(picodata_itemhead_t);
2480                         if (pam->inReadPos >= pam->inWritePos) {
2481                             /*input is finished and PAM need more data :
2482                              clenaup input buffer + switch state back to "schedule state"
2483                              */
2484                             pam->inReadPos = 0;
2485                             pam->inWritePos = 0;
2486                             pam->procState = PICOPAM_SCHEDULE;
2487                             return PICODATA_PU_ATOMIC;
2488                         } else {
2489                             /*input is not finished and need more data :
2490                              remain in state "PICOPAM_FORWARD" */
2491                             return PICODATA_PU_ATOMIC;
2492                         }
2493                         break;
2494 
2495                     case PICOPAM_NA:
2496                     default:
2497                         /*this item has not been stored in internal buffers:
2498                          assign this item to the management of
2499                          "immediate" state*/
2500                         pam->procState = PICOPAM_IMMEDIATE;
2501                         return PICODATA_PU_BUSY;
2502                         break;
2503                 } /*end switch sResult*/
2504                 break; /*PICOPAM_FORWARD*/
2505 
2506             case PICOPAM_FORWARD_FORCE_TERM:
2507                 /*we have one full valid item, with len>0
2508                  starting at pam->inBuf[pam->inReadPos] but we decided
2509                  to force a TERM item before, without losing the item in
2510                  inBuf[inReadPos] : --> generate a TERM item and do the
2511                  forward processing */
2512                 pam_put_term(bForcedItem, 0, &bWr);
2513                 sResult = pam_adapter_forward_step(this, &(bForcedItem[0]));
2514                 switch (sResult) {
2515                     case PICOPAM_READY:
2516                         pam_queue(this, &(bForcedItem[0]));
2517                         /*activate backward processing*/
2518                         sResult = pam_adapter_backward_step(this);
2519                         if (sResult == PICO_OK) {
2520                             pam->procState = PICOPAM_PROCESS;
2521                             return PICODATA_PU_BUSY;
2522                         } else {
2523                             PICODBG_DEBUG(("pam_step (PICOPAM_FORWARD_FORCE_TERM) -- wrong return from BackwardStep: %d -- Buffered sentence will be discarded",sResult));
2524                             pam_reset_processors(this);
2525                             pam->nLastAttachedItemId = pam->nCurrAttachedItem
2526                                     = 0;
2527                             pam->nAttachedItemsSize = 0;
2528 
2529                             pam->procState = PICOPAM_SCHEDULE;
2530                             return PICODATA_PU_BUSY;
2531                         }
2532                         break;
2533 
2534                     default:
2535                         PICODBG_DEBUG(("pam_step (PICOPAM_FORWARD_FORCE_TERM) -- Forced a TERM but processing do not appear to end -- Buffered sentence will be discarded",sResult));
2536                         pam_reset_processors(this);
2537                         pam->nLastAttachedItemId = pam->nCurrAttachedItem = 0;
2538                         pam->nAttachedItemsSize = 0;
2539 
2540                         pam->procState = PICOPAM_SCHEDULE;
2541                         return PICODATA_PU_BUSY;
2542                         break;
2543 
2544                 } /*end switch sResult*/
2545                 break; /*PICOPAM_FORWARD_FORCE_TERM*/
2546 
2547             case PICOPAM_PROCESS:
2548 
2549                 if ((PICOPAM_FRAME_ITEM_SIZE + 4) > (pam->outBufSize
2550                         - pam->outWritePos)) {
2551                     /*WARNING (buffer overflow): leave status unchanged until output buffer free */
2552                     return PICODATA_PU_BUSY;
2553                 }
2554 
2555                 if (pam->nCurrSyllable == 0) {
2556                     sResult = pamDoPreSyll(this);
2557                     if (sResult == PICOPAM_GOTO_FEED) {
2558                         /*
2559                          items pushed to output buffer :
2560                          switch to "feed" but then back
2561                          to "process"
2562                          */
2563                         pam->retState = PICOPAM_PROCESS;
2564                         pam->procState = PICOPAM_FEED;
2565                         return PICODATA_PU_BUSY;
2566                     }
2567                     if (sResult == PICOPAM_CONTINUE) {
2568                         /*
2569                          items processed (maybe commands) :
2570                          return (maybe we need to process other
2571                          items in pre_syll) and then back to "process"
2572                          */
2573                         pam->retState = PICOPAM_PROCESS;
2574                         pam->procState = PICOPAM_PROCESS;
2575                         return PICODATA_PU_BUSY;
2576                     }
2577 
2578                     if ((sResult == PICOPAM_FLUSH_RECEIVED) || (sResult
2579                             == PICODATA_PU_ERROR)) {
2580                         /*
2581                          items processed were a flush or
2582                          problems found: switch to "schedule"
2583                          and abort all processing
2584                          */
2585                         pam->retState = PICOPAM_SCHEDULE;
2586                         pam->procState = PICOPAM_SCHEDULE;
2587                         return PICODATA_PU_BUSY;
2588                     }
2589                     if (sResult == PICOPAM_PRE_SYLL_ENDED) {
2590                         /*
2591                          we get here when     pam->nCurrSyllable==0 and
2592                          no more items to be processed before the syllable
2593                          */
2594                         sResult = sResult;
2595                     }
2596                 }
2597 
2598                 if (pamHasToProcess(this)) {
2599                     if (pamPhoneProcess(this) == PICO_OK) {
2600                         sResult = pamUpdateProcess(this);
2601                         pam->procState = PICOPAM_FEED; /*switch to feed*/
2602                         return PICODATA_PU_BUSY;
2603                     } else {
2604                         PICODBG_DEBUG(("pam_step(PICOPAM_PROCESS) --- NULL return from pamPhoneProcess"));
2605                         return PICODATA_PU_ERROR;
2606                     }
2607                 }
2608 
2609                 if (pamHasToPop(this) != FALSE) {
2610                     if ((qItem = pamPopItem(this)) == NULL) {
2611                         PICODBG_DEBUG(("pam_step(PICOPAM_PROCESS) --- NULL return from pamPopItem"));
2612                         return PICODATA_PU_ERROR;
2613                     }
2614 
2615                     if (isItemToPut(qItem)) {
2616                         /*popped item has to be sent to next PU*/
2617                         sResult = pam_put_qItem(qItem, pam->outBuf,
2618                                 pam->outWritePos, &bWr);
2619                         if (sResult != PICO_OK) {
2620                             PICODBG_DEBUG(("pam_step(PICOPAM_PROCESS) --- Error on writing item to output buffer"));
2621                             return PICODATA_PU_ERROR;
2622                         }
2623                         pam->outWritePos += bWr; /*item write ok*/
2624                         pam->procState = PICOPAM_FEED; /*switch to feed*/
2625                     }
2626 
2627                     /*moved command processing here (after pam_put_qItem) because of FLUSH command could erase
2628                      * the syllable structure and make it impossible to transmit the flush to other PUs*/
2629                     if (is_pam_command(qItem) == TRUE) {
2630                         sResult = pamDoCommand(this, qItem); /*popped item is a PAM command : do it NOW!!*/
2631                         if ((sResult == PICOPAM_FLUSH_RECEIVED) || (sResult
2632                                 == PICODATA_PU_ERROR)) {
2633                             pam->retState = PICOPAM_SCHEDULE;
2634                             pam->procState = PICOPAM_SCHEDULE; /*switch to schedule */
2635                             return PICODATA_PU_BUSY;
2636                         }
2637                     }
2638                     /*update PAM status: if more items attached to the current syllable
2639                      stay in current syllable, otherwise move to next syllable and switch
2640                      to processing phones */
2641                     sResult = pamUpdateProcess(this); /*both "doCommand" or "put" : update PAM status*/
2642                     return PICODATA_PU_BUSY;
2643                 } else {
2644                     pam->procState = PICOPAM_SCHEDULE; /*switch to schedule */
2645                     return PICODATA_PU_BUSY;
2646                 }
2647 
2648                 break; /*PICOPAM_PROCESS*/
2649 
2650             case PICOPAM_IMMEDIATE:
2651                 /* *** item is output NOW!!! */
2652                 /*context: full valid item, with len> starting at pam->inBuf[pam->inReadPos]*/
2653                 numinb = PICODATA_ITEM_HEADSIZE
2654                         + pam->inBuf[pam->inReadPos + 3];
2655                 sResult = picodata_copy_item(&(pam->inBuf[pam->inReadPos]),
2656                         numinb, &(pam->outBuf[pam->outWritePos]),
2657                         pam->outBufSize - pam->outWritePos, &numoutb);
2658 
2659                 if (sResult == PICO_OK) {
2660                     pam->inReadPos += numinb;
2661                     if (pam->inReadPos >= pam->inWritePos) {
2662                         pam->inReadPos = 0;
2663                         pam->inWritePos = 0;
2664                         pam->needMoreInput = FALSE;
2665                     }
2666                     pam->outWritePos += numoutb;
2667                     pam->procState = PICOPAM_FEED; /*switch to FEED state*/
2668                     pam->retState = PICOPAM_SCHEDULE; /*back to SCHEDULE after FEED*/
2669                 } else {
2670                     /*
2671                      PICO_EXC_BUF_IGNORE
2672                      PICO_EXC_BUF_UNDERFLOW
2673                      PICO_EXC_BUF_OVERFLOW
2674                      */
2675                     PICODBG_DEBUG(("pam_step(PICOPAM_IMMEDIATE) --- wrong return from picodata_copy_item:%d",sResult));
2676                     return PICODATA_PU_ERROR;
2677                 }
2678                 return PICODATA_PU_BUSY;
2679                 break; /*PICOPAM_IMMEDIATE*/
2680 
2681             case PICOPAM_FEED:
2682                 /* *************** item output/feeding ***********************************/
2683                 /*feeding items to PU output buffer*/
2684                 sResult = picodata_cbPutItem(this->cbOut,
2685                         &(pam->outBuf[pam->outReadPos]), pam->outWritePos
2686                                 - pam->outReadPos, &numoutb);
2687                 PICODBG_DEBUG(("pam_step -- put item, status: %d",sResult));
2688                 if (PICO_OK == sResult) {
2689 
2690                     PICODATA_INFO_ITEM(this->voice->kbArray[PICOKNOW_KBID_DBG],
2691                             (picoos_uint8 *)"pam: ",
2692                             pam->outBuf + pam->outReadPos, pam->outBufSize);
2693 
2694                     pam->outReadPos += numoutb;
2695                     *numBytesOutput = numoutb;
2696                     if (pam->outReadPos >= pam->outWritePos) {
2697                         /*reset the output pointers*/
2698                         pam->outReadPos = 0;
2699                         pam->outWritePos = 0;
2700                         /*switch to appropriate state*/
2701                         switch (pam->retState) {
2702                             case PICOPAM_IMMEDIATE:
2703                                 pam->procState = PICOPAM_IMMEDIATE;
2704                                 pam->retState = PICOPAM_SCHEDULE;
2705                                 return PICODATA_PU_BUSY;
2706                                 break;
2707                             case PICOPAM_PLAY:
2708                                 pam->procState = PICOPAM_PLAY;
2709                                 pam->retState = PICOPAM_SCHEDULE;
2710                                 return PICODATA_PU_BUSY;
2711                                 break;
2712                             default:
2713                                 break;
2714                         }
2715                         /*Define next state
2716                          a)process (if current sentence has more data to process)
2717                          b)schedule (no more data to process in current sentence)
2718                          NOTE : case b)also happens when dealing with non BOUND/SYLL items*/
2719                         if ((pamHasToProcess(this)) || (pamHasToPop(this))) {
2720                             pam->procState = PICOPAM_PROCESS;
2721                         } else {
2722                             pam->nCurrSyllable = -1;
2723                             pam_reset_processors(this);
2724                             pam->nLastAttachedItemId = pam->nCurrAttachedItem
2725                                     = 0;
2726                             pam->nAttachedItemsSize = 0;
2727 
2728                             pam->nSyllPhoneme = 0;
2729                             pam->procState = PICOPAM_SCHEDULE;
2730                         }
2731                     }
2732                     return PICODATA_PU_BUSY;
2733 
2734                 } else if (PICO_EXC_BUF_OVERFLOW == sResult) {
2735 
2736                     PICODBG_DEBUG(("pam_step ** feeding, overflow, PICODATA_PU_OUT_FULL"));
2737                     return PICODATA_PU_OUT_FULL;
2738 
2739                 } else if ((PICO_EXC_BUF_UNDERFLOW == sResult)
2740                         || (PICO_ERR_OTHER == sResult)) {
2741 
2742                     PICODBG_DEBUG(("pam_step ** feeding problem, discarding item"));
2743                     pam->outReadPos = 0;
2744                     pam->outWritePos = 0;
2745                     pam->procState = PICOPAM_COLLECT;
2746                     return PICODATA_PU_ERROR;
2747 
2748                 }
2749                 break; /*PICOPAM_FEED*/
2750 
2751             default:
2752                 /*NOT feeding items*/
2753                 sResult = PICO_EXC_BUF_IGNORE;
2754                 break;
2755         }/*end switch*/
2756         return PICODATA_PU_BUSY; /*check if there is more data to process after feeding*/
2757 
2758     }/*end while*/
2759     return PICODATA_PU_IDLE;
2760 }/*pam_step*/
2761 
2762 /**
2763  * performs one step of a PamTree
2764  * @param    this : Pam item subobject pointer
2765  * @param    dtpam : the Pam decision tree
2766  * @param    *invec : the input vector pointer
2767  * @param    inveclen : length of the input vector
2768  * @param    *dtres : the classification result
2769  * @return    dtres->set : the result of tree traversal
2770  * @callgraph
2771  * @callergraph
2772  */
pam_do_tree(register picodata_ProcessingUnit this,const picokdt_DtPAM dtpam,const picoos_uint8 * invec,const picoos_uint8 inveclen,picokdt_classify_result_t * dtres)2773 static picoos_uint8 pam_do_tree(register picodata_ProcessingUnit this,
2774         const picokdt_DtPAM dtpam, const picoos_uint8 *invec,
2775         const picoos_uint8 inveclen, picokdt_classify_result_t *dtres)
2776 {
2777     picoos_uint8 okay;
2778 
2779     okay = TRUE;
2780     /* construct input vector, which is set in dtpam */
2781     if (!picokdt_dtPAMconstructInVec(dtpam, invec, inveclen)) {
2782         /* error constructing invec */
2783         PICODBG_WARN(("problem with invec"));
2784         picoos_emRaiseWarning(this->common->em, PICO_WARN_INVECTOR, NULL, NULL);
2785         okay = FALSE;
2786     }
2787     /* classify */
2788     if (okay && (!picokdt_dtPAMclassify(dtpam))) {
2789         /* error doing classification */
2790         PICODBG_WARN(("problem classifying"));
2791         picoos_emRaiseWarning(this->common->em, PICO_WARN_CLASSIFICATION, NULL,
2792                 NULL);
2793         okay = FALSE;
2794     }
2795     /* decompose */
2796     if (okay && (!picokdt_dtPAMdecomposeOutClass(dtpam, dtres))) {
2797         /* error decomposing */
2798         PICODBG_WARN(("problem decomposing"));
2799         picoos_emRaiseWarning(this->common->em, PICO_WARN_OUTVECTOR, NULL, NULL);
2800         okay = FALSE;
2801     }
2802 
2803     PICODBG_TRACE(("dtpam output class: %d", dtres->class));
2804 
2805     return dtres->set;
2806 }/*pam_do_tree*/
2807 
2808 /**
2809  * returns the carrier vowel id inside a syllable
2810  * @param    this : Pam item subobject pointer
2811  * @param    item : the full syllable item
2812  * @param    *pos : pointer to the variable to receive the position of the carrier vowel
2813  * @return    the phonetic id for the carrier vowel inside the syllable
2814  * @callgraph
2815  * @callergraph
2816  */
pam_get_vowel_name(register picodata_ProcessingUnit this,picoos_uint8 * item,picoos_uint8 * pos)2817 static picoos_uint8 pam_get_vowel_name(register picodata_ProcessingUnit this,
2818         picoos_uint8 *item, picoos_uint8 *pos)
2819 {
2820     pam_subobj_t *pam;
2821     picoos_uint8 *phon, nI, nCond1;
2822     if (NULL == this || NULL == this->subObj) {
2823         return 0;
2824     }
2825     pam = (pam_subobj_t *) this->subObj;
2826 
2827     if (item == NULL)
2828         return 0;
2829     if (item[3] == 0)
2830         return 0;
2831     phon = &item[4];
2832     for (nI = 0; nI < item[3]; nI++) {
2833         nCond1 = picoktab_isSyllCarrier(pam->tabphones, phon[nI]);
2834         if (nCond1) {
2835             *pos = nI;
2836             return phon[nI];
2837         }
2838     }
2839     return 0;
2840 }/*pam_get_vowel_name */
2841 
2842 /**
2843  * returns the pause phone id in the current ph.alphabet
2844  * @param    this : Pam sub object pointer
2845  * @return    the (numeric) phonetic id of the pause phone in current phonetic alphabet
2846  * @return    0 :  errors on getting the pam subobject pointer
2847  * @callgraph
2848  * @callergraph
2849  */
pam_get_pause_id(register picodata_ProcessingUnit this)2850 static picoos_uint8 pam_get_pause_id(register picodata_ProcessingUnit this)
2851 {
2852     picoos_uint8 nVal1;
2853     /*picoos_uint8 nVal2; */
2854     pam_subobj_t *pam;
2855     if (NULL == this || NULL == this->subObj) {
2856         return 0;
2857     }
2858     pam = (pam_subobj_t *) this->subObj;
2859     nVal1 = picoktab_getPauseID(pam->tabphones);
2860     return nVal1;
2861 }/*pam_get_pause_id */
2862 
2863 /**
2864  * returns the pam sentence type (declarative, interrogative...)
2865  * @param    iteminfo1 : the boundary item info 1
2866  * @param    iteminfo2 : the boundary item info 2
2867  * @return    the sentence type suitably encoded for trees
2868  * @callgraph
2869  * @callergraph
2870  */
pam_map_sentence_type(picoos_uint8 iteminfo1,picoos_uint8 iteminfo2)2871 static picoos_uint8 pam_map_sentence_type(picoos_uint8 iteminfo1,
2872         picoos_uint8 iteminfo2)
2873 {
2874     switch (iteminfo2) {
2875         case PICODATA_ITEMINFO2_BOUNDTYPE_P:
2876             return PICOPAM_DECLARATIVE;
2877         case PICODATA_ITEMINFO2_BOUNDTYPE_T:
2878             return PICOPAM_DECLARATIVE;
2879         case PICODATA_ITEMINFO2_BOUNDTYPE_Q:
2880             return PICOPAM_INTERROGATIVE;
2881         case PICODATA_ITEMINFO2_BOUNDTYPE_E:
2882             return PICOPAM_DECLARATIVE;
2883         default:
2884             return PICOPAM_DECLARATIVE;
2885     }
2886     iteminfo1 = iteminfo1; /* avoid warning "var not used in this function"*/
2887     return PICOPAM_DECLARATIVE;
2888 }/*pam_map_sentence_type */
2889 
2890 /**
2891  * returns the pam phrase type
2892  * @param    iteminfo1 : the boundary item info 1
2893  * @param    iteminfo2 : the boundary item info 2
2894  * @return    the phrase type suitably encoded for trees
2895  * @callgraph
2896  * @callergraph
2897  */
pam_map_phrase_type(picoos_uint8 iteminfo1,picoos_uint8 iteminfo2)2898 static picoos_uint8 pam_map_phrase_type(picoos_uint8 iteminfo1,
2899         picoos_uint8 iteminfo2)
2900 {
2901 
2902     switch (iteminfo2) {
2903         case PICODATA_ITEMINFO2_BOUNDTYPE_P:
2904             switch (iteminfo1) {
2905                 case PICODATA_ITEMINFO1_BOUND_PHR1:
2906 #                ifdef PAM_PHR2_WITH_PR1
2907                 case PICODATA_ITEMINFO1_BOUND_PHR2:
2908 #                endif
2909                     return PICOPAM_P; /*current_prhase type = "P" (encoded to 1) */
2910                     break;
2911                 case PICODATA_ITEMINFO1_BOUND_PHR3:
2912 #                ifdef PAM_PHR2_WITH_PR3
2913                     case PICODATA_ITEMINFO1_BOUND_PHR2 :
2914 #                endif
2915                     return PICOPAM_p; /*current_prhase type = "p" (encoded to 2) */
2916                     break;
2917                 case PICODATA_ITEMINFO1_BOUND_SBEG:
2918                     return PICOPAM_P; /*current_prhase type = "P" (encoded to 1) */
2919                     break;
2920                 default:
2921                     PICODBG_DEBUG(("Map pam_map_phrase_type : unexpected iteminfo1"));
2922                     return PICOPAM_P; /*current_prhase type = "P" (encoded to 1) */
2923                     break;
2924             }
2925         case PICODATA_ITEMINFO2_BOUNDTYPE_T:
2926             return PICOPAM_T; /*current_prhase type = "T" (encoded to 0) */
2927             break;
2928         case PICODATA_ITEMINFO2_BOUNDTYPE_E:
2929             return PICOPAM_T; /*current_prhase type = "T" (encoded to 0) */
2930             break;
2931         case PICODATA_ITEMINFO2_BOUNDTYPE_Q:
2932             return PICOPAM_Y; /*current_prhase type = "T" (encoded to 0) */
2933             break;
2934         default:
2935             PICODBG_DEBUG(("Map pam_map_phrase_type : unexpected iteminfo2"));
2936             return PICOPAM_T; /*current_prhase type = "T" (encoded to 0) */
2937             break;
2938     }PICODBG_DEBUG(("Map pam_map_phrase_type : unexpected iteminfo2"));
2939     return PICOPAM_T; /*current_prhase type = "T" (encoded to 0) */
2940 
2941 }/*pam_map_phrase_type */
2942 
2943 /**
2944  * does the cleanup of the sub object processors flags at sentence start
2945  * @param    this : pointer to PAM PU sub object pointer
2946  * @return    PICO_OK : reset OK
2947  * @return    PICO_ERR_OTHER : errors on getting pam sub obj pointer
2948  * @callgraph
2949  * @callergraph
2950  */
pam_reset_processors(register picodata_ProcessingUnit this)2951 static pico_status_t pam_reset_processors(register picodata_ProcessingUnit this)
2952 {
2953     pam_subobj_t *pam;
2954     if (NULL == this || NULL == this->subObj) {
2955         return PICO_ERR_OTHER;
2956     }
2957     pam = (pam_subobj_t *) this->subObj;
2958 
2959     pam->nCurrSyllable = -1;
2960     pam->nTotalPhonemes = pam->nSyllPhoneme = pam->nCurrPhoneme
2961             = pam->nTotalSyllables = pam->sType = pam->pType = 0;
2962     pam->dRest = 0.0f;
2963     /*set all to 0*/
2964     pam->a3_overall_syllable    = pam->a3_primary_phrase_syllable   = pam->b4_b5_syllable =
2965         pam->b6_b7_syllable     = pam->b6_b7_state                  = pam->b8_b9_stressed_syllable =
2966         pam->b10_b11_accented_syllable  = pam->b12_b13_syllable     = pam->b12_b13_state =
2967         pam->b14_b15_syllable   = pam->b14_b15_state                = pam->b17_b19_syllable =
2968         pam->b17_b19_state      = pam->b18_b20_b21_syllable         = pam->b18_b20_b21_state =
2969         pam->c3_overall_syllable= pam->c3_primary_phrase_syllable   = pam->d2_syllable_in_word =
2970         pam->d2_prev_syllable_in_word = pam->d2_current_primary_phrase_word = pam->e1_syllable_word_start =
2971         pam->e1_syllable_word_end= pam->e1_content                  = pam->e2_syllable_word_start =
2972         pam->e2_syllable_word_end= pam->e3_e4_word                  = pam->e3_e4_state =
2973         pam->e5_e6_content_word = pam->e5_e6_content                = pam->e7_e8_word =
2974         pam->e7_e8_content      = pam->e7_e8_state                  = pam->e9_e11_word =
2975         pam->e9_e11_saw_word    = pam->e9_e11_state                 = pam->e10_e12_e13_word =
2976         pam->e10_e12_e13_state  = pam->e10_e12_e13_saw_word         = pam->f2_overall_word =
2977         pam->f2_word_syllable   = pam->f2_next_word_syllable        = pam->f2_current_primary_phrase_word =
2978         pam->g1_current_secondary_phrase_syllable                   = pam->g1_current_syllable =
2979         pam->g2_current_secondary_phrase_word                       = pam->g2_current_word =
2980         pam->h1_current_secondary_phrase_syll                       = pam->h2_current_secondary_phrase_word =
2981         pam->h3_h4_current_secondary_phrase_word                    = pam->h5_current_phrase_type =
2982         pam->h5_syllable        = pam->h5_state                     = pam->i1_secondary_phrase_syllable =
2983         pam->i1_next_secondary_phrase_syllable                      = pam->i2_secondary_phrase_word =
2984         pam->i2_next_secondary_phrase_word                          = pam->j1_utterance_syllable =
2985         pam->j2_utterance_word  = pam->j3_utterance_sec_phrases     = 0;
2986     /*Override 0 with 1*/
2987     pam->b4_b5_syllable         = pam->b17_b19_syllable             = pam->b18_b20_b21_syllable =
2988         pam->e9_e11_word        = pam->e10_e12_e13_word             = pam->e7_e8_word =
2989         pam->h2_current_secondary_phrase_word                       = 1;
2990     /*Override 0 with -1*/
2991     pam->e1_syllable_word_start = pam->e1_syllable_word_end         = pam->e2_syllable_word_start =
2992         pam->e2_syllable_word_end                                   = -1;
2993 
2994     return PICO_OK;
2995 }/*pam_reset_processors*/
2996 
2997 /**
2998  * does the cleanup of the sub object processors flags before the backward step
2999  * @param    this : pointer to PAM PU sub object pointer
3000  * @return    PICO_OK : reset OK
3001  * @return    PICO_ERR_OTHER : errors on getting pam sub obj pointer
3002  * @callgraph
3003  * @callergraph
3004  */
pam_reset_processors_back(register picodata_ProcessingUnit this)3005 static pico_status_t pam_reset_processors_back(
3006         register picodata_ProcessingUnit this)
3007 {
3008     pam_subobj_t *pam;
3009     if (NULL == this || NULL == this->subObj) {
3010         return PICO_ERR_OTHER;
3011     }
3012     pam = (pam_subobj_t *) this->subObj;
3013 
3014     /*set all to 0*/
3015     pam->a3_overall_syllable
3016         = pam->a3_primary_phrase_syllable
3017         = pam->b4_b5_syllable
3018         = pam->b6_b7_syllable
3019         = pam->b6_b7_state
3020         = pam->b8_b9_stressed_syllable
3021         = pam->b10_b11_accented_syllable
3022         = pam->b12_b13_syllable
3023         = pam->b12_b13_state
3024         = pam->b14_b15_syllable
3025         = pam->b14_b15_state
3026         = pam->b17_b19_syllable
3027         = pam->b17_b19_state
3028         = pam->b18_b20_b21_syllable
3029         = pam->b18_b20_b21_state
3030         = pam->c3_overall_syllable
3031         = pam->c3_primary_phrase_syllable
3032         = pam->d2_syllable_in_word
3033         = pam->d2_prev_syllable_in_word
3034         = pam->d2_current_primary_phrase_word
3035         = pam->e1_syllable_word_start
3036         = pam->e1_syllable_word_end
3037         = pam->e1_content
3038         = pam->e2_syllable_word_start
3039         = pam->e2_syllable_word_end
3040         = pam->e3_e4_word
3041         = pam->e3_e4_state
3042         = pam->e5_e6_content_word
3043         = pam->e5_e6_content
3044         = pam->e7_e8_word
3045         = pam->e7_e8_content
3046         = pam->e7_e8_state
3047         = pam->e9_e11_word
3048         = pam->e9_e11_saw_word
3049         = pam->e9_e11_state
3050         = pam->e10_e12_e13_word
3051         = pam->e10_e12_e13_state
3052         = pam->e10_e12_e13_saw_word
3053         = pam->f2_overall_word
3054         = pam->f2_word_syllable
3055         = pam->f2_next_word_syllable
3056         = pam->f2_current_primary_phrase_word
3057         = pam->g1_current_secondary_phrase_syllable
3058         = pam->g1_current_syllable
3059         = pam->g2_current_secondary_phrase_word
3060         = pam->g2_current_word
3061         = pam->h1_current_secondary_phrase_syll
3062         = pam->h2_current_secondary_phrase_word
3063         = pam->h3_h4_current_secondary_phrase_word
3064         = pam->h5_current_phrase_type
3065         = pam->h5_state
3066         = pam->i1_secondary_phrase_syllable
3067         = pam->i1_next_secondary_phrase_syllable
3068         = pam->i2_secondary_phrase_word
3069         = pam->i2_next_secondary_phrase_word
3070         = 0;
3071     /*Override 0 with 1*/
3072     pam->b4_b5_syllable = pam->b17_b19_syllable = pam->b18_b20_b21_syllable
3073         = pam->e9_e11_word = pam->e10_e12_e13_word = pam->e7_e8_word
3074         = pam->h2_current_secondary_phrase_word = 1;
3075     /*Override 0 with -1*/
3076     pam->e1_syllable_word_start = pam->e1_syllable_word_end
3077         = pam->e2_syllable_word_start = pam->e2_syllable_word_end = -1;
3078 
3079     return PICO_OK;
3080 }/*pam_reset_processors_back*/
3081 
3082 /**
3083  * processes an input event for a specific feature
3084  * @param    this : pointer to PAM PU sub object pointer
3085  * @param    nFeat : feature column to process
3086  * @param    event_type : event id among syll/boundprim/boundsec/boundword
3087  * @param    direction : forward(0)/backward(1)
3088  * @return    PICO_OK : process OK
3089  * @return    PICO_ERR_OTHER : errors on getting pam sub obj pointer
3090  * @callgraph
3091  * @callergraph
3092  */
pam_process_event_feature(register picodata_ProcessingUnit this,picoos_uint8 nFeat,picoos_uint8 event_type,picoos_uint8 direction)3093 static pico_status_t pam_process_event_feature(
3094         register picodata_ProcessingUnit this, picoos_uint8 nFeat,
3095         picoos_uint8 event_type, picoos_uint8 direction)
3096 {
3097     picoos_uint8 sDest, nI;
3098     picoos_uint16 syllCurr;
3099     pam_subobj_t *pam;
3100     if (NULL == this || NULL == this->subObj) {
3101         return PICO_ERR_OTHER;
3102     }
3103     pam = (pam_subobj_t *) this->subObj;
3104     syllCurr = pam->nCurrSyllable;
3105     switch (nFeat) {
3106         case A3:
3107             /*processor for A3*/
3108             switch (direction) {
3109                 case PICOPAM_DIR_FORW:
3110                     if (event_type == PICOPAM_EVENT_SYLL) {
3111                         if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1]
3112                                 == 1) || (pam->a3_primary_phrase_syllable >= 1)) {
3113                             if (pam->a3_overall_syllable < 1)
3114                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3]
3115                                         = 0;
3116                             else
3117                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3]
3118                                         = pam->sSyllFeats[pam->nCurrSyllable
3119                                                 - 1].phoneV[B3];
3120                         } else {
3121                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3] = 0;
3122                         }
3123                         pam->a3_primary_phrase_syllable++;
3124                         pam->a3_overall_syllable++;
3125                     }
3126                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3127                         pam->a3_primary_phrase_syllable = 0;
3128                     }
3129                     break;
3130                 case PICOPAM_DIR_BACK:
3131                     /*do nothing*/
3132                     break;
3133             }
3134             break;
3135         case B1:
3136         case B2:
3137         case B3:
3138             /*done in createSyllable*/
3139             break;
3140         case B4:/*processor for B4,B5*/
3141             switch (direction) {
3142                 case PICOPAM_DIR_FORW:
3143                     sDest = B4;
3144                     break;
3145                 case PICOPAM_DIR_BACK:
3146                     sDest = B5;
3147                     break;
3148                 default:
3149                     sDest = B4;
3150                     break;
3151             }
3152             if (event_type == PICOPAM_EVENT_SYLL) {
3153                 if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1] == 0) {
3154                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3155                             = pam->b4_b5_syllable;
3156                     pam->b4_b5_syllable++;
3157                 } else {
3158                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest] = 0;
3159                 }
3160             }
3161             if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3162                     == PICOPAM_EVENT_S_BOUND) || (event_type
3163                     == PICOPAM_EVENT_P_BOUND)) {
3164                 pam->b4_b5_syllable = 1;
3165             }
3166             break;
3167         case B5:/*processor for B5 : done in B4*/
3168             break;
3169         case B6:/*processor for B6,B7*/
3170             switch (direction) {
3171                 case PICOPAM_DIR_FORW:
3172                     sDest = B6;
3173                     break;
3174                 case PICOPAM_DIR_BACK:
3175                     sDest = B7;
3176                     break;
3177                 default:
3178                     sDest = B6;
3179                     break;
3180             }
3181             switch (pam->b6_b7_state) {
3182                 case 0:
3183                     if (event_type == PICOPAM_EVENT_SYLL)
3184                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3185                                 = PICOPAM_DONT_CARE_VALUE;
3186                     if (event_type == PICOPAM_EVENT_S_BOUND) {
3187                         pam->b6_b7_syllable = 1;
3188                         pam->b6_b7_state = 1;
3189                     }
3190                     break;
3191                 case 1:
3192                     if (event_type == PICOPAM_EVENT_SYLL) {
3193                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3194                                 = pam->b6_b7_syllable;
3195                         pam->b6_b7_syllable++;
3196                     }
3197                     if (event_type == PICOPAM_EVENT_S_BOUND) {
3198                         pam->b6_b7_syllable = 1;
3199                     }
3200                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3201                         pam->b6_b7_state = 0;
3202                     }
3203                     break;
3204                 default:
3205                     break;
3206             }
3207             break;
3208         case B7:/*Done in B6*/
3209             break;
3210         case B8:/*processor for B8,B9*/
3211             switch (direction) {
3212                 case PICOPAM_DIR_FORW:
3213                     sDest = B8;
3214                     break;
3215                 case PICOPAM_DIR_BACK:
3216                     sDest = B9;
3217                     break;
3218                 default:
3219                     sDest = B8;
3220                     break;
3221             }
3222             if (event_type == PICOPAM_EVENT_SYLL) {
3223                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3224                         = pam->b8_b9_stressed_syllable;
3225                 if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] == 1)
3226                     pam->b8_b9_stressed_syllable++;
3227             }
3228             if (event_type == PICOPAM_EVENT_P_BOUND) {
3229                 pam->b8_b9_stressed_syllable = 0;
3230             }
3231 
3232             break;
3233         case B9:/*done in B8*/
3234             break;
3235         case B10:/*processor for B10, B11*/
3236             switch (direction) {
3237                 case PICOPAM_DIR_FORW:
3238                     sDest = B10;
3239                     break;
3240                 case PICOPAM_DIR_BACK:
3241                     sDest = B11;
3242                     break;
3243                 default:
3244                     sDest = B10;
3245                     break;
3246             }
3247             if (event_type == PICOPAM_EVENT_SYLL) {
3248                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3249                         = pam->b10_b11_accented_syllable;
3250                 if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] == 1)
3251                     pam->b10_b11_accented_syllable++;
3252             }
3253             if (event_type == PICOPAM_EVENT_P_BOUND) {
3254                 pam->b10_b11_accented_syllable = 0;
3255             }
3256             break;
3257         case B11:/*done in B10*/
3258             break;
3259         case B12:/*processor for B12,B13*/
3260             switch (direction) {
3261                 case PICOPAM_DIR_FORW:
3262                     sDest = B12;
3263                     break;
3264                 case PICOPAM_DIR_BACK:
3265                     sDest = B13;
3266                     break;
3267                 default:
3268                     sDest = B12;
3269                     break;
3270             }
3271             switch (pam->b12_b13_state) {
3272                 case 0:
3273                     if (event_type == PICOPAM_EVENT_SYLL) {
3274                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] == 0)
3275                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3276                                     = PICOPAM_DONT_CARE_VALUE;
3277                         else {
3278                             pam->b12_b13_syllable = 0;
3279                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3280                                     = PICOPAM_DONT_CARE_VALUE;
3281                             pam->b12_b13_state = 1;
3282                         }
3283                     }
3284                     break;
3285                 case 1:
3286                     if (event_type == PICOPAM_EVENT_SYLL) {
3287                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3288                                 = pam->b12_b13_syllable;
3289                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] == 1)
3290                             pam->b12_b13_syllable = 0;
3291                         else
3292                             pam->b12_b13_syllable++;
3293                         pam->b12_b13_state = 2;
3294                     }
3295                     if (event_type == PICOPAM_EVENT_P_BOUND)
3296                         pam->b12_b13_state = 0;
3297                     break;
3298                 case 2:
3299                     if (event_type == PICOPAM_EVENT_SYLL) {
3300                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3301                                 = pam->b12_b13_syllable;
3302                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] == 1)
3303                             pam->b12_b13_syllable = 0;
3304                         else
3305                             pam->b12_b13_syllable++;
3306                     }
3307                     if (event_type == PICOPAM_EVENT_P_BOUND)
3308                         pam->b12_b13_state = 0;
3309 
3310                     break;
3311                 default:
3312                     break;
3313             }
3314             break;
3315         case B13:/*done in B12*/
3316             break;
3317 
3318         case B14:/*processor for B14, B15*/
3319             switch (direction) {
3320                 case PICOPAM_DIR_FORW:
3321                     sDest = B14;
3322                     break;
3323                 case PICOPAM_DIR_BACK:
3324                     sDest = B15;
3325                     break;
3326                 default:
3327                     sDest = B14;
3328                     break;
3329             }
3330             switch (pam->b14_b15_state) {
3331                 case 0:
3332                     if (event_type == PICOPAM_EVENT_SYLL) {
3333                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] == 0)
3334                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3335                                     = PICOPAM_DONT_CARE_VALUE;
3336                         else {
3337                             pam->b14_b15_syllable = 0;
3338                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3339                                     = PICOPAM_DONT_CARE_VALUE;
3340                             pam->b14_b15_state = 1;
3341                         }
3342                     }
3343                     break;
3344                 case 1:
3345                     if (event_type == PICOPAM_EVENT_SYLL) {
3346                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3347                                 = pam->b14_b15_syllable;
3348                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] == 1)
3349                             pam->b14_b15_syllable = 0;
3350                         else
3351                             pam->b14_b15_syllable++;
3352                         pam->b14_b15_state = 2;
3353                     }
3354                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3355                         pam->b14_b15_state = 0;
3356                     }
3357                     break;
3358                 case 2:
3359                     if (event_type == PICOPAM_EVENT_SYLL) {
3360                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3361                                 = pam->b14_b15_syllable;
3362                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] == 1)
3363                             pam->b14_b15_syllable = 0;
3364                         else
3365                             pam->b14_b15_syllable++;
3366                     }
3367                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3368                         pam->b14_b15_state = 0;
3369                     }
3370                     break;
3371                 default:
3372                     break;
3373             }
3374             break;
3375         case B15:/*Processor for B15 : done in B14*/
3376             break;
3377         case B16:/*done in createSyllable*/
3378             break;
3379         case B17:/*processor for B17, B19 unified */
3380             switch (direction) {
3381                 case PICOPAM_DIR_FORW:
3382                     switch (pam->b17_b19_state) {
3383                         case 0:
3384                             if (event_type == PICOPAM_EVENT_SYLL) {
3385                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[B17]
3386                                         = PICOPAM_DONT_CARE_VALUE;
3387                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[B19]
3388                                         = pam->b17_b19_syllable;
3389                                 pam->b17_b19_syllable++;
3390                             }
3391                             if (((event_type == PICOPAM_EVENT_P_BOUND)
3392                                     || (event_type == PICOPAM_EVENT_S_BOUND))
3393                                     && (pam->b17_b19_syllable > 1)) {
3394                                 if (event_type == PICOPAM_EVENT_P_BOUND)
3395                                     pam->b17_b19_syllable = 1;
3396                                 pam->b17_b19_state = 1;
3397                             }
3398                             break;
3399                         case 1:
3400                             if (event_type == PICOPAM_EVENT_SYLL) {
3401                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[B17]
3402                                         = pam->b17_b19_syllable;
3403                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[B19]
3404                                         = PICOPAM_DONT_CARE_VALUE;
3405                                 pam->b17_b19_syllable++;
3406                             }
3407                             if (event_type == PICOPAM_EVENT_P_BOUND) {
3408                                 pam->b17_b19_syllable = 1;
3409                             }
3410                             break;
3411                         default:
3412                             break;
3413                     }
3414                     break;
3415                 case PICOPAM_DIR_BACK:
3416                     /*do nothing*/
3417                     break;
3418             }
3419             break;
3420         case B18:/*processor for B18, B20, B21 unfied*/
3421             switch (direction) {
3422                 case PICOPAM_DIR_FORW:/*do nothing*/
3423                     break;
3424                 case PICOPAM_DIR_BACK:
3425                     switch (pam->b18_b20_b21_state) {
3426                         case 0:
3427                             if (event_type == PICOPAM_EVENT_SYLL) {
3428                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[B18]
3429                                         = PICOPAM_DONT_CARE_VALUE;
3430                                 if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
3431                                         == PICOPAM_DECLARATIVE) {
3432                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
3433                                             = pam->b18_b20_b21_syllable;
3434                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
3435                                             = PICOPAM_DONT_CARE_VALUE;
3436                                 } else {
3437                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
3438                                             = PICOPAM_DONT_CARE_VALUE;
3439                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
3440                                             = pam->b18_b20_b21_syllable;
3441                                 }
3442                                 pam->b18_b20_b21_syllable++;
3443                             }
3444                             if (((event_type == PICOPAM_EVENT_P_BOUND)
3445                                     || (event_type == PICOPAM_EVENT_S_BOUND))
3446                                     && (pam->b18_b20_b21_syllable > 1)) {
3447                                 if (event_type == PICOPAM_EVENT_P_BOUND)
3448                                     pam->b18_b20_b21_syllable = 1;
3449                                 pam->b18_b20_b21_state = 1;
3450                             }
3451                             break;
3452                         case 1:
3453                             if (event_type == PICOPAM_EVENT_SYLL) {
3454                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[B18]
3455                                         = pam->b18_b20_b21_syllable;
3456                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
3457                                         = PICOPAM_DONT_CARE_VALUE;
3458                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
3459                                         = PICOPAM_DONT_CARE_VALUE;
3460                                 pam->b18_b20_b21_syllable++;
3461                             }
3462                             if (event_type == PICOPAM_EVENT_P_BOUND) {
3463                                 pam->b18_b20_b21_syllable = 1;
3464                             }
3465                             break;
3466                         default:
3467                             break;
3468                     }
3469                     break;
3470             }
3471             break;
3472         case B19:/*processor for B19 : done in B17*/
3473             break;
3474         case B20:/*processor for B20 : done in B18*/
3475             break;
3476         case B21:/*processor for B21 : done in B18*/
3477             break;
3478         case C3:/*processor for C3*/
3479             switch (direction) {
3480                 case PICOPAM_DIR_FORW:
3481                     /*do nothing*/
3482                     break;
3483                 case PICOPAM_DIR_BACK:
3484                     if (event_type == PICOPAM_EVENT_SYLL) {
3485                         if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1]
3486                                 == 1) || (pam->c3_primary_phrase_syllable >= 1)) {
3487                             if (pam->c3_overall_syllable < 1)
3488                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3]
3489                                         = 0;
3490                             else
3491                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3]
3492                                         = pam->sSyllFeats[pam->nCurrSyllable
3493                                                 + 1].phoneV[B3];
3494                         } else {
3495                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3] = 0;
3496                         }
3497                         pam->c3_primary_phrase_syllable++;
3498                         pam->c3_overall_syllable++;
3499                     }
3500                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3501                         pam->c3_primary_phrase_syllable = 0;
3502                     }
3503                     break;
3504             }
3505             break;
3506         case D2:/*processor for D2*/
3507             switch (direction) {
3508                 case PICOPAM_DIR_FORW:
3509                     if (event_type == PICOPAM_EVENT_SYLL) {
3510                         if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1]
3511                                 == 1) || (pam->d2_current_primary_phrase_word
3512                                 >= 1))
3513                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[D2]
3514                                     = pam->d2_prev_syllable_in_word;
3515                         else
3516                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[D2] = 0;
3517 
3518                         pam->d2_syllable_in_word++;
3519                     }
3520                     if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3521                             == PICOPAM_EVENT_S_BOUND) || (event_type
3522                             == PICOPAM_EVENT_P_BOUND)) {
3523                         pam->d2_current_primary_phrase_word = 1;
3524                         pam->d2_prev_syllable_in_word
3525                                 = pam->d2_syllable_in_word;
3526                         pam->d2_syllable_in_word = 0;
3527                         /*pam->d2_current_primary_phrase_word++;*/
3528                     }
3529                     if ((event_type == PICOPAM_EVENT_P_BOUND)) {
3530                         pam->d2_current_primary_phrase_word = 0;
3531                     }
3532                     break;
3533                 case PICOPAM_DIR_BACK:
3534                     /*do nothing*/
3535                     break;
3536             }
3537             break;
3538         case E1:/*processor for E1*/
3539             switch (direction) {
3540                 case PICOPAM_DIR_FORW: /*remember : content syllable indicator already on P5*/
3541                     if (event_type == PICOPAM_EVENT_SYLL) {
3542                         if (pam->e1_syllable_word_start == -1)
3543                             pam->e1_syllable_word_start
3544                                     = (picoos_int8) pam->nCurrSyllable;
3545                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] == 1)
3546                             pam->e1_content = 1;
3547                         pam->e1_syllable_word_end
3548                                 = (picoos_int8) pam->nCurrSyllable;
3549                     }
3550                     if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3551                             == PICOPAM_EVENT_S_BOUND) || (event_type
3552                             == PICOPAM_EVENT_P_BOUND)) {
3553                         if ((pam->e1_syllable_word_start != -1)
3554                                 && (pam->e1_syllable_word_end != -1)) {
3555                             for (nI = pam->e1_syllable_word_start; nI
3556                                     <= pam->e1_syllable_word_end; nI++)
3557                                 pam->sSyllFeats[nI].phoneV[E1]
3558                                         = pam->e1_content;
3559                         }
3560                         pam->e1_content = 0;
3561                         pam->e1_syllable_word_start = -1;
3562                         pam->e1_syllable_word_end = -1;
3563                     }
3564                     break;
3565                 case PICOPAM_DIR_BACK:
3566                     /*do nothing*/
3567                     break;
3568             }
3569             break;
3570         case E2:/*processor for E2*/
3571             switch (direction) {
3572                 case PICOPAM_DIR_FORW:
3573                     if (event_type == PICOPAM_EVENT_SYLL) {
3574                         if (pam->e2_syllable_word_start == -1)
3575                             pam->e2_syllable_word_start
3576                                     = (picoos_int8) pam->nCurrSyllable;
3577                         pam->e2_syllable_word_end
3578                                 = (picoos_int8) pam->nCurrSyllable;
3579                     }
3580                     if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3581                             == PICOPAM_EVENT_S_BOUND) || (event_type
3582                             == PICOPAM_EVENT_P_BOUND)) {
3583                         if ((pam->e2_syllable_word_start != -1)
3584                                 && (pam->e2_syllable_word_end != -1)) {
3585                             for (nI = pam->e2_syllable_word_start; nI
3586                                     <= pam->e2_syllable_word_end; nI++)
3587                                 pam->sSyllFeats[nI].phoneV[E2]
3588                                         = pam->e2_syllable_word_end
3589                                                 - pam->e2_syllable_word_start
3590                                                 + 1;
3591                         }
3592                         pam->e1_content = 0;
3593                         pam->e2_syllable_word_start = -1;
3594                         pam->e2_syllable_word_end = -1;
3595                     }
3596                     break;
3597                 case PICOPAM_DIR_BACK:
3598                     break;
3599             }
3600             break;
3601         case E3:/*processor for E3,E4*/
3602             switch (direction) {
3603                 case PICOPAM_DIR_FORW:
3604                     sDest = E3;
3605                     break;
3606                 case PICOPAM_DIR_BACK:
3607                     sDest = E4;
3608                     break;
3609                 default:
3610                     sDest = E3;
3611                     break;
3612             }
3613             switch (pam->e3_e4_state) {
3614                 case 0:
3615                     if (event_type == PICOPAM_EVENT_SYLL)
3616                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3617                                 = PICOPAM_DONT_CARE_VALUE;
3618                     if (event_type == PICOPAM_EVENT_S_BOUND) {
3619                         pam->e3_e4_word = 1;
3620                         pam->e3_e4_state = 1;
3621                     }
3622                     break;
3623                 case 1:
3624                     if (event_type == PICOPAM_EVENT_SYLL)
3625                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3626                                 = pam->e3_e4_word;
3627                     if (event_type == PICOPAM_EVENT_S_BOUND)
3628                         pam->e3_e4_word = 1;
3629                     if (event_type == PICOPAM_EVENT_W_BOUND)
3630                         pam->e3_e4_word++;
3631                     if (event_type == PICOPAM_EVENT_P_BOUND)
3632                         pam->e3_e4_state = 0;
3633                     break;
3634                 default:
3635                     break;
3636             }
3637             break;
3638         case E4:/*processor for E4 : done in E3*/
3639             break;
3640         case E5:/*processor for E5,E6*/
3641             switch (direction) {
3642                 case PICOPAM_DIR_FORW:
3643                     sDest = E5;
3644                     break;
3645                 case PICOPAM_DIR_BACK:
3646                     sDest = E6;
3647                     break;
3648                 default:
3649                     sDest = E5;
3650                     break;
3651             }
3652             if (event_type == PICOPAM_EVENT_SYLL) {
3653                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3654                         = pam->e5_e6_content_word;
3655                 if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] == 1)
3656                     pam->e5_e6_content = 1;
3657             }
3658             if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3659                     == PICOPAM_EVENT_S_BOUND) || (event_type
3660                     == PICOPAM_EVENT_P_BOUND)) {
3661                 if (pam->e5_e6_content == 1)
3662                     pam->e5_e6_content_word++;
3663                 pam->e5_e6_content = 0;
3664                 if (event_type == PICOPAM_EVENT_P_BOUND)
3665                     pam->e5_e6_content_word = 0;
3666             }
3667             break;
3668         case E6:/*processor for E6 : done in E5*/
3669             break;
3670         case E7:/*processor for E7,E8*/
3671             switch (direction) {
3672                 case PICOPAM_DIR_FORW:
3673                     sDest = E7;
3674                     break;
3675                 case PICOPAM_DIR_BACK:
3676                     sDest = E8;
3677                     break;
3678                 default:
3679                     sDest = E7;
3680                     break;
3681             }
3682             switch (pam->e7_e8_state) {
3683                 case 0:
3684                     if (event_type == PICOPAM_EVENT_SYLL) {
3685                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3686                                 = PICOPAM_DONT_CARE_VALUE;
3687                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] == 1)
3688                             pam->e7_e8_content = 1;
3689                     }
3690                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3691                         pam->e7_e8_content = 0;
3692                     }
3693 
3694                     if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3695                             == PICOPAM_EVENT_S_BOUND)) {
3696                         if (pam->e7_e8_content == 1) {
3697                             pam->e7_e8_word = 0;
3698                             pam->e7_e8_content = 0;
3699                             pam->e7_e8_state = 1;
3700                         }
3701                     }
3702                     break;
3703                 case 1:
3704                     if (event_type == PICOPAM_EVENT_SYLL) {
3705                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
3706                                 = pam->e7_e8_word;
3707                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] == 1)
3708                             pam->e7_e8_content = 1;
3709                     }
3710                     if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3711                             == PICOPAM_EVENT_S_BOUND)) {
3712                         if (pam->e7_e8_content == 1) {
3713                             pam->e7_e8_word = 0;
3714                             pam->e7_e8_content = 0;
3715                         } else {
3716                             pam->e7_e8_word++;
3717                         }
3718                     }
3719                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3720                         pam->e7_e8_state = 0;
3721                         pam->e7_e8_content = 0; /*<<<<<< added */
3722                     }
3723 
3724                 default:
3725                     break;
3726             }
3727             break;
3728         case E8:/*processor for E8 : done in E7*/
3729             break;
3730         case E9:
3731             /*processor for E9, E11*/
3732             switch (direction) {
3733                 case PICOPAM_DIR_FORW:
3734                     switch (pam->e9_e11_state) {
3735                         case 0:
3736                             if (event_type == PICOPAM_EVENT_SYLL) {
3737                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[E9]
3738                                         = PICOPAM_DONT_CARE_VALUE;
3739                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[E11]
3740                                         = pam->e9_e11_word;
3741                                 pam->e9_e11_saw_word = 1; /*new variable, needs to be initialized to 0*/
3742                             }
3743                             if (event_type == PICOPAM_EVENT_W_BOUND)
3744                                 pam->e9_e11_word++;
3745                             if (((event_type == PICOPAM_EVENT_P_BOUND)
3746                                     || (event_type == PICOPAM_EVENT_S_BOUND))
3747                                     && (pam->e9_e11_saw_word == 1)) { /* modified*/
3748                                 if (event_type == PICOPAM_EVENT_P_BOUND)
3749                                     pam->e9_e11_word = 1;
3750                                 else
3751                                     pam->e9_e11_word++; /*modified*/
3752                                 pam->e9_e11_state = 1;
3753                             }
3754                             break;
3755                         case 1:
3756                             if (event_type == PICOPAM_EVENT_SYLL) {
3757                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[E9]
3758                                         = pam->e9_e11_word;
3759                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[E11]
3760                                         = PICOPAM_DONT_CARE_VALUE;
3761                             }
3762                             if ((event_type == PICOPAM_EVENT_W_BOUND)
3763                                     || (event_type == PICOPAM_EVENT_S_BOUND))
3764                                 pam->e9_e11_word++;
3765                             if (event_type == PICOPAM_EVENT_P_BOUND)
3766                                 pam->e9_e11_word = 1;
3767                             break;
3768                         default:
3769                             break;
3770                     }
3771                     break;
3772                 case PICOPAM_DIR_BACK:
3773                     /*do nothing*/
3774                     break;
3775             }
3776             break;
3777         case E10:/*processor for E10, E12, E13 unified*/
3778             switch (direction) {
3779                 case PICOPAM_DIR_FORW:/*do nothing*/
3780                     break;
3781                 case PICOPAM_DIR_BACK:
3782                     switch (pam->e10_e12_e13_state) {
3783                         case 0:
3784                             if (event_type == PICOPAM_EVENT_SYLL) {
3785                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[E10]
3786                                         = PICOPAM_DONT_CARE_VALUE;
3787                                 pam->e10_e12_e13_saw_word = 1;
3788                                 if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
3789                                         == PICOPAM_DECLARATIVE) {
3790                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
3791                                             = pam->e10_e12_e13_word;
3792                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
3793                                             = PICOPAM_DONT_CARE_VALUE;
3794                                 } else {
3795                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
3796                                             = PICOPAM_DONT_CARE_VALUE;
3797                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
3798                                             = pam->e10_e12_e13_word;
3799                                 }
3800                             }
3801                             if (event_type == PICOPAM_EVENT_W_BOUND)
3802                                 pam->e10_e12_e13_word++;
3803 
3804                             /*if (((event_type==PICOPAM_EVENT_P_BOUND)||(event_type==PICOPAM_EVENT_S_BOUND))&&(pam->e10_e12_e13_word>1))    {*/
3805                             if (((event_type == PICOPAM_EVENT_P_BOUND)
3806                                     || (event_type == PICOPAM_EVENT_S_BOUND))
3807                                     && (pam->e10_e12_e13_saw_word > 0)) {
3808                                 if (event_type == PICOPAM_EVENT_P_BOUND)
3809                                     pam->e10_e12_e13_word = 1;
3810                                 else
3811                                     pam->e10_e12_e13_word++;
3812                                 pam->e10_e12_e13_state = 1;
3813                             }
3814                             break;
3815                         case 1:
3816                             if (event_type == PICOPAM_EVENT_SYLL) {
3817                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[E10]
3818                                         = pam->e10_e12_e13_word;
3819                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
3820                                         = PICOPAM_DONT_CARE_VALUE;
3821                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
3822                                         = PICOPAM_DONT_CARE_VALUE;
3823                             }
3824                             if ((event_type == PICOPAM_EVENT_W_BOUND)
3825                                     || (event_type == PICOPAM_EVENT_S_BOUND))
3826                                 pam->e10_e12_e13_word++;
3827                             if (event_type == PICOPAM_EVENT_P_BOUND)
3828                                 pam->e10_e12_e13_word = 1;
3829                             break;
3830                         default:
3831                             break;
3832                     }
3833                     break;
3834             }
3835             break;
3836 
3837         case E11:/*processor for E11 : done in E9*/
3838             break;
3839         case E12:/*processor for E12 : done in E10*/
3840             break;
3841         case E13:/*processor for E13 : done in E10*/
3842             break;
3843 
3844         case F2:
3845             switch (direction) {
3846                 case PICOPAM_DIR_FORW:/*do nothing*/
3847                     break;
3848                 case PICOPAM_DIR_BACK:
3849                     if (event_type == PICOPAM_EVENT_SYLL) {
3850                         if (pam->f2_current_primary_phrase_word >= 1)/*at least second word in current primary phrase*/
3851                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[F2]
3852                                     = pam->f2_next_word_syllable;
3853                         else
3854                             /*first word in current primary phrase*/
3855                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[F2] = 0;
3856                         pam->f2_word_syllable++;
3857                     }
3858                     if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3859                             == PICOPAM_EVENT_S_BOUND) || (event_type
3860                             == PICOPAM_EVENT_P_BOUND)) {/*word - end : switch*/
3861                         pam->f2_next_word_syllable = pam->f2_word_syllable;
3862                         pam->f2_word_syllable = 0;
3863                     }
3864                     if (event_type == PICOPAM_EVENT_P_BOUND)/*mark first word in current primary phrase*/
3865                         pam->f2_current_primary_phrase_word = 0;
3866                     else /*mark next word in current primary phrase(enables output in PICOPAM_EVENT_SYLL)*/
3867                     if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
3868                             == PICOPAM_EVENT_S_BOUND))
3869                         pam->f2_current_primary_phrase_word++;
3870                     break;
3871             }
3872             break;
3873         case G1:
3874             switch (direction) {
3875                 case PICOPAM_DIR_FORW:
3876                     if (event_type == PICOPAM_EVENT_SYLL) {
3877                         if (pam->g1_current_secondary_phrase_syllable > 0)
3878                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[G1]
3879                                     = pam->g1_current_secondary_phrase_syllable;
3880                         else
3881                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[G1] = 0;
3882                         pam->g1_current_syllable++;
3883                     }
3884                     if (event_type == PICOPAM_EVENT_S_BOUND) {
3885                         pam->g1_current_secondary_phrase_syllable
3886                                 = pam->g1_current_syllable;
3887                         pam->g1_current_syllable = 0;
3888                     }
3889                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3890                         pam->g1_current_secondary_phrase_syllable = 0;
3891                         pam->g1_current_syllable = 0;
3892                     }
3893                 case PICOPAM_DIR_BACK: /*do nothing*/
3894                     break;
3895             }
3896             break;
3897         case G2:
3898             switch (direction) {
3899                 case PICOPAM_DIR_FORW:
3900                     if (event_type == PICOPAM_EVENT_SYLL) {
3901                         if (pam->g2_current_secondary_phrase_word > 0)
3902                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[G2]
3903                                     = pam->g2_current_secondary_phrase_word;
3904                         else
3905                             pam->sSyllFeats[pam->nCurrSyllable].phoneV[G2] = 0;
3906                     }
3907                     if (event_type == PICOPAM_EVENT_W_BOUND)
3908                         pam->g2_current_word++;
3909 
3910                     if (event_type == PICOPAM_EVENT_S_BOUND) {
3911                         pam->g2_current_secondary_phrase_word
3912                                 = pam->g2_current_word + 1;
3913                         pam->g2_current_word = 0;
3914                     }
3915                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3916                         pam->g2_current_secondary_phrase_word = 0;
3917                         pam->g2_current_word = 0;
3918                     }
3919                     break;
3920                 case PICOPAM_DIR_BACK: /*do nothing*/
3921                     break;
3922             }
3923             break;
3924         case H1:
3925             switch (direction) {
3926                 case PICOPAM_DIR_FORW:
3927                     if (event_type == PICOPAM_EVENT_SYLL) {
3928                         pam->h1_current_secondary_phrase_syll++;
3929                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1]
3930                                 = pam->h1_current_secondary_phrase_syll;
3931                     }
3932                     if ((event_type == PICOPAM_EVENT_S_BOUND) || (event_type
3933                             == PICOPAM_EVENT_P_BOUND))
3934                         pam->h1_current_secondary_phrase_syll = 0;
3935                     break;
3936                 case PICOPAM_DIR_BACK:
3937                     if (event_type == PICOPAM_EVENT_SYLL)
3938                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1]
3939                                 = pam->h1_current_secondary_phrase_syll;
3940                     if (event_type == PICOPAM_EVENT_S_BOUND)
3941                         pam->h1_current_secondary_phrase_syll
3942                                 = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1];
3943                     if (event_type == PICOPAM_EVENT_P_BOUND)
3944                         pam->h1_current_secondary_phrase_syll
3945                                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H1];
3946                     break;
3947             }
3948             break;
3949         case H2:
3950             switch (direction) {
3951                 case PICOPAM_DIR_FORW:
3952                     if (event_type == PICOPAM_EVENT_SYLL) {
3953                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
3954                                 = pam->h2_current_secondary_phrase_word;
3955                     }
3956                     if (event_type == PICOPAM_EVENT_W_BOUND) {
3957                         pam->h2_current_secondary_phrase_word++;
3958                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
3959                                 = pam->h2_current_secondary_phrase_word;
3960                     }
3961                     if (event_type == PICOPAM_EVENT_S_BOUND) {
3962                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
3963                                 = pam->h2_current_secondary_phrase_word + 1;
3964                         pam->h2_current_secondary_phrase_word = 0;
3965                     }
3966                     if (event_type == PICOPAM_EVENT_P_BOUND) {
3967                         if (pam->nCurrSyllable > 1)
3968                             pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H2]
3969                                     = pam->h2_current_secondary_phrase_word + 1;
3970                         pam->h2_current_secondary_phrase_word = 0;
3971                     }
3972                     break;
3973                 case PICOPAM_DIR_BACK:
3974                     if (event_type == PICOPAM_EVENT_SYLL)
3975                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
3976                                 = pam->h2_current_secondary_phrase_word;
3977                     if (event_type == PICOPAM_EVENT_S_BOUND)
3978                         pam->h2_current_secondary_phrase_word
3979                                 = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2];
3980                     if (event_type == PICOPAM_EVENT_P_BOUND)
3981                         pam->h2_current_secondary_phrase_word
3982                                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H2];
3983                     break;
3984             }
3985             break;
3986         case H3:/*processor for H3,H4 unified */
3987             switch (direction) {
3988                 case PICOPAM_DIR_FORW:
3989                     sDest = H3;
3990                     break;
3991                 case PICOPAM_DIR_BACK:
3992                     sDest = H4;
3993                     break;
3994                 default:
3995                     sDest = H3;
3996                     break;
3997             }
3998             if (event_type == PICOPAM_EVENT_SYLL) {
3999                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[sDest]
4000                         = pam->h3_h4_current_secondary_phrase_word;
4001             }
4002             if ((event_type == PICOPAM_EVENT_S_BOUND) || (event_type
4003                     == PICOPAM_EVENT_P_BOUND))
4004                 pam->h3_h4_current_secondary_phrase_word++;
4005             break;
4006         case H4: /*processor for H4 : already in H3*/
4007             break;
4008 
4009         case H5:/*processor for H5*/
4010             switch (direction) {
4011                 case PICOPAM_DIR_FORW:
4012                     break;
4013                 case PICOPAM_DIR_BACK:
4014                     switch (pam->h5_state) {
4015                         case 0:
4016                             if (event_type == PICOPAM_EVENT_SYLL)
4017                                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5]
4018                                         = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5];
4019                             if (event_type == PICOPAM_EVENT_S_BOUND) {
4020                                 pam->h5_state = 1;
4021                             }
4022                             break;
4023                         case 1:
4024                             if (event_type == PICOPAM_EVENT_SYLL) {
4025                                 if ((pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5]
4026                                         == PICOPAM_P)
4027                                         && (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1]
4028                                                 == 0))
4029                                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5]
4030                                             = PICOPAM_p;
4031                             }
4032                             if (event_type == PICOPAM_EVENT_P_BOUND) {
4033                                 pam->h5_state = 0;
4034                             }
4035                             break;
4036                         default:
4037                             break;
4038                     }
4039                     break;
4040 
4041                 default:
4042                     break;
4043             }
4044             break;
4045 
4046         case I1:/*processor for I1*/
4047             switch (direction) {
4048                 case PICOPAM_DIR_FORW:
4049                     if (event_type == PICOPAM_EVENT_SYLL) {
4050                         pam->i1_secondary_phrase_syllable++;
4051                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1]
4052                                 = pam->i1_secondary_phrase_syllable;
4053                     }
4054                     if ((event_type == PICOPAM_EVENT_S_BOUND) || (event_type
4055                             == PICOPAM_EVENT_P_BOUND))
4056                         pam->i1_secondary_phrase_syllable = 0;
4057                     break;
4058                 case PICOPAM_DIR_BACK:
4059                     if (event_type == PICOPAM_EVENT_SYLL) {
4060                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1]
4061                                 = pam->i1_next_secondary_phrase_syllable;
4062                     }
4063                     if (event_type == PICOPAM_EVENT_S_BOUND) {
4064                         pam->i1_next_secondary_phrase_syllable
4065                                 = pam->i1_secondary_phrase_syllable;
4066                         pam->i1_secondary_phrase_syllable
4067                                 = pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1];
4068                     }
4069                     if (event_type == PICOPAM_EVENT_P_BOUND) {
4070                         pam->i1_next_secondary_phrase_syllable = 0;
4071                         pam->i1_secondary_phrase_syllable
4072                                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[I1];
4073                     }
4074                     break;
4075             }
4076             break;
4077         case I2: /*processor for I2*/
4078             switch (direction) {
4079                 case PICOPAM_DIR_FORW:
4080                     if (event_type == PICOPAM_EVENT_SYLL) {
4081                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2]
4082                                 = pam->i2_secondary_phrase_word;
4083                     }
4084                     if (event_type == PICOPAM_EVENT_W_BOUND)
4085                         pam->i2_secondary_phrase_word++;
4086 
4087                     if ((event_type == PICOPAM_EVENT_P_BOUND) || (event_type
4088                             == PICOPAM_EVENT_S_BOUND))
4089                         pam->i2_secondary_phrase_word = 1;
4090 
4091                     break;
4092                 case PICOPAM_DIR_BACK:
4093                     if (event_type == PICOPAM_EVENT_SYLL) {
4094                         pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2]
4095                                 = pam->i2_next_secondary_phrase_word;
4096                     }
4097                     if (event_type == PICOPAM_EVENT_S_BOUND) {
4098                         pam->i2_next_secondary_phrase_word
4099                                 = pam->i2_secondary_phrase_word;
4100                         pam->i2_secondary_phrase_word
4101                                 = pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2];
4102                     }
4103                     if (event_type == PICOPAM_EVENT_P_BOUND) {
4104                         pam->i2_next_secondary_phrase_word = 0;
4105                         pam->i2_secondary_phrase_word
4106                                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[I2];
4107                     }
4108                     break;
4109             }
4110             break;
4111         case J1: /*processor for J1 */
4112             switch (direction) {
4113                 case PICOPAM_DIR_FORW:
4114                     if (event_type == PICOPAM_EVENT_SYLL) {
4115                         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1] != 1)
4116                             pam->j1_utterance_syllable++;
4117                     }
4118                     break;
4119                 case PICOPAM_DIR_BACK:
4120                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[J1]
4121                             = pam->j1_utterance_syllable;
4122                     break;
4123             }
4124             break;
4125         case J2: /*processor for J2*/
4126             switch (direction) {
4127                 case PICOPAM_DIR_FORW:
4128                     if ((event_type == PICOPAM_EVENT_W_BOUND) || (event_type
4129                             == PICOPAM_EVENT_S_BOUND) || (event_type
4130                             == PICOPAM_EVENT_P_BOUND))
4131                         pam->j2_utterance_word++;
4132                     break;
4133                 case PICOPAM_DIR_BACK:
4134                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[J2]
4135                             = pam->j2_utterance_word - 1;
4136                     break;
4137             }
4138             break;
4139         case J3: /*processor for J3*/
4140             switch (direction) {
4141                 case PICOPAM_DIR_FORW:
4142                     if (event_type == PICOPAM_EVENT_S_BOUND) {
4143                         pam->j3_utterance_sec_phrases++;
4144                         break;
4145                     }
4146                     if (event_type == PICOPAM_EVENT_P_BOUND) {
4147                         pam->j3_utterance_sec_phrases++;
4148                         break;
4149                     }
4150                     break;
4151                 case PICOPAM_DIR_BACK:
4152                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[J3]
4153                             = pam->j3_utterance_sec_phrases - 1;
4154                     break;
4155             }
4156             break;
4157     }
4158     return PICO_OK;
4159 }/*pam_process_event_feature*/
4160 
4161 /**
4162  * processes an input event spanning it to all column features
4163  * @param    this : pointer to PAM PU sub object pointer
4164  * @param    event_type : event id among syll/boundprim/boundsec/boundword
4165  * @param    direction : forward(0)/backward(1)
4166  * @return    PICO_OK : process OK
4167  * @return    PICO_ERR_OTHER : errors on getting pam sub obj pointer
4168  * @callgraph
4169  * @callergraph
4170  */
pam_process_event(register picodata_ProcessingUnit this,picoos_uint8 event_type,picoos_uint8 direction)4171 static pico_status_t pam_process_event(register picodata_ProcessingUnit this,
4172         picoos_uint8 event_type, picoos_uint8 direction)
4173 {
4174     picoos_uint8 nFeat;
4175     pico_status_t nResult;
4176 
4177     pam_subobj_t *pam;
4178     if (NULL == this || NULL == this->subObj) {
4179         return PICO_ERR_OTHER;
4180     }
4181     pam = (pam_subobj_t *) this->subObj;
4182 
4183     if (direction == PICOPAM_DIR_FORW) {
4184         if (event_type == PICOPAM_EVENT_P_BOUND)
4185             /*primary boundary*/
4186             pam->sSyllFeats[pam->nCurrSyllable].phoneV[P2] = 1;
4187         if (event_type == PICOPAM_EVENT_S_BOUND)
4188             /*secondary boundary*/
4189             pam->sSyllFeats[pam->nCurrSyllable].phoneV[P3] = 1;
4190         if (event_type == PICOPAM_EVENT_W_BOUND)
4191             /*word boundary*/
4192             pam->sSyllFeats[pam->nCurrSyllable].phoneV[P4] = 1;
4193     }
4194     for (nFeat = A3; nFeat <= J3; nFeat++) {
4195         nResult = pam_process_event_feature(this, nFeat, event_type, direction);
4196         if (nResult != PICO_OK)
4197             return nResult;
4198     }
4199     return PICO_OK;
4200 }/*pam_process_event*/
4201 
4202 /**
4203  * inserts a syllable inside the subobj sentence data struct.
4204  * @param    this : pointer to PAM PU sub object pointer
4205  * @param    syllType  : the syllable type (pause/syllable)
4206  * @param    sContent : the item content
4207  * @param    sentType : the sentence type
4208  * @param    phType : the phrase type
4209  * @param    uBoundType : the boundary type (only for silence syllables)
4210  * @param    uMinDur, uMaxDur : the mimimum and maximum duration (only for silence syllables)
4211  * @return    PICO_OK : syllable creation successful
4212  * @return    PICO_ERR_OTHER : errors in one internal function (check_phones_size..)
4213  * @callgraph
4214  * @callergraph
4215  */
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)4216 static pico_status_t pam_create_syllable(register picodata_ProcessingUnit this,
4217         picoos_uint8 syllType, picoos_uint8 *sContent, picoos_uint8 sentType,
4218         picoos_uint8 phType, picoos_uint8 uBoundType, picoos_uint16 uMinDur,
4219         picoos_uint16 uMaxDur)
4220 {
4221     pam_subobj_t *pam;
4222     picoos_uint8 nI;
4223     picoos_uint8 pos;
4224     /* picoos_uint8    *npUi16; */
4225     picoos_uint32 pos32;
4226 
4227     if (NULL == this || NULL == this->subObj) {
4228         return PICO_ERR_OTHER;
4229     }
4230     pam = (pam_subobj_t *) this->subObj;
4231     pos = 0;
4232     /*check buffer full condition on number of syllables*/
4233     if (check_syllables_size(pam, 1) != PICO_OK) {
4234         return PICO_ERR_OTHER;
4235     }
4236 
4237     if (syllType == PICOPAM_SYLL_PAUSE) {
4238         /*check buffer full condition on number of phonemes*/
4239         if (check_phones_size(pam, 1) != PICO_OK) {
4240             return PICO_ERR_OTHER;
4241         }
4242     }
4243     if (syllType == PICOPAM_SYLL_SYLL) {
4244         /*check item availability*/
4245         if (sContent == NULL) {
4246             return PICO_ERR_OTHER;
4247         }
4248         /*check buffer full condition  on number of phonemes*/
4249         if (check_phones_size(pam, sContent[3]) != PICO_OK) {
4250             return PICO_ERR_OTHER;
4251         }
4252     }
4253 
4254     /*open new syllable*/
4255     pam->nCurrSyllable = pam->nCurrSyllable + 1;
4256     /*cleanup*/
4257     for (nI = 0; nI < PICOPAM_VECT_SIZE; nI++) {
4258         if (pam->nCurrSyllable > 0) {
4259             pam->sSyllFeats[pam->nCurrSyllable].phoneV[nI] = 0;
4260         } else {
4261             if ((nI >= ITM) && (nI <= itm)) {
4262                 if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[nI] > 0) {
4263                     /*do not cleanup "attached item offset" fields (ITM, itm):
4264                      an already existing attached item could be lost*/
4265                 } else {
4266                     /*cleanup "attached item offset"*/
4267                     pam->sSyllFeats[pam->nCurrSyllable].phoneV[nI] = 0;
4268                 }
4269             } else {
4270                 /*cleanup all fields except "attached item offset" (ITM, itm)*/
4271                 pam->sSyllFeats[pam->nCurrSyllable].phoneV[nI] = 0;
4272             }
4273         }
4274     }
4275     /*set minimum and maximum duration values*/
4276     if ((uMinDur == 0) && (uMaxDur == 0) && (syllType == PICOPAM_SYLL_PAUSE)) {
4277         /*both 0 : use default duration limits for boundaries*/
4278         get_default_boundary_limit(uBoundType, &uMinDur, &uMaxDur);
4279     }
4280     if (uMinDur > 0) {
4281         pos32 = Min;
4282         picoos_write_mem_pi_uint16(pam->sSyllFeats[pam->nCurrSyllable].phoneV,
4283                 &pos32, uMinDur);
4284     }
4285     if (uMaxDur > 0) {
4286         pos32 = Max;
4287         picoos_write_mem_pi_uint16(pam->sSyllFeats[pam->nCurrSyllable].phoneV,
4288                 &pos32, uMaxDur);
4289     }
4290     /*END OF BREAK COMMAND SUPPORT*/
4291 
4292     if (syllType == PICOPAM_SYLL_PAUSE) {
4293         /*initialize a pause syllable*/
4294         if (sentType == PICOPAM_DECLARATIVE)
4295             pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
4296                     = PICOPAM_DECLARATIVE;
4297         if (sentType == PICOPAM_INTERROGATIVE)
4298             pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
4299                     = PICOPAM_INTERROGATIVE;
4300 
4301         pam->sSyllFeats[pam->nCurrSyllable].phoneV[bnd] = uBoundType;
4302         pam->sSyllFeats[pam->nCurrSyllable].phoneV[P1] = 1; /*this means the syllable contains a pause-silence*/
4303         pam->sSyllFeats[pam->nCurrSyllable].phoneV[P8] = 1;
4304 
4305         /*b1,b2,b9,b11,b13,b15,e1,e6,e8,e10 already set to 0*/
4306 
4307         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3]
4308                 = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B4]
4309                         = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B5]
4310                                 = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B6]
4311                                         = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B7]
4312                                                 = 1;
4313 
4314         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B16]
4315                 = PICOPAM_PH_DONT_CARE_VAL; /*name of the vowel in the syllable = NONE */
4316 
4317         pam->sSyllFeats[pam->nCurrSyllable].phoneV[E2]
4318                 = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E3]
4319                         = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E4] = 1;
4320 
4321         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5] = phType;
4322 
4323         /*Store current phonetic codes in input phonetic string*/
4324         pam->sPhIds[pam->nCurrPhoneme] = pam_get_pause_id(this);
4325         picoos_mem_copy((void*) &pam->nCurrPhoneme,
4326                 &(pam->sSyllFeats[pam->nCurrSyllable].phoneV[FID]),
4327                 sizeof(pam->nCurrPhoneme));
4328         pam->nCurrPhoneme++;
4329         pam->nTotalPhonemes++;
4330         /*add 1 to total number of syllables*/
4331         pam->nTotalSyllables++;
4332 
4333         return PICO_OK;
4334     }
4335     if (syllType == PICOPAM_SYLL_SYLL) {
4336         /*initialize a real syllable*/
4337         if (sContent[2] > PICODATA_ACC0)
4338             pam->sSyllFeats[pam->nCurrSyllable].phoneV[P5] = 1; /*set content syllable indicator*/
4339         if (sentType == PICOPAM_DECLARATIVE)
4340             pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
4341                     = PICOPAM_DECLARATIVE;
4342         if (sentType == PICOPAM_INTERROGATIVE)
4343             pam->sSyllFeats[pam->nCurrSyllable].phoneV[P6]
4344                     = PICOPAM_INTERROGATIVE;
4345 
4346         if ((sContent[2] >= PICODATA_ACC1) && (sContent[2] <= PICODATA_ACC4))
4347             /*stressed*/
4348             pam->sSyllFeats[pam->nCurrSyllable].phoneV[B1] = 1;
4349 
4350         if ((sContent[2] >= PICODATA_ACC1) && (sContent[2] <= PICODATA_ACC2))
4351             /*accented*/
4352             pam->sSyllFeats[pam->nCurrSyllable].phoneV[B2] = 1;
4353 
4354         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B3] = sContent[3];/*len*/
4355 
4356         if (pam->nCurrSyllable > 30)
4357             pam->nCurrSyllable = pam->nCurrSyllable;
4358 
4359         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B16] = pam_get_vowel_name(this,
4360                 sContent, &pos); /*name of the vowel in the syllable*/
4361 
4362         pam->sSyllFeats[pam->nCurrSyllable].phoneV[P8] = pos; /*temp for storing the position of the vowel*/
4363 
4364         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5] = phType;
4365 
4366         /*Store current phonetic codes in input phonetic string*/
4367         picoos_mem_copy((void*) &pam->nCurrPhoneme,
4368                 &(pam->sSyllFeats[pam->nCurrSyllable].phoneV[FID]),
4369                 sizeof(pam->nCurrPhoneme));
4370         for (nI = 0; nI < sContent[3]; nI++)
4371             pam->sPhIds[pam->nCurrPhoneme + nI] = sContent[4 + nI];
4372         pam->nCurrPhoneme += nI;
4373         pam->nTotalPhonemes += nI;
4374         /*add 1 to total number of syllables*/
4375         pam->nTotalSyllables++;
4376         return PICO_OK;
4377     }
4378     /*if no SyllType has been identified -->> error*/
4379     return PICO_ERR_OTHER;
4380 }/*pam_create_syllable*/
4381 
4382 /**
4383  * performs the forward step of the PAM adapter
4384  * @param    this : pointer to PAM PU sub object pointer
4385  * @param    itemBase : pointer to current item
4386  * @return    PICOPAM_READY : forward step ok, the sentence is complete
4387  * @return  PICOPAM_MORE : forward step ok, but more data needed to complete the sentence
4388  * @return    PICO_ERR_OTHER : errors in one internal function (CreateSyllable..)
4389  * @callgraph
4390  * @callergraph
4391  */
pam_adapter_forward_step(register picodata_ProcessingUnit this,picoos_uint8 * itemBase)4392 static pico_status_t pam_adapter_forward_step(
4393         register picodata_ProcessingUnit this, picoos_uint8 *itemBase)
4394 {
4395     register pam_subobj_t * pam;
4396     pico_status_t sResult;
4397     picoos_uint16 uMinDur, uMaxDur;
4398     picoos_uint32 nPos;
4399 
4400     if (NULL == this || NULL == this->subObj) {
4401         return PICO_ERR_OTHER;
4402     }
4403     pam = (pam_subobj_t *) this->subObj;
4404     uMinDur = uMaxDur = 0; /*default 0 : not initialized*/
4405     switch (itemBase[0]) {
4406         case PICODATA_ITEM_BOUND:
4407             /*received a boundary item*/
4408             switch (itemBase[1]) {
4409                 case PICODATA_ITEMINFO1_BOUND_SBEG:
4410                 case PICODATA_ITEMINFO1_BOUND_PHR1:
4411 #ifdef PAM_PHR2_WITH_PR1
4412                 case PICODATA_ITEMINFO1_BOUND_PHR2:
4413 #endif
4414                 case PICODATA_ITEMINFO1_BOUND_SEND:
4415                 case PICODATA_ITEMINFO1_BOUND_TERM:
4416                     if (itemBase[3] == 2 * sizeof(picoos_uint16)) {
4417                         /*only when the item len duration is equal to 2 int16 --> get the values*/
4418                         nPos = 4;
4419                         picoos_read_mem_pi_uint16(itemBase, &nPos, &uMinDur);
4420                         picoos_read_mem_pi_uint16(itemBase, &nPos, &uMaxDur);
4421                     }
4422                     break;
4423                 default:
4424                     break;
4425             }
4426             switch (itemBase[1]) {
4427                 case PICODATA_ITEMINFO1_BOUND_SBEG:
4428                     /* received a sentence init boundary */
4429                     pam_reset_processors(this); /*reset all processor variables*/
4430                     pam->sType
4431                             = pam_map_sentence_type(itemBase[1], itemBase[2]);
4432                     pam->pType = pam_map_phrase_type(itemBase[1], itemBase[2]);
4433                     /*create silence syll and process P_BOUND event*/
4434                     sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
4435                             pam->sType, pam->pType, itemBase[1], uMinDur,
4436                             uMaxDur);
4437                     if (sResult != PICO_OK)
4438                         return sResult;
4439                     sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
4440                             PICOPAM_DIR_FORW);
4441                     if (sResult != PICO_OK)
4442                         return sResult;
4443                     return PICOPAM_MORE;
4444                     break;
4445 
4446                 case PICODATA_ITEMINFO1_BOUND_PHR1:
4447 #ifdef PAM_PHR2_WITH_PR1
4448                 case PICODATA_ITEMINFO1_BOUND_PHR2:
4449 #endif
4450                     /*received a primary boundary*/
4451                     pam->sType
4452                             = pam_map_sentence_type(itemBase[1], itemBase[2]);
4453                     pam->pType = pam_map_phrase_type(itemBase[1], itemBase[2]);
4454                     /*create silence syll and process P_BOUND event*/
4455                     sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
4456                             pam->sType, pam->pType, itemBase[1], uMinDur,
4457                             uMaxDur);
4458                     if (sResult != PICO_OK)
4459                         return sResult;
4460                     sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
4461                             PICOPAM_DIR_FORW);
4462                     if (sResult != PICO_OK)
4463                         return sResult;
4464                     return PICOPAM_MORE;
4465                     break;
4466 
4467 #ifdef PAM_PHR2_WITH_PR3
4468                     case PICODATA_ITEMINFO1_BOUND_PHR2 :
4469 #endif
4470                 case PICODATA_ITEMINFO1_BOUND_PHR3:
4471                     /*received a secondary boundary*/
4472                     /*process S_BOUND event*/
4473                     sResult = pam_process_event(this, PICOPAM_EVENT_S_BOUND,
4474                             PICOPAM_DIR_FORW);
4475                     /*determine new sentence and Phrase types for following syllables*/
4476                     pam->sType
4477                             = pam_map_sentence_type(itemBase[1], itemBase[2]);
4478                     pam->pType = pam_map_phrase_type(itemBase[1], itemBase[2]);
4479                     if (sResult != PICO_OK)
4480                         return sResult;
4481                     return PICOPAM_MORE;
4482                     break;
4483 
4484                 case PICODATA_ITEMINFO1_BOUND_PHR0:
4485                     /*received a word end boundary*/
4486                     /*process W_BOUND event*/
4487                     sResult = pam_process_event(this, PICOPAM_EVENT_W_BOUND,
4488                             PICOPAM_DIR_FORW);
4489                     if (sResult != PICO_OK)
4490                         return sResult;
4491                     return PICOPAM_MORE;
4492                     break;
4493 
4494                 case PICODATA_ITEMINFO1_BOUND_SEND:
4495                     /*received a SEND boundary*/
4496                     /*insert a new silence syllable and process P_BOUND event*/
4497                     /*create silence syll and process P_BOUND event*/
4498                     sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
4499                             pam->sType, pam->pType, itemBase[1], uMinDur,
4500                             uMaxDur);
4501                     if (sResult != PICO_OK)
4502                         return sResult;
4503                     sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
4504                             PICOPAM_DIR_FORW);
4505                     if (sResult != PICO_OK)
4506                         return sResult;
4507                     return PICOPAM_READY;
4508                     break;
4509 
4510                 case PICODATA_ITEMINFO1_BOUND_TERM:
4511                     /* received a flush boundary*/
4512                     if (pam->nCurrSyllable == -1) {
4513                         return PICOPAM_NA;
4514                     }
4515                     /*insert a new silence syllable and process P_BOUND event*/
4516                     /*create silence syll and process P_BOUND event*/
4517                     sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
4518                             pam->sType, pam->pType, itemBase[1], uMinDur,
4519                             uMaxDur);
4520                     if (sResult != PICO_OK)
4521                         return sResult;
4522                     sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
4523                             PICOPAM_DIR_FORW);
4524                     if (sResult != PICO_OK)
4525                         return sResult;
4526                     return PICOPAM_READY;
4527                     break;
4528 
4529                 default:
4530                     /*boundary type not known*/
4531                     return PICOPAM_NA;
4532                     break;
4533             }/*end switch (itemBase[1])*/
4534             break; /*end case PICODATA_ITEM_BOUND*/
4535 
4536         case PICODATA_ITEM_SYLLPHON:
4537             /*received a syllable item*/
4538             /*    ------------------------------------------------------------------
4539              following code has to be used if we do expect
4540              SYLL items arrive even without SBEG items starting the sentence.
4541              this may happen after a term has been issued to make room in local storage.
4542              */
4543             if (pam->nCurrSyllable == -1) {
4544                 pam_reset_processors(this);
4545                 /*insert an SBEG with sType and pType taken from previous sentence*/
4546                 sResult = pam_create_syllable(this, PICOPAM_SYLL_PAUSE, NULL,
4547                         pam->sType, pam->pType, PICODATA_ITEMINFO1_BOUND_SBEG,
4548                         0, 0);
4549                 if (sResult != PICO_OK)
4550                     return sResult;
4551                 sResult = pam_process_event(this, PICOPAM_EVENT_P_BOUND,
4552                         PICOPAM_DIR_FORW);
4553                 if (sResult != PICO_OK)
4554                     return sResult;
4555             }
4556             /* ------------------------------------------------------------------*/
4557             sResult = pam_create_syllable(this, PICOPAM_SYLL_SYLL, itemBase,
4558                     pam->sType, pam->pType, 0, 0, 0);
4559             if (sResult != PICO_OK)
4560                 return sResult;
4561             sResult = pam_process_event(this, PICOPAM_EVENT_SYLL,
4562                     PICOPAM_DIR_FORW);
4563             if (sResult != PICO_OK)
4564                 return sResult;
4565             return PICOPAM_MORE;
4566             break;
4567 
4568         default:
4569             return PICOPAM_NA;
4570             break;
4571     }
4572     return PICO_ERR_OTHER;
4573 }/*pam_adapter_forward_step*/
4574 
4575 /**
4576  * performs the backward step of the PAM adapter
4577  * @param    this : pointer to PAM PU sub object pointer
4578  * @return    PICO_OK : backward step complete
4579  * @return  PICO_ERR_OTHER : errors on retrieving the PU pointer
4580  * @remarks derived in some parts from the pam forward code
4581  * @callgraph
4582  * @callergraph
4583  */
pam_adapter_backward_step(register picodata_ProcessingUnit this)4584 static pico_status_t pam_adapter_backward_step(
4585         register picodata_ProcessingUnit this)
4586 {
4587     register pam_subobj_t * pam;
4588     picoos_uint8 nProcessed;
4589     picoos_uint16 nSyll;
4590 
4591     if (NULL == this || NULL == this->subObj) {
4592         return PICO_ERR_OTHER;
4593     }
4594     pam = (pam_subobj_t *) this->subObj;
4595 
4596     /*Resets the processors for the backward step*/
4597     pam_reset_processors_back(this);
4598     /*Do the backward step*/
4599     nSyll = pam->nCurrSyllable;
4600     while (pam->nCurrSyllable >= 0) {
4601         nProcessed = 0;
4602         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P2] == 1) {
4603             /*primary boundary*/
4604             pam_process_event(this, PICOPAM_EVENT_P_BOUND, PICOPAM_DIR_BACK);
4605             pam->nCurrSyllable--;
4606             nProcessed = 1;
4607         }
4608         if ((nProcessed == 0)
4609                 && (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P3] == 1)) {
4610             /*secondary boundary*/
4611             pam_process_event(this, PICOPAM_EVENT_S_BOUND, PICOPAM_DIR_BACK);
4612             pam_process_event(this, PICOPAM_EVENT_SYLL, PICOPAM_DIR_BACK);
4613             pam->nCurrSyllable--;
4614             nProcessed = 1;
4615         }
4616         if ((nProcessed == 0)
4617                 && (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P4] == 1)) {
4618             /*word boundary*/
4619             pam_process_event(this, PICOPAM_EVENT_W_BOUND, PICOPAM_DIR_BACK);
4620             pam_process_event(this, PICOPAM_EVENT_SYLL, PICOPAM_DIR_BACK);
4621             pam->nCurrSyllable--;
4622             nProcessed = 1;
4623         }
4624         if (nProcessed == 0) {
4625             /*non boundaried syllable*/
4626             pam_process_event(this, PICOPAM_EVENT_SYLL, PICOPAM_DIR_BACK);
4627             pam->nCurrSyllable--;
4628             nProcessed = 0;
4629         }
4630     }/*end while (pam->nCurrSyllable>=0)*/
4631     /*reset syllpointer to original value*/
4632     pam->nCurrSyllable = nSyll;
4633     /*Perform pause processing*/
4634     pam_adapter_do_pauses(this);
4635     pam->nCurrSyllable = 0;
4636     pam->nSyllPhoneme = 0;
4637 
4638     return PICO_OK;
4639 }/*pam_adapter_backward_step*/
4640 
4641 /**
4642  * processes a pause (silence) syllable after backward processing
4643  * @param    this : pointer to PAM PU sub object pointer : processes a pause (silence) syllable after backward processing
4644  * @return    PICO_OK : backward step complete
4645  * @return  PICO_ERR_OTHER : errors on retrieving the PU pointer
4646  * @remarks pam->nCurrSyllable should point to a pause item
4647  * @remarks this function should be called after backward processing
4648  * @remarks this function corresponds to initializing silence phonemes with
4649  * @remarks values derived from previous or following syllables
4650  * @callgraph
4651  * @callergraph
4652  */
pam_do_pause(register picodata_ProcessingUnit this)4653 static pico_status_t pam_do_pause(register picodata_ProcessingUnit this)
4654 {
4655     picoos_uint16 syllCurr;
4656     pam_subobj_t *pam;
4657     if (NULL == this || NULL == this->subObj) {
4658         return PICO_ERR_OTHER;
4659     }
4660     pam = (pam_subobj_t *) this->subObj;
4661     syllCurr = pam->nCurrSyllable;
4662 
4663     /*processor for all features that can be inherited from previous syll (or word/phrase)*/
4664     if (pam->nCurrSyllable > 0) {
4665         pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3]
4666                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B3];
4667         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B8]
4668                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B8];
4669         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B10]
4670                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B10];
4671         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B12]
4672                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B12];
4673         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B14]
4674                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B14];
4675         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B17]
4676                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B17];
4677         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B19]
4678                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B19];
4679         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
4680                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B20];
4681         pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
4682                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[B21];
4683 
4684         pam->sSyllFeats[pam->nCurrSyllable].phoneV[D2]
4685                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E2];
4686         pam->sSyllFeats[pam->nCurrSyllable].phoneV[G1]
4687                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H1];
4688         pam->sSyllFeats[pam->nCurrSyllable].phoneV[G2]
4689                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H2];
4690 
4691         pam->sSyllFeats[pam->nCurrSyllable].phoneV[E5]
4692                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E5];
4693         pam->sSyllFeats[pam->nCurrSyllable].phoneV[E7]
4694                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E7];
4695         pam->sSyllFeats[pam->nCurrSyllable].phoneV[E9]
4696                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E9];
4697         pam->sSyllFeats[pam->nCurrSyllable].phoneV[E11]
4698                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E11];
4699         pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
4700                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E12];
4701         pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
4702                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E13];
4703         pam->sSyllFeats[pam->nCurrSyllable].phoneV[E13]
4704                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[E13];
4705 
4706         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1]
4707                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H1];
4708         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
4709                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H2];
4710         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H3]
4711                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H3];
4712         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H4]
4713                 = pam->sSyllFeats[pam->nCurrSyllable - 1].phoneV[H4];
4714 
4715     } else {
4716         pam->sSyllFeats[pam->nCurrSyllable].phoneV[A3]
4717             =pam->sSyllFeats[pam->nCurrSyllable].phoneV[B8]
4718             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B10]
4719             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B12]
4720             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B14]
4721             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B17]
4722             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B19]
4723             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B20]
4724             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[B21]
4725             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E5]
4726             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E9]
4727             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E11]
4728             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[E12]
4729             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H1]
4730             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H2]
4731             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[H3]
4732             = 0;
4733 
4734         /*init values different from 0*/
4735         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H4]
4736             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[J3];
4737         pam->sSyllFeats[pam->nCurrSyllable].phoneV[H5] = PICOPAM_p;
4738 
4739     }
4740 
4741     /*processor for all features that can be inherited from next syll (or word/phrase)*/
4742     if (pam->nCurrSyllable < pam->nTotalSyllables - 1) {
4743         /*non last syllable*/
4744         pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3]
4745                 = pam->sSyllFeats[pam->nCurrSyllable + 1].phoneV[B3];
4746         pam->sSyllFeats[pam->nCurrSyllable].phoneV[F2]
4747                 = pam->sSyllFeats[pam->nCurrSyllable + 1].phoneV[E2];
4748         pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1]
4749                 = pam->sSyllFeats[pam->nCurrSyllable + 1].phoneV[H1];
4750         pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2]
4751                 = pam->sSyllFeats[pam->nCurrSyllable + 1].phoneV[H2];
4752     } else {
4753         /*last syllable*/
4754         pam->sSyllFeats[pam->nCurrSyllable].phoneV[C3]
4755             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[F2]
4756             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[I1]
4757             = pam->sSyllFeats[pam->nCurrSyllable].phoneV[I2]
4758             = 0;
4759     }
4760 
4761     /*Other fixed values derived from de-facto standard*/
4762     pam->sSyllFeats[pam->nCurrSyllable].phoneV[B18] = 0;
4763 
4764     return PICO_OK;
4765 }/*pam_do_pause*/
4766 
4767 /**
4768  * performs the initialization of pause "syllables"
4769  * @param    this : pointer to PAM PU sub object pointer : processes a pause (silence) syllable after backward processing
4770  * @return    PICO_OK : pause processing successful
4771  * @return  PICO_ERR_OTHER : errors on retrieving the PU pointer
4772  * @callgraph
4773  * @callergraph
4774  */
pam_adapter_do_pauses(register picodata_ProcessingUnit this)4775 static pico_status_t pam_adapter_do_pauses(register picodata_ProcessingUnit this)
4776 {
4777     register pam_subobj_t * pam;
4778     picoos_uint16 nSyll;
4779 
4780     if (NULL == this || NULL == this->subObj) {
4781         return PICO_ERR_OTHER;
4782     }
4783     pam = (pam_subobj_t *) this->subObj;
4784 
4785     /*Do the pause processing*/
4786     nSyll = pam->nCurrSyllable;
4787     while (pam->nCurrSyllable >= 0) {
4788         if (pam->sSyllFeats[pam->nCurrSyllable].phoneV[P2] == 1) {
4789             /*pause processing*/
4790             pam_do_pause(this);
4791         }
4792         pam->nCurrSyllable--;
4793     }/*end while (pam->nCurrSyllable>=0)*/
4794     /*reset syllpointer to original value*/
4795     pam->nCurrSyllable = nSyll;
4796     return PICOPAM_READY;
4797 }/*pam_adapter_do_pauses*/
4798 
4799 #ifdef __cplusplus
4800 }
4801 #endif
4802 
4803 /* picopam.c end */
4804