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 picodata.c
18  *
19  * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
20  * All rights reserved.
21  *
22  * History:
23  * - 2009-04-20 -- initial version
24  *
25  */
26 
27 #include "picodefs.h"
28 #include "picoos.h"
29 #include "picodbg.h"
30 #include "picorsrc.h"
31 #include "picotrns.h"
32 #include "picodata.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 #if 0
38 }
39 #endif
40 
41 /* we output coefficients as fixed point values */
42 #define PICOCEP_OUT_DATA_FORMAT PICODATA_ITEMINFO1_FRAME_PAR_DATA_FORMAT_FIXED
43 
44 /* ***************************************************************
45  *                   CharBuffer                                  *
46  *****************************************************************/
47 
48 /*
49  * method signatures
50  */
51 typedef pico_status_t (* picodata_cbPutItemMethod) (register picodata_CharBuffer this,
52         const picoos_uint8 *buf, const picoos_uint16 blenmax,
53         picoos_uint16 *blen);
54 
55 typedef pico_status_t (* picodata_cbGetItemMethod) (register picodata_CharBuffer this,
56         picoos_uint8 *buf, const picoos_uint16 blenmax,
57         picoos_uint16 *blen, const picoos_uint8 issd);
58 
59 typedef pico_status_t (* picodata_cbSubResetMethod) (register picodata_CharBuffer this);
60 typedef pico_status_t (* picodata_cbSubDeallocateMethod) (register picodata_CharBuffer this, picoos_MemoryManager mm);
61 
62 typedef struct picodata_char_buffer
63 {
64     picoos_char *buf;
65     picoos_uint16 rear; /* next free position to write */
66     picoos_uint16 front; /* next position to read */
67     picoos_uint16 len; /* empty: len = 0, full: len = size */
68     picoos_uint16 size;
69 
70     picoos_Common common;
71 
72     picodata_cbGetItemMethod getItem;
73     picodata_cbPutItemMethod putItem;
74 
75     picodata_cbSubResetMethod subReset;
76     picodata_cbSubDeallocateMethod subDeallocate;
77     void * subObj;
78 } char_buffer_t;
79 
80 
81 static pico_status_t data_cbPutItem(register picodata_CharBuffer this,
82         const picoos_uint8 *buf, const picoos_uint16 blenmax,
83         picoos_uint16 *blen);
84 
85 static pico_status_t data_cbGetItem(register picodata_CharBuffer this,
86         picoos_uint8 *buf, const picoos_uint16 blenmax,
87         picoos_uint16 *blen, const picoos_uint8 issd);
88 
picodata_cbReset(register picodata_CharBuffer this)89 pico_status_t picodata_cbReset(register picodata_CharBuffer this)
90 {
91     this->rear = 0;
92     this->front = 0;
93     this->len = 0;
94     if (NULL != this->subObj) {
95         return this->subReset(this);
96     } else {
97         return PICO_OK;
98     }
99 }
100 
101 /* CharBuffer constructor */
picodata_newCharBuffer(picoos_MemoryManager mm,picoos_Common common,picoos_objsize_t size)102 picodata_CharBuffer picodata_newCharBuffer(picoos_MemoryManager mm,
103         picoos_Common common,
104         picoos_objsize_t size)
105 {
106     picodata_CharBuffer this;
107 
108     this = (picodata_CharBuffer) picoos_allocate(mm, sizeof(*this));
109     PICODBG_DEBUG(("new character buffer, size=%i", size));
110     if (NULL == this) {
111         return NULL;
112     }
113     this->buf = picoos_allocate(mm, size);
114     if (NULL == this->buf) {
115         picoos_deallocate(mm, (void*) &this);
116         return NULL;
117     }
118     this->size = size;
119     this->common = common;
120 
121     this->getItem = data_cbGetItem;
122     this->putItem = data_cbPutItem;
123 
124     this->subReset = NULL;
125     this->subDeallocate = NULL;
126     this->subObj = NULL;
127 
128     picodata_cbReset(this);
129     return this;
130 }
131 
picodata_disposeCharBuffer(picoos_MemoryManager mm,picodata_CharBuffer * this)132 void picodata_disposeCharBuffer(picoos_MemoryManager mm,
133                                 picodata_CharBuffer *this)
134 {
135     if (NULL != (*this)) {
136         /* terminate */
137         if (NULL != (*this)->subObj) {
138             (*this)->subDeallocate(*this,mm);
139         }
140         picoos_deallocate(mm,(void*)&(*this)->buf);
141         picoos_deallocate(mm,(void*)this);
142     }
143 }
144 
picodata_cbPutCh(register picodata_CharBuffer this,picoos_char ch)145 pico_status_t picodata_cbPutCh(register picodata_CharBuffer this,
146                                picoos_char ch)
147 {
148     if (this->len < this->size) {
149         this->buf[this->rear++] = ch;
150         this->rear %= this->size;
151         this->len++;
152         return PICO_OK;
153     } else {
154         return PICO_EXC_BUF_OVERFLOW;
155     }
156 }
157 
158 
picodata_cbGetCh(register picodata_CharBuffer this)159 picoos_int16 picodata_cbGetCh(register picodata_CharBuffer this)
160 {
161     picoos_char ch;
162     if (this->len > 0) {
163         ch = this->buf[this->front++];
164         this->front %= this->size;
165         this->len--;
166         return ch;
167     } else {
168         return PICO_EOF;
169     }
170 }
171 
172 /* ***************************************************************
173  *                   items: CharBuffer functions                 *
174  *****************************************************************/
175 
data_cbGetItem(register picodata_CharBuffer this,picoos_uint8 * buf,const picoos_uint16 blenmax,picoos_uint16 * blen,const picoos_uint8 issd)176 static pico_status_t data_cbGetItem(register picodata_CharBuffer this,
177         picoos_uint8 *buf, const picoos_uint16 blenmax,
178         picoos_uint16 *blen, const picoos_uint8 issd)
179 {
180     picoos_uint16 i;
181 
182     if (this->len < PICODATA_ITEM_HEADSIZE) {    /* item not in cb? */
183         *blen = 0;
184         if (this->len == 0) {    /* is cb empty? */
185             PICODBG_DEBUG(("no item to get"));
186             return PICO_EOF;
187         } else {    /* cb not empty, but not a valid item */
188             PICODBG_WARN(("problem getting item, incomplete head, underflow"));
189         }
190         return PICO_EXC_BUF_UNDERFLOW;
191     }
192     *blen = PICODATA_ITEM_HEADSIZE + (picoos_uint8)(this->buf[((this->front) +
193                                       PICODATA_ITEMIND_LEN) % this->size]);
194 
195     /* if getting speech data in item */
196     if (issd) {
197         /* check item type */
198         if (this->buf[this->front] != PICODATA_ITEM_FRAME) {
199             PICODBG_WARN(("item type mismatch for speech data: %c",
200                           this->buf[this->front]));
201             for (i=0; i<*blen; i++) {
202                 this->front++;
203                 this->front %= this->size;
204                 this->len--;
205             }
206             *blen = 0;
207             return PICO_OK;
208         }
209     }
210 
211     if (*blen > this->len) {    /* item in cb not complete? */
212         PICODBG_WARN(("problem getting item, incomplete content, underflow; "
213                       "blen=%d, len=%d", *blen, this->len));
214         *blen = 0;
215         return PICO_EXC_BUF_UNDERFLOW;
216     }
217     if (blenmax < *blen) {    /* buf not large enough? */
218         PICODBG_WARN(("problem getting item, overflow"));
219         *blen = 0;
220         return PICO_EXC_BUF_OVERFLOW;
221     }
222 
223     /* if getting speech data in item */
224     if (issd) {
225         /* skip item header */
226         for (i = 0; i < PICODATA_ITEM_HEADSIZE; i++) {
227             this->front++;
228             this->front %= this->size;
229             this->len--;
230         }
231         *blen -= PICODATA_ITEM_HEADSIZE;
232     }
233 
234     /* all ok, now get item (or speech data only) */
235     for (i = 0; i < *blen; i++) {
236         buf[i] = (picoos_uint8)(this->buf[this->front++]);
237         this->front %= this->size;
238         this->len--;
239     }
240 
241 #if defined(PICO_DEBUG)
242     if (issd) {
243         PICODBG_DEBUG(("got speech data: %d samples", *blen));
244     } else {
245         PICODBG_DEBUG(("got item: %c|%d|%d|%d||", buf[PICODATA_ITEMIND_TYPE],
246                        buf[PICODATA_ITEMIND_INFO1], buf[PICODATA_ITEMIND_INFO2],
247                        buf[PICODATA_ITEMIND_LEN]));
248         for (i=PICODATA_ITEM_HEADSIZE; i<*blen; i++) {
249             if (buf[PICODATA_ITEMIND_TYPE] == PICODATA_ITEM_WORDGRAPH) {
250                 PICODBG_DEBUG(("%c", buf[i]));
251             } else {
252                 PICODBG_DEBUG((" %d", buf[i]));
253             }
254         }
255     }
256 #endif
257 
258     return PICO_OK;
259 }
260 
data_cbPutItem(register picodata_CharBuffer this,const picoos_uint8 * buf,const picoos_uint16 blenmax,picoos_uint16 * blen)261 static pico_status_t data_cbPutItem(register picodata_CharBuffer this,
262         const picoos_uint8 *buf, const picoos_uint16 blenmax,
263         picoos_uint16 *blen)
264 {
265     picoos_uint16 i;
266 
267     if (blenmax < PICODATA_ITEM_HEADSIZE) {    /* itemlen not accessible? */
268         PICODBG_WARN(("problem putting item, underflow"));
269         *blen = 0;
270         return PICO_EXC_BUF_UNDERFLOW;
271     }
272     *blen = buf[PICODATA_ITEMIND_LEN] + PICODATA_ITEM_HEADSIZE;
273     if (*blen > (this->size - this->len)) {    /* cb not enough space? */
274         PICODBG_WARN(("problem putting item, overflow"));
275         *blen = 0;
276         return PICO_EXC_BUF_OVERFLOW;
277     }
278     if (*blen > blenmax) {    /* item in buf not completely accessible? */
279         PICODBG_WARN(("problem putting item, underflow"));
280         *blen = 0;
281         return PICO_EXC_BUF_UNDERFLOW;
282     }
283     /* all ok, now put complete item */
284 
285 #if defined(PICO_DEBUG)
286     PICODBG_DEBUG(("putting item: %c|%d|%d|%d||",
287                    buf[PICODATA_ITEMIND_TYPE],
288                    buf[PICODATA_ITEMIND_INFO1],
289                    buf[PICODATA_ITEMIND_INFO2],
290                    buf[PICODATA_ITEMIND_LEN]));
291     for (i=PICODATA_ITEM_HEADSIZE; i<*blen; i++) {
292         if (buf[PICODATA_ITEMIND_TYPE] == PICODATA_ITEM_WORDGRAPH) {
293             PICODBG_DEBUG(("%c", buf[i]));
294         } else {
295             PICODBG_DEBUG((" %d", buf[i]));
296         }
297     }
298 #endif
299 
300     for (i = 0; i < *blen; i++) {
301         /* put single byte */
302         this->buf[this->rear++] = (picoos_char)buf[i];
303         this->rear %= this->size;
304         this->len++;
305     }
306     return PICO_OK;
307 }
308 
309 /*----------------------------------------------------------
310  *  Names   : picodata_cbGetItem
311  *            picodata_cbGetSpeechData
312  *  Function: gets one item from 'this' and writes it on 'blenmax' sized 'buf'.
313  *            gets one item from 'this' and writes the speech data to
314  *              'blenmax' sized 'buf'.
315  *  Returns : PICO_OK : one item was copied
316  *            PICO_EOF : 'this' is empty; no new items available
317  *            PICO_BUF_UNDERFLOW : 'this' doesn't contain a full/valid item
318  *            PICO_BUF_OVERFLOW : 'buf[blenmax]' too small to hold item
319  *            on return, '*blen' contains the number of bytes written to 'buf'
320  * ---------------------------------------------------------*/
picodata_cbGetItem(register picodata_CharBuffer this,picoos_uint8 * buf,const picoos_uint16 blenmax,picoos_uint16 * blen)321 pico_status_t picodata_cbGetItem(register picodata_CharBuffer this,
322         picoos_uint8 *buf, const picoos_uint16 blenmax,
323         picoos_uint16 *blen)
324 {
325     return this->getItem(this, buf, blenmax, blen, FALSE);
326 }
327 
picodata_cbGetSpeechData(register picodata_CharBuffer this,picoos_uint8 * buf,const picoos_uint16 blenmax,picoos_uint16 * blen)328 pico_status_t picodata_cbGetSpeechData(register picodata_CharBuffer this,
329         picoos_uint8 *buf, const picoos_uint16 blenmax,
330         picoos_uint16 *blen)
331 {
332 
333     return this->getItem(this, buf, blenmax, blen, TRUE);
334 }
335 
336 
picodata_cbPutItem(register picodata_CharBuffer this,const picoos_uint8 * buf,const picoos_uint16 blenmax,picoos_uint16 * blen)337 pico_status_t picodata_cbPutItem(register picodata_CharBuffer this,
338         const picoos_uint8 *buf, const picoos_uint16 blenmax,
339         picoos_uint16 *blen)
340 {
341 
342         return this->putItem(this,buf,blenmax,blen);
343 }
344 
345 /* unsafe, just for measuring purposes */
picodata_cbGetFrontItemType(register picodata_CharBuffer this)346 picoos_uint8 picodata_cbGetFrontItemType(register picodata_CharBuffer this)
347 {
348     return  this->buf[this->front];
349 }
350 /* ***************************************************************
351  *                   items: support function                     *
352  *****************************************************************/
353 
is_valid_itemtype(const picoos_uint8 ch)354 picoos_uint8 is_valid_itemtype(const picoos_uint8 ch) {
355     switch (ch) {
356         case PICODATA_ITEM_WSEQ_GRAPH:
357         case PICODATA_ITEM_TOKEN:
358         case PICODATA_ITEM_WORDGRAPH:
359         case PICODATA_ITEM_WORDINDEX:
360         case PICODATA_ITEM_WORDPHON:
361         case PICODATA_ITEM_SYLLPHON:
362         case PICODATA_ITEM_BOUND:
363         case PICODATA_ITEM_PUNC:
364         case PICODATA_ITEM_CMD:
365         case PICODATA_ITEM_PHONE:
366         case PICODATA_ITEM_FRAME:
367         case PICODATA_ITEM_FRAME_PAR:
368             return TRUE;
369             break;
370         case PICODATA_ITEM_OTHER:
371         default:
372             break;
373     }
374     PICODBG_WARN(("item type problem: %c", ch));
375     return FALSE;
376 }
377 
picodata_is_valid_itemhead(const picodata_itemhead_t * head)378 picoos_uint8 picodata_is_valid_itemhead(const picodata_itemhead_t *head) {
379     if ((NULL != head) && is_valid_itemtype(head->type)) {
380         return TRUE;
381     } else {
382         PICODBG_WARN(("item header problem"));
383         return FALSE;
384     }
385 }
386 
387 /* ***************************************************/
388 
389 
picodata_get_itemparts_nowarn(const picoos_uint8 * buf,const picoos_uint16 blenmax,picodata_itemhead_t * head,picoos_uint8 * content,const picoos_uint16 clenmax,picoos_uint16 * clen)390 pico_status_t picodata_get_itemparts_nowarn(
391         const picoos_uint8 *buf, const picoos_uint16 blenmax,
392         picodata_itemhead_t *head, picoos_uint8 *content,
393         const picoos_uint16 clenmax, picoos_uint16 *clen)
394 {
395     if (blenmax >= PICODATA_ITEM_HEADSIZE) {
396         head->type = buf[PICODATA_ITEMIND_TYPE];
397         head->info1 = buf[PICODATA_ITEMIND_INFO1];
398         head->info2 = buf[PICODATA_ITEMIND_INFO2];
399         head->len = buf[PICODATA_ITEMIND_LEN];
400         *clen = head->len;
401         if (blenmax >= (*clen + PICODATA_ITEM_HEADSIZE)) {
402             if (clenmax >= head->len) {
403                 picoos_uint16 i;
404                 for (i=0; i<head->len; i++) {
405                     content[i] = buf[PICODATA_ITEM_HEADSIZE+i];
406                 }
407                 return PICO_OK;
408             }
409             *clen = 0;
410             return PICO_EXC_BUF_OVERFLOW;
411         }
412     }
413     *clen = 0;
414     return PICO_EXC_BUF_UNDERFLOW;
415 }
416 
picodata_get_itemparts(const picoos_uint8 * buf,const picoos_uint16 blenmax,picodata_itemhead_t * head,picoos_uint8 * content,const picoos_uint16 clenmax,picoos_uint16 * clen)417 pico_status_t picodata_get_itemparts(
418         const picoos_uint8 *buf, const picoos_uint16 blenmax,
419         picodata_itemhead_t *head, picoos_uint8 *content,
420         const picoos_uint16 clenmax, picoos_uint16 *clen)
421 {
422     pico_status_t status = picodata_get_itemparts_nowarn(buf,blenmax,head,content,clenmax,clen);
423     if (PICO_EXC_BUF_OVERFLOW == status) {
424         PICODBG_WARN(("problem getting item, overflow"));
425     } else if  (PICO_EXC_BUF_UNDERFLOW == status) {
426         PICODBG_WARN(("problem getting item, overflow"));
427     }
428     return status;
429 }
picodata_put_itemparts(const picodata_itemhead_t * head,const picoos_uint8 * content,const picoos_uint16 clenmax,picoos_uint8 * buf,const picoos_uint16 blenmax,picoos_uint16 * blen)430 pico_status_t picodata_put_itemparts(const picodata_itemhead_t *head,
431         const picoos_uint8 *content, const picoos_uint16 clenmax,
432         picoos_uint8 *buf, const picoos_uint16 blenmax, picoos_uint16 *blen)
433 {
434     *blen = head->len + PICODATA_ITEM_HEADSIZE;
435     if (blenmax >= *blen) {
436         if (clenmax >= head->len) {
437             picoos_uint16 i;
438             buf[PICODATA_ITEMIND_TYPE] = head->type;
439             buf[PICODATA_ITEMIND_INFO1] = head->info1;
440             buf[PICODATA_ITEMIND_INFO2] = head->info2;
441             buf[PICODATA_ITEMIND_LEN] = head->len;
442             for (i=0; i<head->len; i++) {
443                 buf[PICODATA_ITEM_HEADSIZE+i] = content[i];
444             }
445             return PICO_OK;
446         }
447         PICODBG_WARN(("problem putting item, underflow"));
448         *blen = 0;
449         return PICO_EXC_BUF_UNDERFLOW;
450     }
451     PICODBG_WARN(("problem putting item, overflow"));
452     *blen = 0;
453     return PICO_EXC_BUF_OVERFLOW;
454 }
455 
picodata_get_iteminfo(picoos_uint8 * buf,const picoos_uint16 blenmax,picodata_itemhead_t * head,picoos_uint8 ** content)456 pico_status_t picodata_get_iteminfo(
457         picoos_uint8 *buf, const picoos_uint16 blenmax,
458         picodata_itemhead_t *head, picoos_uint8 **content) {
459     if (blenmax >= PICODATA_ITEM_HEADSIZE) {
460         head->type = buf[PICODATA_ITEMIND_TYPE];
461         head->info1 = buf[PICODATA_ITEMIND_INFO1];
462         head->info2 = buf[PICODATA_ITEMIND_INFO2];
463         head->len = buf[PICODATA_ITEMIND_LEN];
464         if (head->len == 0) {
465             *content = NULL;
466         } else {
467             *content = &buf[PICODATA_ITEM_HEADSIZE];
468         }
469         return PICO_OK;
470     }
471     return PICO_EXC_BUF_UNDERFLOW;
472 }
473 
picodata_copy_item(const picoos_uint8 * inbuf,const picoos_uint16 inlenmax,picoos_uint8 * outbuf,const picoos_uint16 outlenmax,picoos_uint16 * numb)474 pico_status_t picodata_copy_item(const picoos_uint8 *inbuf,
475         const picoos_uint16 inlenmax, picoos_uint8 *outbuf,
476         const picoos_uint16 outlenmax, picoos_uint16 *numb)
477 {
478     if (picodata_is_valid_item(inbuf, inlenmax)) {
479         *numb = PICODATA_ITEM_HEADSIZE + inbuf[PICODATA_ITEMIND_LEN];
480     } else {
481         *numb = 0;
482     }
483     if (*numb > 0) {
484         if (outlenmax >= inlenmax) {
485             picoos_uint16 i;
486             for (i=0; i<*numb; i++) {
487                 outbuf[i] = inbuf[i];
488             }
489             return PICO_OK;
490         } else {
491             PICODBG_WARN(("buffer problem, out: %d > in: %d", outlenmax, inlenmax));
492             *numb = 0;
493             return PICO_EXC_BUF_OVERFLOW;
494         }
495     } else {
496         PICODBG_WARN(("item problem in inbuf"));
497         return PICO_ERR_OTHER;
498     }
499 }
500 
picodata_set_iteminfo1(picoos_uint8 * buf,const picoos_uint16 blenmax,const picoos_uint8 info)501 pico_status_t picodata_set_iteminfo1(picoos_uint8 *buf,
502         const picoos_uint16 blenmax, const picoos_uint8 info) {
503     if (PICODATA_ITEMIND_INFO1 < blenmax) {
504         buf[PICODATA_ITEMIND_INFO1] = info;
505         return PICO_OK;
506     } else
507         return PICO_EXC_BUF_UNDERFLOW;
508 }
509 
picodata_set_iteminfo2(picoos_uint8 * buf,const picoos_uint16 blenmax,const picoos_uint8 info)510 pico_status_t picodata_set_iteminfo2(picoos_uint8 *buf,
511         const picoos_uint16 blenmax, const picoos_uint8 info) {
512     if (PICODATA_ITEMIND_INFO2 < blenmax) {
513         buf[PICODATA_ITEMIND_INFO2] = info;
514         return PICO_OK;
515     } else
516         return PICO_EXC_BUF_UNDERFLOW;
517 }
518 
519 /* sets the len field in the header contained in the item in buf;
520    return values:
521    PICO_OK                 <- all ok
522    PICO_EXC_BUF_UNDERFLOW  <- underflow in buf
523 */
picodata_set_itemlen(picoos_uint8 * buf,const picoos_uint16 blenmax,const picoos_uint8 len)524 pico_status_t picodata_set_itemlen(picoos_uint8 *buf,
525         const picoos_uint16 blenmax, const picoos_uint8 len) {
526     if (PICODATA_ITEMIND_LEN < blenmax) {
527         buf[PICODATA_ITEMIND_LEN] = len;
528         return PICO_OK;
529     } else
530         return PICO_EXC_BUF_UNDERFLOW;
531 }
532 
picodata_is_valid_item(const picoos_uint8 * item,const picoos_uint16 ilenmax)533 picoos_uint8 picodata_is_valid_item(const picoos_uint8 *item,
534         const picoos_uint16 ilenmax)
535 {
536     if (ilenmax >= PICODATA_ITEM_HEADSIZE) {
537         picodata_itemhead_t head;
538         head.type = item[0];
539         head.info1 = item[1];
540         head.info2 = item[2];
541         head.len = item[3];
542         if ((ilenmax >= (head.len + PICODATA_ITEM_HEADSIZE)) &&
543             picodata_is_valid_itemhead(&head))
544         {
545             return TRUE;
546         }
547     }
548     return FALSE;
549 }
550 
551 /* ***************************************************************
552  *                   ProcessingUnit                              *
553  *****************************************************************/
picodata_get_default_buf_size(picodata_putype_t puType)554 picoos_uint16 picodata_get_default_buf_size (picodata_putype_t puType)
555 {
556     return  (PICODATA_PUTYPE_TEXT == puType) ? PICODATA_BUFSIZE_TEXT
557           : (PICODATA_PUTYPE_TOK  == puType) ? PICODATA_BUFSIZE_TOK
558           : (PICODATA_PUTYPE_PR   == puType) ? PICODATA_BUFSIZE_PR
559           : (PICODATA_PUTYPE_PR   == puType) ? PICODATA_BUFSIZE_PR
560           : (PICODATA_PUTYPE_WA   == puType) ? PICODATA_BUFSIZE_WA
561           : (PICODATA_PUTYPE_SA   == puType) ? PICODATA_BUFSIZE_SA
562           : (PICODATA_PUTYPE_ACPH == puType) ? PICODATA_BUFSIZE_ACPH
563           : (PICODATA_PUTYPE_SPHO == puType) ? PICODATA_BUFSIZE_SPHO
564           : (PICODATA_PUTYPE_PAM  == puType) ? PICODATA_BUFSIZE_PAM
565           : (PICODATA_PUTYPE_CEP  == puType) ? PICODATA_BUFSIZE_CEP
566           : (PICODATA_PUTYPE_SIG  == puType) ? PICODATA_BUFSIZE_SIG
567           : (PICODATA_PUTYPE_SINK  == puType) ? PICODATA_BUFSIZE_SINK
568           :                                    PICODATA_BUFSIZE_DEFAULT;
569 }
570 
571 
572 typedef struct simple_pu_data
573 {
574     picorsrc_Voice voice;
575 } simple_pu_data_t;
576 
puSimpleInitialize(register picodata_ProcessingUnit this,picoos_int32 resetMode)577 static pico_status_t puSimpleInitialize (register picodata_ProcessingUnit this, picoos_int32 resetMode) {
578     return PICO_OK;
579 }
580 
puSimpleTerminate(register picodata_ProcessingUnit this)581 static pico_status_t puSimpleTerminate (register picodata_ProcessingUnit this) {
582     return PICO_OK;
583 }
584 
puSimpleStep(register picodata_ProcessingUnit this,picoos_int16 mode,picoos_uint16 * numBytesOutput)585 static picodata_step_result_t puSimpleStep (register picodata_ProcessingUnit this,
586                                             picoos_int16 mode,
587                                             picoos_uint16 * numBytesOutput) {
588     picoos_int16 ch;
589     picoos_int16 result = PICO_OK;
590     mode = mode;        /*PP 13.10.08 : fix warning "var not used in this function"*/
591     *numBytesOutput = 0;
592     while ((result == PICO_OK) && (ch = picodata_cbGetCh(this->cbIn)) != PICO_EOF) {
593         result = picodata_cbPutCh(this->cbOut,(picoos_char) ch);
594         (*numBytesOutput)++;
595     }
596     if (PICO_OK != result) {
597         (*numBytesOutput)--;
598     }
599     if (PICO_OK == result) {
600         return PICODATA_PU_IDLE;
601     } else {
602         return PICODATA_PU_ERROR;
603     }
604 }
605 
606 
picodata_newProcessingUnit(picoos_MemoryManager mm,picoos_Common common,picodata_CharBuffer cbIn,picodata_CharBuffer cbOut,picorsrc_Voice voice)607 picodata_ProcessingUnit picodata_newProcessingUnit(
608         picoos_MemoryManager mm,
609         picoos_Common common,
610         picodata_CharBuffer cbIn,
611         picodata_CharBuffer cbOut,
612         picorsrc_Voice voice)
613 {
614     picodata_ProcessingUnit this = (picodata_ProcessingUnit) picoos_allocate(mm, sizeof(*this));
615     if (this == NULL) {
616         picoos_emRaiseException(common->em,PICO_EXC_OUT_OF_MEM,NULL,NULL);
617         return NULL;
618     }
619     this->common = common;
620     this->cbIn = cbIn;
621     this->cbOut = cbOut;
622     this->voice = voice;
623     this->initialize = puSimpleInitialize;
624     this->terminate = puSimpleTerminate;
625     this->step = puSimpleStep;
626     this->subDeallocate = NULL;
627     this->subObj = NULL;
628     return this;
629 }
630 
picodata_disposeProcessingUnit(picoos_MemoryManager mm,picodata_ProcessingUnit * this)631 void picodata_disposeProcessingUnit(
632         picoos_MemoryManager mm,
633         picodata_ProcessingUnit * this)
634 {
635     if (NULL != (*this)) {
636         /* terminate */
637         if (NULL != (*this)->subObj) {
638             (*this)->subDeallocate(*this,mm);
639         }
640         picoos_deallocate(mm,(void *)this);
641     }
642 
643 }
644 
645 
picodata_getCbIn(picodata_ProcessingUnit this)646 picodata_CharBuffer picodata_getCbIn(picodata_ProcessingUnit this)
647 {
648     if (NULL == this) {
649         picoos_emRaiseException(this->common->em,PICO_ERR_NULLPTR_ACCESS,NULL,NULL);
650         return NULL;
651     } else {
652         return this->cbIn;
653     }
654 }
655 
picodata_getCbOut(picodata_ProcessingUnit this)656 picodata_CharBuffer picodata_getCbOut(picodata_ProcessingUnit this)
657 {
658     if (NULL == this) {
659         picoos_emRaiseException(this->common->em,PICO_ERR_NULLPTR_ACCESS,NULL,NULL);
660         return NULL;
661     } else {
662         return this->cbOut;
663     }
664 }
665 
picodata_setCbIn(picodata_ProcessingUnit this,picodata_CharBuffer cbIn)666 pico_status_t picodata_setCbIn(picodata_ProcessingUnit this, picodata_CharBuffer cbIn)
667 {
668     if (NULL == this) {
669         picoos_emRaiseException(this->common->em,PICO_ERR_NULLPTR_ACCESS,NULL,NULL);
670         return PICO_ERR_OTHER;
671     } else {
672         this->cbIn = cbIn;
673         return PICO_OK;
674     }
675 
676 }
677 
picodata_setCbOut(picodata_ProcessingUnit this,picodata_CharBuffer cbOut)678 pico_status_t picodata_setCbOut(picodata_ProcessingUnit this, picodata_CharBuffer cbOut)
679 {
680     if (NULL == this) {
681         picoos_emRaiseException(this->common->em,PICO_ERR_NULLPTR_ACCESS,NULL,NULL);
682         return PICO_ERR_OTHER;
683     } else {
684         this->cbOut = cbOut;
685         return PICO_OK;
686     }
687 }
688 
689 
690 /* ***************************************************************
691  *                   auxiliary functions                         *
692  *****************************************************************/
693 
transDurUniform(picoos_uint8 frame_duration_exp,picoos_int8 array_length,picoos_uint8 * inout,picoos_int16 inputdur,picoos_int16 targetdur,picoos_int16 * restdur)694 static void transDurUniform(
695         picoos_uint8 frame_duration_exp, /* 2's exponent of frame duration in ms, e.g. 2 for 4ms, 3 for 8ms */
696         picoos_int8 array_length,
697         picoos_uint8 * inout,
698         picoos_int16 inputdur, /* input duration in ms */
699         picoos_int16 targetdur, /* target duration in ms */
700         picoos_int16 * restdur /* in/out, rest in ms */
701         )
702 {
703     picoos_int8 i;
704     picoos_int32 fact, rest;
705 
706     /* calculate rest and factor in number of frames (in PICODATA_PICODATA_PRECISION) */
707     rest = (*restdur) << (PICODATA_PRECISION - frame_duration_exp);
708     fact = (targetdur << (PICODATA_PRECISION - frame_duration_exp)) / inputdur;
709 
710     for (i = 0; i < array_length; i++) {
711         rest += fact * inout[i];
712         /* instead of rounding, we carry the rest to the next state */
713         inout[i] = rest >> PICODATA_PRECISION;
714         rest -= inout[i] << PICODATA_PRECISION;
715     }
716     (*restdur) = rest >> (PICODATA_PRECISION - frame_duration_exp);
717 }
718 
transDurWeighted(picoos_uint8 frame_duration_exp,picoos_int8 array_length,picoos_uint8 * inout,const picoos_uint16 * weight,picoos_int16 inputdur,picoos_int16 targetdur,picoos_int16 * restdur)719 static void transDurWeighted(
720         picoos_uint8 frame_duration_exp, /* 2's exponent of frame duration in ms, e.g. 2 for 4ms, 3 for 8ms */
721         picoos_int8 array_length,
722         picoos_uint8 * inout,
723         const picoos_uint16 * weight,  /* integer weights */
724         picoos_int16 inputdur, /* input duration in ms */
725         picoos_int16 targetdur, /* target duration in ms */
726         picoos_int16 * restdur /* in/out, rest in ms */
727         )
728 {
729     picoos_int8 i;
730     picoos_int32 fact, rest, out, weighted_sum;
731 
732     /* calculate rest and factor in number of frames (in PICODATA_PICODATA_PRECISION) */
733     rest = (*restdur) << (PICODATA_PRECISION - frame_duration_exp);
734     weighted_sum = 0;
735     for (i=0; i < array_length; i++) {
736         weighted_sum += inout[i] * weight[i];
737     }
738     if (0 == weighted_sum) {
739         transDurUniform(frame_duration_exp,array_length,inout,inputdur,targetdur,restdur);
740         return;
741     }
742     /* get the additive change factor in PICODATA_PRECISION: */
743     if (targetdur > inputdur) {
744         fact = ((targetdur - inputdur) << (PICODATA_PRECISION-frame_duration_exp))/ weighted_sum;
745     } else {
746         fact = -((inputdur - targetdur) << (PICODATA_PRECISION-frame_duration_exp))/ weighted_sum;
747     }
748 
749     /* input[i] * fact * weight[i] is the additive modification in PICODATA_PRECISION */
750     for (i=0; i < array_length; i++) {
751         rest += fact * inout[i] * weight[i];
752         /* instead of rounding, we carry the rest to the next state */
753         out = inout[i] + (rest >> PICODATA_PRECISION);
754         if (out < 0) {
755             out = 0;
756         }
757         rest -= ((out-inout[i]) << PICODATA_PRECISION);
758         inout[i] = out;
759     }
760    (*restdur) = rest >> (PICODATA_PRECISION - frame_duration_exp);
761 }
762 
763 
764 
picodata_transformDurations(picoos_uint8 frame_duration_exp,picoos_int8 array_length,picoos_uint8 * inout,const picoos_uint16 * weight,picoos_int16 mintarget,picoos_int16 maxtarget,picoos_int16 facttarget,picoos_int16 * dur_rest)765 void picodata_transformDurations(
766         picoos_uint8 frame_duration_exp,
767         picoos_int8 array_length,
768         picoos_uint8 * inout,
769         const picoos_uint16 * weight,  /* integer weights */
770         picoos_int16 mintarget, /* minimum target duration in ms */
771         picoos_int16 maxtarget, /* maximum target duration in ms */
772         picoos_int16 facttarget, /* factor to be multiplied with original length to get the target
773                                      the factor is fixed-point with PICODATA_PRECISION PICODATA_PRECISION, i.e.
774                                      the factor as float would be facttarget / PICODATA_PRECISION_FACT
775                                      if factor is 0, only min/max are considered */
776         picoos_int16 * dur_rest /* in/out, rest in ms */
777         )
778 {
779     picoos_int32 inputdur, targetdur;
780     picoos_int8 i;
781 
782     /* find the original duration in ms */
783     inputdur = 0;
784     for (i=0; i < array_length; i++) {
785         inputdur += inout[i];
786     }
787 
788     PICODBG_TRACE(("######## transforming duration fact=%i, limits = [%i,%i] (input frames: %i)",facttarget,mintarget,maxtarget, inputdur));
789 
790     inputdur <<= frame_duration_exp;
791 
792     /* find the target duration */
793     if (facttarget) {
794         targetdur = (facttarget * inputdur + PICODATA_PREC_HALF) >> PICODATA_PRECISION;
795     } else {
796         targetdur = inputdur;
797     }
798 
799     /* we need to modify input if there is an explicit factor or input is not in the target range */
800     if (facttarget || (targetdur < mintarget) || (maxtarget < targetdur)) {
801         /* make sure we are in the limits */
802         if (targetdur < mintarget) {
803             targetdur = mintarget;
804         } else if (maxtarget < targetdur) {
805             targetdur = maxtarget;
806         }
807         /* perform modification */
808         if (NULL == weight) {
809             transDurUniform(frame_duration_exp,array_length,inout,inputdur,targetdur,dur_rest);
810         } else {
811             transDurWeighted(frame_duration_exp,array_length,inout,weight,inputdur,targetdur,dur_rest);
812         }
813     }
814 }
815 
816 
817 
picodata_getPuTypeFromExtension(picoos_uchar * filename,picoos_bool input)818 extern picoos_uint8 picodata_getPuTypeFromExtension(picoos_uchar * filename, picoos_bool input)
819 {
820     if (input) {
821         if (picoos_has_extension(filename, PICODATA_PUTYPE_TOK_INPUT_EXTENSION)) {
822             return PICODATA_ITEMINFO2_CMD_TO_TOK;
823         }
824         else if (picoos_has_extension(filename, PICODATA_PUTYPE_PR_INPUT_EXTENSION)) {
825             return PICODATA_ITEMINFO2_CMD_TO_PR;
826         }
827         else if (picoos_has_extension(filename, PICODATA_PUTYPE_WA_INPUT_EXTENSION)) {
828             return PICODATA_ITEMINFO2_CMD_TO_WA;
829         }
830         else if (picoos_has_extension(filename, PICODATA_PUTYPE_SA_INPUT_EXTENSION)) {
831             return PICODATA_ITEMINFO2_CMD_TO_SA;
832         }
833         else if (picoos_has_extension(filename, PICODATA_PUTYPE_ACPH_INPUT_EXTENSION)) {
834             return PICODATA_ITEMINFO2_CMD_TO_ACPH;
835         }
836         else if (picoos_has_extension(filename, PICODATA_PUTYPE_SPHO_INPUT_EXTENSION)) {
837             return PICODATA_ITEMINFO2_CMD_TO_SPHO;
838         }
839         else if (picoos_has_extension(filename, PICODATA_PUTYPE_PAM_INPUT_EXTENSION)) {
840             return PICODATA_ITEMINFO2_CMD_TO_PAM;
841         }
842         else if (picoos_has_extension(filename, PICODATA_PUTYPE_CEP_INPUT_EXTENSION)) {
843             return PICODATA_ITEMINFO2_CMD_TO_CEP;
844         }
845         else if (picoos_has_extension(filename, PICODATA_PUTYPE_SIG_INPUT_EXTENSION) ||
846                 picoos_has_extension(filename, PICODATA_PUTYPE_WAV_INPUT_EXTENSION)) {
847             return PICODATA_ITEMINFO2_CMD_TO_SIG;
848         }
849         else {
850             return PICODATA_ITEMINFO2_CMD_TO_UNKNOWN;
851         }
852     }
853     else {
854         if (picoos_has_extension(filename, PICODATA_PUTYPE_TOK_OUTPUT_EXTENSION)) {
855             return PICODATA_ITEMINFO2_CMD_TO_TOK;
856         }
857         else if (picoos_has_extension(filename, PICODATA_PUTYPE_PR_OUTPUT_EXTENSION)) {
858             return PICODATA_ITEMINFO2_CMD_TO_PR;
859         }
860         else if (picoos_has_extension(filename, PICODATA_PUTYPE_WA_OUTPUT_EXTENSION)) {
861             return PICODATA_ITEMINFO2_CMD_TO_WA;
862         }
863         else if (picoos_has_extension(filename, PICODATA_PUTYPE_SA_OUTPUT_EXTENSION)) {
864             return PICODATA_ITEMINFO2_CMD_TO_SA;
865         }
866         else if (picoos_has_extension(filename, PICODATA_PUTYPE_ACPH_OUTPUT_EXTENSION)) {
867             return PICODATA_ITEMINFO2_CMD_TO_ACPH;
868         }
869         else if (picoos_has_extension(filename, PICODATA_PUTYPE_SPHO_OUTPUT_EXTENSION)) {
870             return PICODATA_ITEMINFO2_CMD_TO_SPHO;
871         }
872         else if (picoos_has_extension(filename, PICODATA_PUTYPE_PAM_OUTPUT_EXTENSION)) {
873             return PICODATA_ITEMINFO2_CMD_TO_PAM;
874         }
875         else if (picoos_has_extension(filename, PICODATA_PUTYPE_CEP_OUTPUT_EXTENSION)) {
876             return PICODATA_ITEMINFO2_CMD_TO_CEP;
877         }
878         else if (picoos_has_extension(filename, PICODATA_PUTYPE_SIG_OUTPUT_EXTENSION) ||
879                 picoos_has_extension(filename, PICODATA_PUTYPE_WAV_OUTPUT_EXTENSION)) {
880             return PICODATA_ITEMINFO2_CMD_TO_SIG;
881         }
882         else {
883             return PICODATA_ITEMINFO2_CMD_TO_UNKNOWN;
884         }
885     }
886     return PICODATA_ITEMINFO2_CMD_TO_UNKNOWN;
887 }
888 
889 
890 
891 
892 /**
893  *
894  * @param transducer
895  * @param common
896  * @param xsampa_parser
897  * @param svoxpa_parser
898  * @param xsampa2svoxpa_mapper
899  * @param inputPhones
900  * @param alphabet
901  * @param outputPhoneIds
902  * @param maxOutputPhoneIds
903  * @return
904  */
picodata_mapPAStrToPAIds(picotrns_SimpleTransducer transducer,picoos_Common common,picokfst_FST xsampa_parser,picokfst_FST svoxpa_parser,picokfst_FST xsampa2svoxpa_mapper,picoos_uchar * inputPhones,picoos_uchar * alphabet,picoos_uint8 * outputPhoneIds,picoos_int32 maxOutputPhoneIds)905 pico_status_t picodata_mapPAStrToPAIds(picotrns_SimpleTransducer transducer,
906         picoos_Common common, picokfst_FST xsampa_parser,
907         picokfst_FST svoxpa_parser, picokfst_FST xsampa2svoxpa_mapper,
908         picoos_uchar * inputPhones, picoos_uchar * alphabet,
909         picoos_uint8 * outputPhoneIds, picoos_int32 maxOutputPhoneIds)
910 {
911     pico_status_t status = PICO_OK;
912     if (picoos_strcmp(alphabet, PICODATA_XSAMPA) == 0) {
913         if ((NULL != xsampa_parser) && (NULL != xsampa2svoxpa_mapper)) {
914             picotrns_stInitialize(transducer);
915             status = picotrns_stAddWithPlane(transducer, inputPhones,
916                     PICOKFST_PLANE_ASCII);
917             if (PICO_OK != status) {
918                 picoos_emRaiseWarning(common->em, status, NULL,
919                         (picoos_char *) "phoneme sequence too long (%s)",
920                         inputPhones);
921             } else {
922                 status = picotrns_stTransduce(transducer, xsampa_parser);
923                 if (PICO_OK != status) {
924                     picoos_emRaiseWarning(common->em, status, NULL,
925                             (picoos_char *) "not recognized as xsampa (%s)",
926                             inputPhones);
927                 } else {
928                     status = picotrns_stTransduce(transducer, xsampa2svoxpa_mapper);
929                     if (PICO_OK != status) {
930                         picoos_emRaiseWarning(common->em, status, NULL,
931                                 (picoos_char *) "illeagal phoneme sequence (%s)",
932                                 inputPhones);
933                     } else {
934                         status = picotrns_stGetSymSequence(transducer, outputPhoneIds,
935                                 maxOutputPhoneIds);
936                     }
937                 }
938             }
939             return status;
940         }
941     } else if (picoos_strcmp(alphabet, PICODATA_SVOXPA) == 0) {
942         if ((NULL != svoxpa_parser)) {
943             picotrns_stInitialize(transducer);
944             status = picotrns_stAddWithPlane(transducer, inputPhones,
945                     PICOKFST_PLANE_ASCII);
946             if (PICO_OK == status) {
947                 status = picotrns_stTransduce(transducer, svoxpa_parser);
948             }
949             if (PICO_OK == status) {
950                 status = picotrns_stGetSymSequence(transducer, outputPhoneIds,
951                         maxOutputPhoneIds);
952             }
953             return status;
954         }
955     }
956     picoos_strlcpy(outputPhoneIds, (picoos_char *) "", maxOutputPhoneIds);
957     picoos_emRaiseWarning(common->em, PICO_EXC_NAME_ILLEGAL, NULL,
958             (picoos_char *) "alphabet not supported (%s)", alphabet);
959     return PICO_EXC_NAME_ILLEGAL;
960 
961 }
962 
963 #if defined (PICO_DEBUG)
964 /* ***************************************************************
965  *                   For Debugging only                          *
966  *****************************************************************/
967 
968 
969 /* put string representation of 'itemtype' into 'str' (allocated size 'strsize')
970  * return 'str' */
data_itemtype_to_string(const picoos_uint8 itemtype,picoos_char * str,picoos_uint16 strsize)971 static picoos_char * data_itemtype_to_string(const picoos_uint8 itemtype,
972         picoos_char * str, picoos_uint16 strsize)
973 {
974     picoos_char * tmpstr;
975     switch (itemtype) {
976         case PICODATA_ITEM_BOUND:
977             tmpstr = (picoos_char *)"BOUND";
978             break;
979         case PICODATA_ITEM_FRAME_PAR:
980             tmpstr = (picoos_char *)"FRAME_PAR";
981             break;
982         case PICODATA_ITEM_PHONE:
983             tmpstr = (picoos_char *)"PHONE";
984             break;
985         case PICODATA_ITEM_CMD:
986             tmpstr = (picoos_char *)"CMD";
987             break;
988         case PICODATA_ITEM_ERR:
989             tmpstr = (picoos_char *)"ERR";
990             break;
991         case PICODATA_ITEM_FRAME:
992             tmpstr = (picoos_char *)"FRAME";
993             break;
994         case PICODATA_ITEM_OTHER:
995             tmpstr = (picoos_char *)"OTHER";
996             break;
997         case PICODATA_ITEM_PUNC:
998             tmpstr = (picoos_char *)"PUNC";
999             break;
1000         case PICODATA_ITEM_SYLLPHON:
1001             tmpstr = (picoos_char *)"SYLLPHON";
1002             break;
1003         case PICODATA_ITEM_WORDGRAPH:
1004             tmpstr = (picoos_char *)"WORDGRAPH";
1005             break;
1006         case PICODATA_ITEM_WORDINDEX:
1007             tmpstr = (picoos_char *)"WORDINDEX";
1008             break;
1009         case PICODATA_ITEM_WORDPHON:
1010             tmpstr = (picoos_char *)"WORDPHON";
1011             break;
1012         case PICODATA_ITEM_WSEQ_GRAPH:
1013             tmpstr = (picoos_char *)"WSEQ_GRAPH";
1014             break;
1015         default:
1016             tmpstr = (picoos_char *)"UNKNOWN";
1017             break;
1018     }
1019     picopal_slprintf((picopal_char *) str, strsize, (picopal_char *)"%s",
1020             tmpstr);
1021     return str;
1022 }
1023 
1024 
picodata_head_to_string(const picodata_itemhead_t * head,picoos_char * str,picoos_uint16 strsize)1025 picoos_char * picodata_head_to_string(const picodata_itemhead_t *head,
1026         picoos_char * str, picoos_uint16 strsize)
1027 {
1028     picoos_uint16 typelen;
1029 
1030     if (NULL == head) {
1031         picoos_strlcpy(str,(picoos_char *)"[head is NULL]",strsize);
1032     } else {
1033         data_itemtype_to_string(head->type, str, strsize);
1034         typelen = picoos_strlen(str);
1035         picopal_slprintf((picopal_char *) str+typelen, strsize-typelen,
1036                 (picopal_char *)"|%c|%c|%i", head->info1, head->info2,
1037                 head->len);
1038     }
1039 
1040     return str;
1041 }
1042 
picodata_info_item(const picoknow_KnowledgeBase kb,const picoos_uint8 * pref6ch,const picoos_uint8 * item,const picoos_uint16 itemlenmax,const picoos_char * filterfn)1043 void picodata_info_item(const picoknow_KnowledgeBase kb,
1044                         const picoos_uint8 *pref6ch,
1045                         const picoos_uint8 *item,
1046                         const picoos_uint16 itemlenmax,
1047                         const picoos_char *filterfn)
1048 {
1049 #define SA_USE_PHST 1
1050     picoos_uint16 i;
1051     picoos_uint8 ch;
1052 
1053     if ((itemlenmax < 4) || (item == NULL)) {
1054         PICODBG_INFO_MSG(("invalid item\n"));
1055     }
1056 
1057     /* first 6 char used for prefix */
1058     PICODBG_INFO_MSG_F(filterfn, ("%6s(", pref6ch));
1059 
1060     /* type */
1061     ch = item[0];
1062     if ((32 <= ch) && (ch < 127)) {
1063         PICODBG_INFO_MSG_F(filterfn, ("'%c',", ch));
1064     } else {
1065         PICODBG_INFO_MSG_F(filterfn, ("%3d,", ch));
1066     }
1067     /* info1 */
1068     ch = item[1];
1069     if ((32 <= ch) && (ch < 127))
1070         switch (item[0]) {
1071             case PICODATA_ITEM_PUNC:
1072             case PICODATA_ITEM_BOUND:
1073             case PICODATA_ITEM_CMD:
1074             case PICODATA_ITEM_TOKEN:
1075             case PICODATA_ITEM_FRAME_PAR:
1076                 PICODBG_INFO_MSG_F(filterfn, ("'%c',", ch));
1077                 break;
1078             default:
1079                 PICODBG_INFO_MSG_F(filterfn, ("%3d,", ch));
1080         }
1081     else
1082         PICODBG_INFO_MSG_F(filterfn, ("%3d,", ch));
1083 
1084     /* info2 */
1085     ch = item[2];
1086     if ((32 <= ch) && (ch < 127))
1087         switch (item[0]) {
1088             case PICODATA_ITEM_PUNC:
1089             case PICODATA_ITEM_BOUND:
1090             case PICODATA_ITEM_CMD:
1091             case PICODATA_ITEM_WORDPHON:
1092             case PICODATA_ITEM_SYLLPHON:
1093                 PICODBG_INFO_MSG_F(filterfn, ("'%c',", ch));
1094                 break;
1095             default:
1096                 PICODBG_INFO_MSG_F(filterfn, ("%3d,", ch));
1097         }
1098     else
1099         PICODBG_INFO_MSG_F(filterfn, ("%3d,", ch));
1100 
1101     /* len */
1102     ch = item[3];
1103     PICODBG_INFO_MSG_F(filterfn, ("%3d)", ch));
1104 
1105     for (i = 0; i < ch; i++) {
1106         if ((item[0] == PICODATA_ITEM_WSEQ_GRAPH) ||
1107             (item[0] == PICODATA_ITEM_TOKEN) ||
1108             (item[0] == PICODATA_ITEM_WORDGRAPH) ||
1109             ((item[0] == PICODATA_ITEM_CMD) && !((item[1] == PICODATA_ITEMINFO1_CMD_SPEED) ||
1110                                                  (item[1] == PICODATA_ITEMINFO1_CMD_PITCH) ||
1111                                                  (item[1] == PICODATA_ITEMINFO1_CMD_VOLUME) ||
1112                                                  (item[1] == PICODATA_ITEMINFO1_CMD_SPELL) ||
1113                                                  (item[1] == PICODATA_ITEMINFO1_CMD_SIL)))) {
1114             PICODBG_INFO_MSG_F(filterfn, ("%c", item[4 + i]));
1115         } else {
1116             PICODBG_INFO_MSG_F(filterfn, ("%4d", item[4 + i]));
1117         }
1118     }
1119 
1120 #if defined (SA_USE_PHST)
1121     {
1122 #include "picokdbg.h"
1123         picoos_uint8 j;
1124         picokdbg_Dbg kdbg;
1125         kdbg = picokdbg_getDbg(kb);
1126 
1127         if ((item[0] == PICODATA_ITEM_WORDPHON) ||
1128                 (item[0] == PICODATA_ITEM_SYLLPHON) ||
1129                 ((item[0] == PICODATA_ITEM_CMD) && (item[1] == PICODATA_ITEMINFO1_CMD_PHONEME))) {
1130             if (picokdbg_getPhoneSym(kdbg, item[4])) {
1131                 PICODBG_INFO_MSG_F(filterfn, ("  "));
1132                 for (j = 0; j < item[3]; j++) {
1133                     PICODBG_INFO_MSG_F(filterfn, ("%s",
1134                             picokdbg_getPhoneSym(kdbg, item[4 + j])));
1135                 }
1136             }
1137         }
1138     }
1139 #endif
1140 
1141     PICODBG_INFO_MSG_F(filterfn, ("\n"));
1142 }
1143 
1144 
1145 #endif   /* PICO_DEBUG */
1146 
1147 #ifdef __cplusplus
1148 }
1149 #endif
1150 
1151 
1152 /* picodata.c end */
1153