1b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
2b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
3b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
4b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Licensed under the Apache License, Version 2.0 (the "License");
5b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * you may not use this file except in compliance with the License.
6b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * You may obtain a copy of the License at
7b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
8b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *     http://www.apache.org/licenses/LICENSE-2.0
9b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
10b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Unless required by applicable law or agreed to in writing, software
11b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * distributed under the License is distributed on an "AS IS" BASIS,
12b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * See the License for the specific language governing permissions and
14b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * limitations under the License.
15b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
16b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
17b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @file picocep.c
18b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
19b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Phonetic to Acoustic Mapping PU - Implementation
20b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
21b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
22b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * All rights reserved.
23b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
24b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * History:
25b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - 2009-04-20 -- initial version
26b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
27b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
28b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
29b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
30b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @addtogroup picocep
31b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * <b> Pico Cepstral Smoothing </b>\n
32b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
33b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen itemtype, iteminfo1, iteminfo2, content -> TYPE(INFO1,INFO2)content
34b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen in the following
35b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
36b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen items input
37b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
38b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen processed:
39b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
40b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen - PHONE(PHONID,StatesPerPhone)[FramesPerState|f0Index|mgcIndex]{StatesPerPhone}
41b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
42b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen (StatesPerPhone is a constant (5) for the time being. The content size is therfore allways 34)
43b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
44b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen unprocessed:
45b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen - all other item types are forwarded through the PU without modification
46b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen items output
48b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
49b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen FRAME(PHONID,F0 [?])ceps{25}
50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
51b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen each PHONE produces at least StatesPerPhone FRAME (if each state has FramesPerState == 1), but usually more.
52b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
53b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen minimal input size (before processing starts)
54b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
55b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen other limitations
56b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
57b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
58b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodefs.h"
59b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picoos.h"
60b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodbg.h"
61b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodata.h"
62b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picokpdf.h"
63b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodsp.h"
64b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picocep.h"
65b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
66b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
67b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" {
68b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
69b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if 0
70b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
71b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
72b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
73b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_MAXWINLEN 10000  /* maximum number of frames that can be smoothed, i.e. maximum sentence length */
74b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_MSGSTR_SIZE 32
75b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_IN_BUFF_SIZE PICODATA_BUFSIZE_DEFAULT
76b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
77b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_OUT_DATA_FORMAT PICODATA_ITEMINFO1_FRAME_PAR_DATA_FORMAT_FIXED /* we output coefficients as fixed point values */
78b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
79b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_STEPSTATE_COLLECT         0
80b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_STEPSTATE_PROCESS_PARSE   1
81b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_STEPSTATE_PROCESS_SMOOTH  2
82b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_STEPSTATE_PROCESS_FRAME   3
83b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_STEPSTATE_FEED            4
84b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
85b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_LFZINVPOW 31  /* cannot be higher than 31 because 1<<invpow must fit in uint32 */
86b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_MGCINVPOW 24
87b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_LFZDOUBLEDEC 1
88b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_MGCDOUBLEDEC 0
89b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
90b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef enum picocep_WantMeanOrIvar
91b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
92b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICOCEP_WANTMEAN, PICOCEP_WANTIVAR
93b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} picocep_WantMeanOrIvar_t;
94b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
95b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef enum picocep_WantStaticOrDeltax
96b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
97b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICOCEP_WANTSTATIC, PICOCEP_WANTDELTA, PICOCEP_WANTDELTA2
98b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} picocep_WantStaticOrDelta_t;
99b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   Fixedpoint arithmetic (might go into a separate module if general enough and needed by other modules)
102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PICO_DEBUG) || defined(PICO_DEVEL_MODE)
105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenint numlongmult = 0, numshortmult = 0;
106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW1 (0x1)
109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW2 (0x2)
110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW3 (0x4)
111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW4 (0x8)
112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW5 (0x10)
113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW6 (0x20)
114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW7 (0x40)
115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW8 (0x80)
116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW9 (0x100)
117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW10 (0x200)
118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW11 (0x400)
119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW12 (0x800)
120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW13 (0x1000)
121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW14 (0x2000)
122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW15 (0x4000)
123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW16 (0x8000)
124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW17 (0x10000)
125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW18 (0x20000)
126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW19 (0x40000)
127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW20 (0x80000)
128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW21 (0x100000)
129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW22 (0x200000)
130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW23 (0x400000)
131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW24 (0x800000)
132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW25 (0x1000000)
133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW26 (0x2000000)
134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW27 (0x4000000)
135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW28 (0x8000000)
136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW29 (0x10000000)
137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW30 (0x20000000)
138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define POW31 (0x40000000)
139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* item num restriction: maximum number of extended item heads in headx */
141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_MAXNR_HEADX    60
142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* item num restriction: maximum size of all item contents together in cont */
143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOCEP_MAXSIZE_CBUF 7680 /* (128 * PICOCEP_MAXNR_HEADX) */
144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct
146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picodata_itemhead_t head;
148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 cind;
149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 frame; /* sync position */
150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} picoacph_headx_t;
151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*----------------------------------------------------------
153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen //    Name    :    cep_subobj
154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen //    Function:    subobject definition for the cep processing
155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen //    Shortcut:    cep
156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen //---------------------------------------------------------*/
157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct cep_subobj
158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*----------------------PU voice management------------------------------*/
160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* picorsrc_Voice voice; */
161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*----------------------PU state management------------------------------*/
162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 procState; /* where to take up work at next processing step */
163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool needMoreInput; /* more data necessary to start processing   */
164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* picoos_uint8 force; *//* forced processing (needMoreData but buffers full */
165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 sentenceEnd;
166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 feedFollowState;
167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool inIgnoreState;
168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*----------------------PU input management------------------------------*/
169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 inBuf[PICODATA_MAX_ITEMSIZE]; /* internal input buffer */
170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 inBufSize; /* actually allocated size */
171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 inReadPos, inWritePos; /* next pos to read/write from/to inBuf*/
172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 nextInPos;
173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoacph_headx_t headx[PICOCEP_MAXNR_HEADX];
175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 headxBottom; /* bottom */
176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 headxWritePos; /* next free position; headx is empty if headxBottom == headxWritePos */
177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 cbuf[PICOCEP_MAXSIZE_CBUF];
179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 cbufBufSize; /* actually allocated size */
180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 cbufWritePos; /* length, 0 if empty */
181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*----------------------PU output management-----------------------------*/
183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picodata_itemhead_t framehead;
184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 outBuf[PICODATA_MAX_ITEMSIZE]; /* internal output buffer (one item) */
185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 outBufSize; /* allocated outBuf size */
186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 outReadPos, outWritePos; /* next pos to read/write from/to outBuf*/
187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 nNumFrames;
189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*---------------------- other working variables ---------------------------*/
190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 diag0[PICOCEP_MAXWINLEN], diag1[PICOCEP_MAXWINLEN],
192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            diag2[PICOCEP_MAXWINLEN], WUm[PICOCEP_MAXWINLEN],
193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            invdiag0[PICOCEP_MAXWINLEN];
194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*---------------------- constants --------------------------------------*/
196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 xi[5], x1[2], x2[3], xm[3], xn[2];
197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 xsqi[5], xsq1[2], xsq2[3], xsqm[3], xsqn[2];
198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 scmeanpowLFZ, scmeanpowMGC;
200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 scmeanLFZ, scmeanMGC;
201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*---------------------- indices --------------------------------------*/
203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* index buffer to hold indices as input for smoothing */
204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 indicesLFZ[PICOCEP_MAXWINLEN];
205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 indicesMGC[PICOCEP_MAXWINLEN];
206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 indexReadPos, indexWritePos;
207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 activeEndPos; /* end position of indices to be considered */
208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* this is used for input and output */
210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 phoneId[PICOCEP_MAXWINLEN]; /* synchronised with indexReadPos */
211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*---------------------- coefficients --------------------------------------*/
213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* output coefficients buffer */
214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int16 * outF0;
215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 outF0ReadPos, outF0WritePos;
216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int16 * outXCep;
217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 outXCepReadPos, outXCepWritePos;  /* uint32 needed for MAXWINLEN*ceporder > 2^16 */
218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 * outVoiced;
219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 outVoicedReadPos, outVoicedWritePos;
220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*---------------------- LINGWARE related data -------------------*/
222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* pdflfz knowledge base */
223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picokpdf_PdfMUL pdflfz, pdfmgc;
224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} cep_subobj_t;
226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * picocep_highestBit
229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @brief        find the highest non-zero bit in input x
230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @remarks        this may be implemented by comparing x to powers of 2
231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *                or instead of calling this function perform multiplication
232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *                and consult overflow register if available on target
233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @note        implemented as a series of macros
234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picocep_highestBitNZ(x) (x>=POW17?(x>=POW25?(x>=POW29?(x>=POW31?31:(x>=POW30?30:29)):(x>=POW27?(x>=POW28?28:27):(x>=POW26?26:25))):(x>=POW21?(x>=POW23?(x>=POW24?24:23):(x>=POW22?22:21)):(x>=POW19?(x>=POW20?20:19):(x>=POW18?18:17)))):(x>=POW9?(x>=POW13?(x>=POW15?(x>=POW16?16:15):(x>=POW14?14:13)):(x>=POW11?(x>=POW12?12:11):(x>=POW10?10:9))):(x>=POW5?(x>=POW7?(x>=POW8?8:7):(x>=POW6?6:5)):(x>=POW3?(x>=POW4?4:3):(x>=POW2?2:1)))))
237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picocep_highestBitU(x) (x==0?0:picocep_highestBitNZ(x))
238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picocep_highestBitS(x,zz) (x==0?0:(x<0?((zz)=(-x),picocep_highestBitNZ(zz)):picocep_highestBitNZ(x)))
239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ------------------------------------------------------------------------------
241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen Internal function definitions
242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen ---------------------------------------------------------------------------------*/
243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void initSmoothing(cep_subobj_t * cep);
245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 getFromPdf(picokpdf_PdfMUL pdf, picoos_uint32 vecstart,
247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 cepnum, picocep_WantMeanOrIvar_t wantMeanOrIvar,
248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picocep_WantStaticOrDelta_t wantStaticOrDeltax);
249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void invMatrix(cep_subobj_t * cep, picoos_uint16 N,
251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int16 *smoothcep, picoos_uint8 cepnum,
252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picokpdf_PdfMUL pdf, picoos_uint8 invpow, picoos_uint8 invDoubleDec);
253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint8 makeWUWandWUm(cep_subobj_t * cep, picokpdf_PdfMUL pdf,
255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint16 *indices, picoos_uint16 b, picoos_uint16 N,
256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 cepnum);
257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void getDirect(picokpdf_PdfMUL pdf, picoos_uint16 *indices,
259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint16 activeEndPos,
260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 cepnum, picoos_int16 *smoothcep);
261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void getVoiced(picokpdf_PdfMUL pdf, picoos_uint16 *indices,
263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint16 activeEndPos,
264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 *smoothcep);
265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint16 get_pi_uint16(picoos_uint8 * buf, picoos_uint16 *pos);
267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void treat_phone(cep_subobj_t * cep, picodata_itemhead_t * ihead);
269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint8 forwardingItem(picodata_itemhead_t * ihead);
271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picodata_step_result_t cepStep(register picodata_ProcessingUnit this,
273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int16 mode, picoos_uint16 * numBytesOutput);
274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* --------------------------------------------
276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   generic PU management
277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * --------------------------------------------
278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * initialization of a cep PU (processing unit)
282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    this : handle to a cep PU struct
283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  PICO_OK : init succeded
284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  PICO_ERR_OTHER : init failed
285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
288e9f72c8954f29f10cb4feb16d328a1b5c1fd7169Jean-Michel Trivistatic pico_status_t cepInitialize(register picodata_ProcessingUnit this, picoos_int32 resetMode)
289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*pico_status_t nRes;*/
291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep_subobj_t * cep;
292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this || NULL == this->subObj) {
293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_ERR_OTHER;
294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep = (cep_subobj_t *) this->subObj;
296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* inBuf */
297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->inBufSize = PICODATA_BUFSIZE_CEP;
298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->inReadPos = 0;
299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->inWritePos = 0;
300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* headx and cbuf */
301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->headxBottom = cep->headxWritePos = 0;
302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->cbufBufSize = PICOCEP_MAXSIZE_CBUF;
303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->cbufWritePos = 0;
304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* outBuf */
305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outBufSize = PICODATA_MAX_ITEMSIZE;
306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outReadPos = 0;
307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outWritePos = 0;
308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* indices* */
309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->indexReadPos = 0;
310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->indexWritePos = 0;
311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* outCep, outF0, outVoiced */
312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outXCepReadPos = 0;
313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outXCepWritePos = 0;
314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outVoicedReadPos = 0;
315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outVoicedWritePos = 0;
316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outF0ReadPos = 0;
317b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outF0WritePos = 0;
318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
319b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->needMoreInput = 0;
320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->inIgnoreState = 0;
321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->sentenceEnd = FALSE;
322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->procState = PICOCEP_STEPSTATE_COLLECT;
323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->nNumFrames = 0;
325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*-----------------------------------------------------------------
327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     * MANAGE Item I/O control management
328b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     ------------------------------------------------------------------*/
329b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->activeEndPos = PICOCEP_MAXWINLEN;
330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
331e9f72c8954f29f10cb4feb16d328a1b5c1fd7169Jean-Michel Trivi    if (resetMode == PICO_RESET_FULL) {
3327bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        /* kb pdflfz */
3337bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->pdflfz = picokpdf_getPdfMUL(
3347bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi                this->voice->kbArray[PICOKNOW_KBID_PDF_LFZ]);
335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
3367bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        /* kb pdfmgc */
3377bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->pdfmgc = picokpdf_getPdfMUL(
3387bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi                this->voice->kbArray[PICOKNOW_KBID_PDF_MGC]);
339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
3407bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        /* kb tab phones */
3417bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        /* cep->phones =
3427bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi         picoktab_getPhones(this->voice->kbArray[PICOKNOW_KBID_TAB_PHONES]); */
343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
3447bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        /*---------------------- other working variables ---------------------------*/
3457bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        /* define the (constant) FRAME_PAR item header */
3467bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->framehead.type = PICODATA_ITEM_FRAME_PAR;
3477bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->framehead.info1 = PICOCEP_OUT_DATA_FORMAT;
3487bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->framehead.info2 = cep->pdfmgc->ceporder;
3497bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->framehead.len = sizeof(picoos_uint16) + (cep->framehead.info2 + 4)
3507bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi                * sizeof(picoos_uint16);
3517bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->scmeanpowLFZ = cep->pdflfz->bigpow - cep->pdflfz->meanpow;
3527bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->scmeanpowMGC = cep->pdfmgc->bigpow - cep->pdfmgc->meanpow;
353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
3547bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->scmeanLFZ = (1 << (picoos_uint32) cep->scmeanpowLFZ);
355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
3567bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi        cep->scmeanMGC = (1 << (picoos_uint32) cep->scmeanpowMGC);
357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
3587bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi    }
3597bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi    /* constants used in makeWUWandWUm */
3607bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi    initSmoothing(cep);
361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}/*cepInitialize*/
365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * termination of a cep PU (processing unit)
368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    this : handle to a cep PU struct
369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  PICO_OK : termination succeded
370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  PICO_ERR_OTHER : termination failed
371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t cepTerminate(register picodata_ProcessingUnit this)
375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * deallocation of a cep PU internal sub object
381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    this : handle to a cep PU struct
382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    mm : handle of the engine memory manager
383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  PICO_OK : deallocation succeded
384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  PICO_ERR_OTHER : deallocation failed
385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic pico_status_t cepSubObjDeallocate(register picodata_ProcessingUnit this,
389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_MemoryManager mm)
390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    mm = mm; /* avoid warning "var not used in this function"*/
393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PICO_DEVEL_MODE)
394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    printf("number of long mult is %d, number of short mult is %i\n",numlongmult,numshortmult);
395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#else
396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_INFO_MSG(("number of long mult is %d, number of short mult is %i\n",numlongmult,numshortmult));
397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep_subobj_t * cep = (cep_subobj_t *) this->subObj;
400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(this->common->mm, (void *) &cep->outXCep);
401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(this->common->mm, (void *) &cep->outVoiced);
402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(this->common->mm, (void *) &cep->outF0);
403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(this->common->mm, (void *) &this->subObj);
404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * creates a new cep PU (processing unit)
410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    mm : engine memory manager object pointer
411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    common : engine common object pointer
412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cbIn : PU input buffer
413b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cbOut : PU output buffer
414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    voice : the voice descriptor object
415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  a valid PU handle if creation succeded
416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  NULL : creation failed
417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicodata_ProcessingUnit picocep_newCepUnit(picoos_MemoryManager mm,
421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_Common common, picodata_CharBuffer cbIn,
422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picodata_CharBuffer cbOut, picorsrc_Voice voice)
423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picodata_ProcessingUnit this = picodata_newProcessingUnit(mm, common, cbIn,
425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cbOut, voice);
426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep_subobj_t * cep;
427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (this == NULL) {
429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->initialize = cepInitialize;
432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("set this->step to cepStep"));
434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->step = cepStep;
436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->terminate = cepTerminate;
437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subDeallocate = cepSubObjDeallocate;
438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->subObj = picoos_allocate(mm, sizeof(cep_subobj_t));
439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep = (cep_subobj_t *) this->subObj;
441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
442b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (this->subObj == NULL) {
443b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void*) &this);
444b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    };
446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* allocate output coeeficient buffers */
448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outF0 = (picoos_int16 *) picoos_allocate(this->common->mm,
449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICOCEP_MAXWINLEN * PICOKPDF_MAX_MUL_LFZ_CEPORDER
450b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    * sizeof(picoos_int16));
451b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outXCep = (picoos_int16 *) picoos_allocate(this->common->mm,
452b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICOCEP_MAXWINLEN * PICOKPDF_MAX_MUL_MGC_CEPORDER
453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    * sizeof(picoos_int16));
454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->outVoiced = (picoos_uint8 *) picoos_allocate(this->common->mm,
455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICOCEP_MAXWINLEN * sizeof(picoos_uint8));
456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((NULL == cep->outF0) || (NULL == cep->outXCep) || (NULL
458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            == cep->outVoiced)) {
459b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(this->common->mm, (void *) &(cep->outF0));
460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(this->common->mm, (void *) &(cep->outXCep));
461b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(this->common->mm, (void *) &(cep->outVoiced));
462b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void*) &cep);
463b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void*) &this);
464b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
465b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
4667bc39b0d41efe0d8733490d54e14bc392d9f0b6dJean-Michel Trivi    cepInitialize(this, PICO_RESET_FULL);
467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this;
469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}/*picocep_newCepUnit*/
470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* --------------------------------------------
472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   processing and internal functions
473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * --------------------------------------------
474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
477b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * multiply by 1<<pow and check overflow
478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    a : input value
479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    pow : shift value
480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  multiplied value
481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 picocep_fixptmultpow(picoos_int32 a, picoos_uint8 pow)
485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 b;
487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 zzz;
488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (picocep_highestBitS(a,zzz) + pow < 32) {
490b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        b = a << pow;
491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* clip to maximum positive or negative value */
493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        b = 1 << 31; /* maximum negative value */
494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (a > 0) {
495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            b -= 1; /* maximum positive value */
496b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }PICODBG_WARN(("picocep_fixptmultpow warning: overflow in fixed point multiplication %i*1<<%i.  Clipping to %i\n", a, pow, b));
497b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
498b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return b;
499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
500b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
501b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * divide by 1<<pow with rounding
503b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    a : input value
504b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    pow : shift value
505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  divided value
506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
508b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
509b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 picocep_fixptdivpow(picoos_int32 a, picoos_uint8 pow)
510b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
511b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 big;
512b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
513b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (a == 0) {
514b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return a;
515b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
516b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    big = 1 << (pow - 1);
517b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (a > 0) {
518b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        a = (a + big) >> pow;
519b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        a = -1 * ((-1 * a + big) >> pow);
521b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
522b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
523b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return a;
524b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
527b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * fixed point multiplication of x and y for large values of x or y or both
528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    x,y  : operands 1 & 2, in fixed point S:M:N representation
529b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    bigpow (int) : normalization factor=2**N, where N=number of binary decimal digits
530b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    invDoubleDec : boolean indicating that x has double decimal size.
531b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *             do extra division by 1<<bigpow so that result has again single decimal size
532b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  z(int) : result, in fixed point S:M:N representation
533b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
534b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 picocep_fixptmultdouble(picoos_int32 x, picoos_int32 y,
537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 bigpow, picoos_uint8 invDoubleDec)
538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
539b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 a, b, c, d, e, z;
540b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 big;
541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
542b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    big = 1 << bigpow;
543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
544b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* a = floor(x/big); */
545b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (x >= 0) {
546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        a = x >> bigpow;
547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        b = x - (a << bigpow);
548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
549b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        a = -1 * ((x * -1) >> bigpow); /* most significant 2 bytes of x */
550b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        b = x - (a << bigpow);
551b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
552b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* least significant 2 bytes of x i.e. x modulo big */
554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* c = floor(y/big); */
555b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (y >= 0) {
556b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c = y >> bigpow;
557b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        d = y - (c << bigpow);
558b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c = -1 * ((y * -1) >> bigpow);
560b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        d = y - (c << bigpow);
561b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
562b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
563b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (invDoubleDec == 1) {
564b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        e = a * d + b * c + picocep_fixptdivpow(b * d, bigpow);
565b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        z = a * c + picocep_fixptdivpow(e, bigpow);
566b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
567b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        z = ((a * c) << bigpow) + (a * d + b * c) + picocep_fixptdivpow(b * d,
568b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                bigpow); /* 4 mult and 3 add instead of 1 mult. */
569b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
570b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
571b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return z;
572b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
573b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
574b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
575b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * fixed point multiplication of x and y
576b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    x,y : operands 1 & 2, in fixed point S:M:N representation
577b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    bigpow (int) : normalization factor=2**N, where N=number of binary decimal digits
578b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    invDoubleDec : boolean indicating that x has double decimal size.
579b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *             do extra division by 1<<bigpow so that result has again single decimal size
580b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  z(int) : result, in fixed point S:M:N representation
581b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Notes
582b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - input and output values are 32 bit signed integers
583b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   meant to represent a S.M.N encoding of a floating point value where
584b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   - S : 1 sign bit
585b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   - M : number of binary integer digits (M=32-1-N)
586b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   - N : number of binary decimal digits (N=log2(big))
587b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   the routine supports 2 methods
588b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * -# standard multiplication of x and y
589b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * -# long multiplication of x and y
590b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * under PICO_DEBUG the number of double and single precision multiplications is monitored for accuracy/performance tuning
591b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Calls
592b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - picocep_highestBit
593b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - picocep_fixptmultdouble
594b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
595b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
596b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
597b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 picocep_fixptmult(picoos_int32 x, picoos_int32 y,
598b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 bigpow, picoos_uint8 invDoubleDec)
599b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
600b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 z;
601b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 multsz, pow;
602b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 zz1, zz2;
603b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
604b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* in C, the evaluation order of f() + g() is not defined, so
605b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     * if both have a side effect on e.g. zz, the outcome of zz is not defined.
606b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     * For that reason, picocep_highestBitS(x,zz) + picocep_highestBitS(y,zz)
607b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     * would generate a warning "operation on zz may be undefined" which we
608b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     * avoid by using two different variables zz1 and zz2 */
609b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    multsz = picocep_highestBitS(x,zz1) + picocep_highestBitS(y,zz2);
610b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pow = bigpow;
611b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (invDoubleDec == 1) {
612b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        pow += bigpow;
613b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
614b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
615b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (multsz <= 30) { /* x*y < 1<<30 is safe including rounding in picocep_fixptdivpow, x*y < 1<<31 is safe but not with rounding */
616b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* alternatively perform multiplication and consult overflow register */
617b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        z = picocep_fixptdivpow(x * y, pow);
618b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PICO_DEBUG)
619b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        numshortmult++; /*  keep track of number of short multiplications */
620b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
621b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
622b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PICO_DEBUG)
623b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (multsz> 31 + pow) {
624b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICODBG_WARN(("picocep_fixptmult warning: overflow in fixed point multiplication %i*%i, multsz = %i, pow = %i, decrease bigpow\n", x, y, multsz, pow));
625b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
626b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
627b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        z = picocep_fixptmultdouble(x, y, bigpow, invDoubleDec); /*  perform long multiplication for large x and y */
628b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined(PICO_DEBUG)
629b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        numlongmult++; /*  keep track of number of long multiplications */
630b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
631b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
632b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return z;
633b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}/* picocep_fixptmult */
634b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
635b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
636b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * fixed point ^division of a vs b
637b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    a,b : operands 1 & 2, in fixed point S:M:N representation
638b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    bigpow (int) : normalization factor=2**N, where N=number of binary decimal digits
639b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  z(int) : result, in fixed point S:M:N representation
640b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Notes
641b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - input and output values are 32 bit signed integers
642b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   meant to represent a S.M.N encoding of a floating point value where
643b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   - S : 1 sign bit
644b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   - M : number of binary integer digits (M=32-1-N)
645b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   - N : number of binary decimal digits (N=log2(big))
646b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - standard implementation of division by iteratively calculating
647b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * the remainder and setting corresponding bit
648b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * calculate integer part by integer division (DIV),
649b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * then add X bits of precision in decimal part
650b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
651b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
652b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
653b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 picocep_fixptdiv(picoos_int32 a, picoos_int32 b,
654b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 bigpow)
655b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
656b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 r, c, f, h, stop;
657b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    r = (a < 0) ? -a : a; /* take absolute value; b is already guaranteed to be positive in smoothing operation */
658b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (r == 0) {
659b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return 0;
660b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
661b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    c = 0;
662b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    stop = 0;
663b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
664b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* can speed up slightly by setting stop = 2 => slightly less precision */
665b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    h = r / b; /* in first loop h can be multiple bits, after first loop h can only be 0 or 1 */
666b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* faster implementation on target by using comparison instead of DIV? */
667b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* For our LDL even in first loop h <= 1, but not in backward step */
668b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    c = c + (h << bigpow); /* after first loop simply set bit */
669b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    r = r - h * b; /* corresponds to modulo operation */
670b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    bigpow--;
671b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    r <<= 1;
672b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
673b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((bigpow > stop) && (r != 0)) { /* calculate bigpow bits after fixed point */
674b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* can speed up slightly by setting stop = 2 => slightly less precision */
675b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (r >= b) {
676b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            c += (1 << bigpow); /* after first loop simply set bit */
677b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            r -= b; /* corresponds to modulo operation */
678b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
679b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        bigpow--;
680b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        r <<= 1;
681b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
682b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
683b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (r != 0) {
684b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        f = r + (b >> 1);
685b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (f >= b) {
686b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (f >= b + b) {
687b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c += 2;
688b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
689b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c++;
690b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
691b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
692b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
693b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* final step: do rounding (experimentally improves accuracy for our problem) */
694b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    c = (a >= 0) ? c : -c; /* b is guaranteed to be positive because corresponds to diag0 */
695b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return c;
696b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}/* picocep_fixptdiv */
697b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
698b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
699b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * perform inversion of diagonal element of WUW matrix
700b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    d : diagonal element to be inverted
701b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    rowscpow (int) : fixed point base for each dimension of the vectors stored in the database
702b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    bigpow (int) : fixed point base used during cepstral smoothing
703b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    invpow : fixed point base of inverted pivot elements
704b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return   inverted pivot element
705b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @note
706b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - d is guaranteed positive
707b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
708b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
709b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
710b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 picocep_fixptInvDiagEle(picoos_uint32 d,
711b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8* rowscpow, picoos_uint8 bigpow, picoos_uint8 invpow)
712b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
713b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 r, b, c, h, f, stop;
714b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 dlen;
715b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* picoos_int32 zz; */
716b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    c = 0;
717b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    stop = 0;
718b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
719b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    dlen = picocep_highestBitU(d);
720b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (invpow + bigpow > 30 + dlen) { /* c must be < 2^32, hence d which is >= 2^(dlen-1) must be > 2^(invpow+bigpow-32), or invpow+bigpow must be <= dlen+30*/
721b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *rowscpow = invpow + bigpow - 30 - dlen;PICODBG_DEBUG(("input to picocep_fixptInvDiagEle is %i <= 1<<%i = 1<<invpow+bigpow-32. Choose lower invpow. For now scaling row by 1<<%i\n", d, invpow+bigpow-32, *rowscpow));
722b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
723b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *rowscpow = 0;
724b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
725b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    r = 1 << invpow;
726b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    b = d << (*rowscpow);
727b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
728b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* first */
729b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    h = r / b;
730b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (h > 0) {
731b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c += (h << bigpow);
732b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        r -= h * b;
733b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
734b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    bigpow--;
735b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    r <<= 1;
736b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
737b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* loop */
738b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((bigpow > stop) && (r != 0)) {
739b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (r >= b) {
740b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            c += (1 << bigpow);
741b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            r -= b;
742b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
743b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        bigpow--;
744b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        r <<= 1;
745b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
746b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
747b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (r != 0) {
748b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        f = r + (b >> 1);
749b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (f >= b) {
750b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (f >= b + b) {
751b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c += 2;
752b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
753b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c++;
754b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
755b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
756b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
757b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
758b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return c;
759b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}/* picocep_fixptInvDiagEle */
760b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
761b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
762b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * perform division of two operands a and b by multiplication by inverse of b
763b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    a (int32) : operand 1 in fixed point S:M:N representation
764b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    invb(uint32)   : inverse of operand b, in fixed point P:Q representation (sign is positive)
765b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    bigpow(uint8)  : N = bigpow when invDoubleDec==0, else N = 2*bigpow
766b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    invpow(uint8)  : Q = invpow = number of binary decimal digits for invb
767b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param      invDoubleDec   : boolean to indicate that a and the return value c have 2*N binary decimal digits instead of N
768b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  c(int32)       : result in fixed point S:v:w where w = 2*N when invDoubleDec == 1
769b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @note Calls
770b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - picocep_fixptmult
771b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
772b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
773b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
774b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 picocep_fixptinv(picoos_int32 a, picoos_uint32 invb,
775b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 bigpow, picoos_uint8 invpow, picoos_uint8 invDoubleDec)
776b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
777b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 c;
778b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int8 normpow;
779b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
780b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    c = picocep_fixptmult(a, invb, bigpow, invDoubleDec);
781b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
782b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* if invDoubleDec==0, picocep_fixptmult assumes a and invb are in base 1<<bigpow and returns c = (a*b)/1<<bigpow
783b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     Since invb is in base 1<<invpow instead of 1<<bigpow, normalize c by 1<<(bigpow-invpow)
784b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     if invDoubleDec==1:
785b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     multiply additionally by 1<<bigpow*2 (for invb and c) so that base of c is again 2*bigpow
786b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     this can be seen by setting a=A*big, b=B*big, invb=big2/B, mult(a,invb) = a*invb/(big*big) = A/B*big*big2/(big*big) = A/B*big2/big
787b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     and we want c = A/B*big*big => normfactor = big^3/big2
788b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     */
789b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (invDoubleDec == 1) {
790b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        normpow = 3 * bigpow;
791b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
792b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        normpow = bigpow;
793b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
794b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (normpow < invpow) {
795b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* divide with rounding */
796b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c = picocep_fixptdivpow(c, invpow - normpow);
797b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
798b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c = picocep_fixptmultpow(c, normpow - invpow);
799b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
800b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return c;
801b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
802b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
803b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
804b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * initializes the coefficients to calculate delta and delta-delta values and the squares of the coefficients
805b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cep : the CEP PU sub-object handle
806b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
807b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
808b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
809b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void initSmoothing(cep_subobj_t * cep)
810b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
811b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xi[0] = 1;
812b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xi[1] = -1;
813b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xi[2] = 2;
814b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xi[3] = -4;
815b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xi[4] = 2;
816b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqi[0] = 1;
817b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqi[1] = 1;
818b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqi[2] = 4;
819b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqi[3] = 16;
820b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqi[4] = 4;
821b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
822b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->x1[0] = -1;
823b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->x1[1] = 2;
824b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsq1[0] = 1;
825b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsq1[1] = 4;
826b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
827b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->x2[0] = -1;
828b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->x2[1] = -4;
829b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->x2[2] = 2;
830b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsq2[0] = 1;
831b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsq2[1] = 16;
832b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsq2[2] = 4;
833b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
834b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xm[0] = 1;
835b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xm[1] = 2;
836b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xm[2] = -4;
837b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqm[0] = 1;
838b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqm[1] = 4;
839b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqm[2] = 16;
840b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
841b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xn[0] = 1;
842b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xn[1] = 2;
843b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqn[0] = 1;
844b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->xsqn[1] = 4;
845b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
846b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
847b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
848b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * matrix inversion
849b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cep : PU sub object pointer
850b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    N
851b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    smoothcep : pointer to picoos_int16, sequence of smoothed cepstral vectors
852b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cepnum :  cepstral dimension to be treated
853b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    pdf :  pdf resource
854b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    invpow :  fixed point base for inverse
855b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    invDoubleDec : boolean indicating that result of picocep_fixptinv has fixed point base 2*bigpow
856b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *             picocep_fixptmult absorbs double decimal size by dividing its result by extra factor big
857b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  void
858b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @remarks diag0, diag1, diag2, WUm, invdiag0  globals needed in this function (object members in pico)
859b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
860b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
861b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
862b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void invMatrix(cep_subobj_t * cep, picoos_uint16 N,
863b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int16 *smoothcep, picoos_uint8 cepnum,
864b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picokpdf_PdfMUL pdf, picoos_uint8 invpow, picoos_uint8 invDoubleDec)
865b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
866b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 j, v1, v2, h;
867b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 k;
868b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 rowscpow, prevrowscpow;
869b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 ceporder = pdf->ceporder;
870b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 bigpow = pdf->bigpow;
871b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 meanpow = pdf->meanpow;
872b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
873b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* LDL factorization */
874b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    prevrowscpow = 0;
875b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->invdiag0[0] = picocep_fixptInvDiagEle(cep->diag0[0], &rowscpow,
876b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            bigpow, invpow); /* inverse has fixed point basis 1<<invpow */
877b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->diag1[0] = picocep_fixptinv((cep->diag1[0]) << rowscpow,
878b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->invdiag0[0], bigpow, invpow, invDoubleDec); /* perform division via inverse */
879b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->diag2[0] = picocep_fixptinv((cep->diag2[0]) << rowscpow,
880b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->invdiag0[0], bigpow, invpow, invDoubleDec);
881b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->WUm[0] = (cep->WUm[0]) << rowscpow; /* if diag0 too low, multiply LHS and RHS of row in matrix equation by 1<<rowscpow */
882b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (j = 1; j < N; j++) {
883b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* do forward substitution */
884b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep->WUm[j] = cep->WUm[j] - picocep_fixptmult(cep->diag1[j - 1],
885b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cep->WUm[j - 1], bigpow, invDoubleDec);
886b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (j > 1) {
887b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->WUm[j] = cep->WUm[j] - picocep_fixptmult(cep->diag2[j - 2],
888b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->WUm[j - 2], bigpow, invDoubleDec);
889b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
890b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
891b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* update row j */
892b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        v1 = picocep_fixptmult((cep->diag1[j - 1]) / (1 << rowscpow),
893b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cep->diag0[j - 1], bigpow, invDoubleDec); /* undo scaling by 1<<rowscpow because diag1(j-1) refers to symm ele in column j-1 not in row j-1 */
894b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep->diag0[j] = cep->diag0[j] - picocep_fixptmult(cep->diag1[j - 1],
895b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                v1, bigpow, invDoubleDec);
896b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (j > 1) {
897b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            v2 = picocep_fixptmult((cep->diag2[j - 2]) / (1 << prevrowscpow),
898b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->diag0[j - 2], bigpow, invDoubleDec); /* undo scaling by 1<<prevrowscpow because diag1(j-2) refers to symm ele in column j-2 not in row j-2 */
899b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag0[j] = cep->diag0[j] - picocep_fixptmult(
900b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->diag2[j - 2], v2, bigpow, invDoubleDec);
901b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
902b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        prevrowscpow = rowscpow;
903b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep->invdiag0[j] = picocep_fixptInvDiagEle(cep->diag0[j], &rowscpow,
904b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                bigpow, invpow); /* inverse has fixed point basis 1<<invpow */
905b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep->WUm[j] = (cep->WUm[j]) << rowscpow;
906b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (j < N - 1) {
907b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            h = picocep_fixptmult(cep->diag2[j - 1], v1, bigpow, invDoubleDec);
908b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag1[j] = picocep_fixptinv((cep->diag1[j] - h) << rowscpow,
909b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->invdiag0[j], bigpow, invpow, invDoubleDec); /* eliminate column j below pivot */
910b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
911b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (j < N - 2) {
912b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag2[j] = picocep_fixptinv((cep->diag2[j]) << rowscpow,
913b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->invdiag0[j], bigpow, invpow, invDoubleDec); /* eliminate column j below pivot */
914b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
915b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
916b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
917b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* divide all entries of WUm by diag0 */
918b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (j = 0; j < N; j++) {
919b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep->WUm[j] = picocep_fixptinv(cep->WUm[j], cep->invdiag0[j], bigpow,
920b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                invpow, invDoubleDec);
921b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (invDoubleDec == 1) {
922b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->WUm[j] = picocep_fixptdivpow(cep->WUm[j], bigpow);
923b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
924b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
925b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
926b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* backward substitution */
927b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (j = N - 2; j >= 0; j--) {
928b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep->WUm[j] = cep->WUm[j] - picocep_fixptmult(cep->diag1[j], cep->WUm[j
929b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                + 1], bigpow, invDoubleDec);
930b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (j < N - 2) {
931b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->WUm[j] = cep->WUm[j] - picocep_fixptmult(cep->diag2[j],
932b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->WUm[j + 2], bigpow, invDoubleDec);
933b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
934b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
935b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* copy N frames into smoothcep (only for coeff # "cepnum")  */
936b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* coefficients normalized to occupy short; for correct waveform energy, divide by (1<<(bigpow-meanpow)) then convert e.g. to picoos_single */
937b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    k = cepnum;
938b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (j = 0; j < N; j++) {
939b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        smoothcep[k] = (picoos_int16)(cep->WUm[j]/(1<<meanpow));
940b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        k += ceporder;
941b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
942b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
943b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}/* invMatrix*/
944b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
945b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
946b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Calculate matrix products needed to implement the solution
947b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cep : PU sub object pointer
948b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    pdf :  pointer to picoos_uint8, sequence of pdf vectors, each vector of length 1+ceporder*2+numdeltas*3+ceporder*3
949b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    indices : indices of pdf vectors for all frames in current sentence
950b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    b, N :  to be smoothed frames indices (range will be from b to b+N-1)
951b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cepnum :  cepstral dimension to be treated
952b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  void
953b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @remarks diag0, diag1, diag2, WUm, invdiag0  globals needed in this function (object members in pico)
954b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @remarks WUW --> At x W x A
955b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @remarks WUm --> At x W x b
956b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
957b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
958b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
959b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint8 makeWUWandWUm(cep_subobj_t * cep, picokpdf_PdfMUL pdf,
960b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint16 *indices, picoos_uint16 b, picoos_uint16 N,
961b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 cepnum)
962b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
963b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 Id[2], Idd[3];
964b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*picoos_uint32      vecstart, k;*/
965b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 vecstart;
966b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 *x = NULL, *xsq = NULL;
967b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 mean, ivar;
968b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 i, j, numd = 0, numdd = 0;
969b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 vecsize = pdf->vecsize;
970b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 prev_WUm, prev_diag0, prev_diag1, prev_diag1_1, prev_diag2;
971b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
972b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    prev_WUm = prev_diag0 = prev_diag1 = prev_diag1_1 = prev_diag2 = 0;
973b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i = 0; i < N; i++) {
974b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
975b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if ((1 < i) && (i < N - 2)) {
976b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            x = cep->xi;
977b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            xsq = cep->xsqi;
978b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            numd = 2;
979b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            numdd = 3;
980b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Id[0] = Idd[0] = i - 1;
981b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Id[1] = Idd[2] = i + 1;
982b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Idd[1] = i;
983b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else if (i == 0) {
984b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            x = cep->x1;
985b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            xsq = cep->xsq1;
986b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            numd = numdd = 1;
987b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Id[0] = Idd[0] = 1;
988b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else if (i == 1) {
989b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            x = cep->x2;
990b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            xsq = cep->xsq2;
991b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            numd = 1;
992b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            numdd = 2;
993b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Id[0] = Idd[1] = 2;
994b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Idd[0] = 1;
995b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else if (i == N - 2) {
996b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            x = cep->xm;
997b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            xsq = cep->xsqm;
998b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            numd = 1;
999b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            numdd = 2;
1000b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Id[0] = Idd[0] = N - 3;
1001b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Idd[1] = N - 2;
1002b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else if (i == N - 1) {
1003b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            x = cep->xn;
1004b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            xsq = cep->xsqn;
1005b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            numd = numdd = 1;
1006b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            Id[0] = Idd[0] = N - 2;
1007b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1008b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1009b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* process static means and static inverse variances */
1010b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (i > 0 && indices[b + i] == indices[b + i - 1]) {
1011b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag0[i] = prev_diag0;
1012b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->WUm[i] = prev_WUm;
1013b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1014b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            vecstart = indices[b + i] * vecsize;
1015b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            ivar = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTIVAR,
1016b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTSTATIC);
1017b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            prev_diag0 = cep->diag0[i] = ivar << 2; /* multiply ivar by 4 (4 used to be first entry of xsq) */
1018b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            mean = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTMEAN,
1019b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTSTATIC);
1020b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            prev_WUm = cep->WUm[i] = mean << 1; /* multiply mean by 2 (2 used to be first entry of x) */
1021b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1022b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1023b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* process delta means and delta inverse variances */
1024b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        for (j = 0; j < numd; j++) {
1025b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            vecstart = indices[b + Id[j]] * vecsize;
1026b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            ivar = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTIVAR,
1027b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTDELTA);
1028b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag0[i] += xsq[j] * ivar;
1029b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1030b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            mean = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTMEAN,
1031b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTDELTA);
1032b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (mean != 0) {
1033b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cep->WUm[i] += x[j] * mean;
1034b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1035b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1036b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1037b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* process delta delta means and delta delta inverse variances */
1038b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        for (j = 0; j < numdd; j++) {
1039b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            vecstart = indices[b + Idd[j]] * vecsize;
1040b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            ivar = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTIVAR,
1041b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTDELTA2);
1042b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag0[i] += xsq[numd + j] * ivar;
1043b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1044b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            mean = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTMEAN,
1045b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTDELTA2);
1046b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (mean != 0) {
1047b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cep->WUm[i] += x[numd + j] * mean;
1048b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1049b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1050b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1051b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep->diag0[i] = (cep->diag0[i] + 2) / 4; /* long DIV with rounding */
1052b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cep->WUm[i] = (cep->WUm[i] + 1) / 2; /* long DIV with rounding */
1053b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1054b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* calculate diag(A,-1) */
1055b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (i < N - 1) {
1056b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (i < N - 2) {
1057b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (i > 0 && indices[b + i + 1] == indices[b + i]) {
1058b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->diag1[i] = prev_diag1;
1059b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else {
1060b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    vecstart = indices[b + i + 1] * vecsize;
1061b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /*
1062b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     diag1[i] = getFromPdf(pdf, vecstart, numvuv, ceporder, numdeltas, cepnum,
1063b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     bigpow, meanpowUm, ivarpow, PICOCEP_WANTIVAR, PICOCEP_WANTDELTA2);
1064b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     */
1065b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    prev_diag1 = cep->diag1[i] = getFromPdf(pdf, vecstart,
1066b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cepnum, PICOCEP_WANTIVAR, PICOCEP_WANTDELTA2);
1067b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1068b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /*
1069b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 k = vecstart +pdf->numvuv+pdf->ceporder*2 +    pdf->numdeltas*3 +
1070b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 pdf->ceporder*2 +cepnum;
1071b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 cep->diag1[i] = (picoos_int32)(pdf->content[k]) << pdf->bigpow;
1072b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 */
1073b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
1074b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cep->diag1[i] = 0;
1075b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1076b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (i > 0) {
1077b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (i > 1 && indices[b + i] == indices[b + i - 1]) {
1078b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->diag1[i] += prev_diag1_1;
1079b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else {
1080b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    vecstart = indices[b + i] * vecsize;
1081b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /*
1082b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     k = vecstart + pdf->numvuv + pdf->ceporder * 2 + pdf->numdeltas * 3 + pdf->ceporder * 2 + cepnum;
1083b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     cep->diag1[i] += (picoos_int32)(pdf->content[k]) << pdf->bigpow; */
1084b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* cepnum'th delta delta ivar */
1085b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1086b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    prev_diag1_1 = getFromPdf(pdf, vecstart, cepnum,
1087b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            PICOCEP_WANTIVAR, PICOCEP_WANTDELTA2);
1088b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->diag1[i] += prev_diag1_1;
1089b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1090b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1091b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } /*i < N-1 */
1092b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag1[i] *= -2;
1093b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1094b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1095b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1096b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* calculate diag(A,-2) */
1097b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i = 0; i < N - 2; i++) {
1098b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (i > 0 && indices[b + i + 1] == indices[b + i]) {
1099b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag2[i] = prev_diag2;
1100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            vecstart = indices[b + i + 1] * vecsize;
1102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /*
1103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             k = vecstart + pdf->numvuv + pdf->ceporder * 2 + pdf->numdeltas * 3 + pdf->ceporder * 2 + cepnum;
1104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             cep->diag2[i] = (picoos_int32)(pdf->content[k]) << pdf->bigpow;
1105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             k -= pdf->ceporder;
1106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             ivar = (picoos_int32)(pdf->content[k]) << pdf->bigpow;
1107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen             */
1108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag2[i] = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTIVAR,
1109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTDELTA2);
1110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            ivar = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTIVAR,
1111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTDELTA);
1112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->diag2[i] -= (ivar + 2) / 4;
1113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            prev_diag2 = cep->diag2[i];
1114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return 0;
1118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}/* makeWUWandWUm */
1119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
1121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Retrieve actual values for MGC from PDF resource
1122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    pdf :  pointer to picoos_uint8, sequence of pdf vectors, each vector of length 1+ceporder*2+numdeltas*3+ceporder*3
1123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    vecstart : indices of pdf vectors for all frames in current sentence
1124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cepnum :  cepstral dimension to be treated
1125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    wantMeanOrIvar :  flag to select mean or variance values
1126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    wantStaticOrDeltax :  flag to select static or delta values
1127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  the actual value retrieved
1128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
1129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
1130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 getFromPdf(picokpdf_PdfMUL pdf, picoos_uint32 vecstart,
1132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 cepnum, picocep_WantMeanOrIvar_t wantMeanOrIvar,
1133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picocep_WantStaticOrDelta_t wantStaticOrDeltax)
1134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 s, ind;
1136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 *p;
1137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 ceporder, ceporder2, cc;
1138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 k;
1139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 mean = 0, ivar = 0;
1140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (pdf->numdeltas == 0xFF) {
1142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        switch (wantMeanOrIvar) {
1143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_WANTMEAN:
1144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                switch (wantStaticOrDeltax) {
1145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTSTATIC:
1146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        p = pdf->content
1147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                + (vecstart + pdf->numvuv + cepnum * 2); /* cepnum'th static mean */
1148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        mean = ((picoos_int32) ((picoos_int16) (*(p + 1) << 8))
1149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                | *p) << (pdf->meanpowUm[cepnum]);
1150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTDELTA:
1152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cc = pdf->ceporder + cepnum;
1153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                p = pdf->content + (vecstart + pdf->numvuv + cc * 2); /* cepnum'th delta mean */
1154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        mean = ((picoos_int32) ((picoos_int16) (*(p + 1) << 8))
1155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                | *p) << (pdf->meanpowUm[cc]);
1156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTDELTA2:
1158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cc = pdf->ceporder * 2 + cepnum;
1159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                p = pdf->content + (vecstart + pdf->numvuv + cc * 2); /* cepnum'th delta delta mean */
1160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        mean = ((picoos_int32) ((picoos_int16) (*(p + 1) << 8))
1161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                | *p) << (pdf->meanpowUm[cc]);
1162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    default:
1164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* should never come here */
1165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_ERROR(("unknown type wantStaticOrDeltax = %i", wantStaticOrDeltax));
1166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return mean;
1168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_WANTIVAR:
1170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                switch (wantStaticOrDeltax) {
1171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTSTATIC:
1172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                k = vecstart + pdf->numvuv + pdf->ceporder * 6 + cepnum; /* cepnum'th static ivar */
1173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ivar = (picoos_int32) (pdf->content[k])
1174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        << (pdf->ivarpow[cepnum]);
1175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTDELTA:
1177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ceporder = pdf->ceporder;
1178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                k = vecstart + pdf->numvuv + ceporder * 7 + cepnum; /* cepnum'th delta ivar */
1179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ivar = (picoos_int32) (pdf->content[k])
1180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        << (pdf->ivarpow[ceporder + cepnum]);
1181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTDELTA2:
1183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ceporder = pdf->ceporder;
1184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                k = vecstart + pdf->numvuv + ceporder * 8 + cepnum; /* cepnum'th delta delta ivar */
1185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        ivar = (picoos_int32) (pdf->content[k])
1186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                << (pdf->ivarpow[2 * ceporder + cepnum]);
1187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    default:
1189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* should never get here */
1190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_ERROR(("unknown type wantStaticOrDeltax = %i", wantStaticOrDeltax));
1191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return ivar;
1193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            default:
1195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* should never come here */
1196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICODBG_ERROR(("unknown type wantMeanOrIvar = %n", wantMeanOrIvar));
1197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return 0;
1198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        switch (wantMeanOrIvar) {
1201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_WANTMEAN:
1202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                switch (wantStaticOrDeltax) {
1203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTSTATIC:
1204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        p = pdf->content
1205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                + (vecstart + pdf->numvuv + cepnum * 2); /* cepnum'th static mean */
1206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        mean = ((picoos_int32) ((picoos_int16) (*(p + 1) << 8))
1207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                | *p) << (pdf->meanpowUm[cepnum]);
1208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return mean;
1209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTDELTA:
1211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ceporder = pdf->ceporder;
1212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                s = 0;
1213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ind = 0;
1214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        while ((s < pdf->numdeltas) && (ind < cepnum || (ind
1215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                == 0 && cepnum == 0))) { /* rawmean deltas are sparse so investigate indices in column */
1216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    k = vecstart + pdf->numvuv + ceporder * 2 + s; /* s'th delta index */
1217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    ind = (picoos_uint8) (pdf->content[k]); /* is already picoos_uint8 but just to make explicit */
1218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if (ind == cepnum) {
1219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        k = vecstart + pdf->numvuv + ceporder * 2
1220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                + pdf->numdeltas + s * 2; /* s'th sparse delta mean, corresponds to cepnum'th delta mean */
1221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                mean
1222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        = ((picoos_int32) ((picoos_int16) ((pdf->content[k
1223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                + 1]) << 8)) | pdf->content[k])
1224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                << (pdf->meanpowUm[ceporder
1225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                        + cepnum]);
1226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        return mean;
1227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
1228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    s++;
1229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return 0;
1231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTDELTA2:
1233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ceporder = pdf->ceporder;
1234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ceporder2 = ceporder * 2;
1235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                s = pdf->numdeltas;
1236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ind = 2 * ceporder;
1237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                while ((s-- > 0) && (ind > ceporder + cepnum)) { /* rawmean deltas are sparse so investigate indices in column */
1238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    k = vecstart + pdf->numvuv + ceporder2 + s; /* s'th delta index */
1239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    ind = (picoos_uint8) (pdf->content[k]); /* is already picoos_uint8 but just to make explicit */
1240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if (ind == ceporder + cepnum) {
1241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                k = vecstart + pdf->numvuv + ceporder2
1242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        + pdf->numdeltas + s * 2; /* s'th sparse delta mean, corresponds to cepnum'th delta delta mean */
1243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                mean
1244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        = ((picoos_int32) ((picoos_int16) ((pdf->content[k
1245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                + 1]) << 8)) | pdf->content[k])
1246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                << (pdf->meanpowUm[ceporder2
1247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                        + cepnum]);
1248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        return mean;
1249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
1250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return 0;
1252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    default:
1254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_ERROR(("getFromPdf: unknown type wantStaticOrDeltax = %i\n", wantStaticOrDeltax));
1255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        return 0;
1256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_WANTIVAR:
1259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                switch (wantStaticOrDeltax) {
1260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTSTATIC:
1261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        k = vecstart + pdf->numvuv + pdf->ceporder * 2
1262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                + pdf->numdeltas * 3 + cepnum; /* cepnum'th static ivar */
1263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ivar = (picoos_int32) (pdf->content[k])
1264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        << (pdf->ivarpow[cepnum]);
1265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTDELTA:
1267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ceporder = pdf->ceporder;
1268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        k = vecstart + pdf->numvuv + ceporder * 3
1269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                + pdf->numdeltas * 3 + cepnum; /* cepnum'th delta ivar */
1270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ivar = (picoos_int32) (pdf->content[k])
1271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        << (pdf->ivarpow[ceporder + cepnum]);
1272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    case PICOCEP_WANTDELTA2:
1274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ceporder2 = 2 * pdf->ceporder;
1275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        k = vecstart + pdf->numvuv + ceporder2 + pdf->numdeltas
1276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                * 3 + ceporder2 + cepnum; /* cepnum'th delta delta ivar */
1277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                ivar = (picoos_int32) (pdf->content[k])
1278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        << (pdf->ivarpow[ceporder2 + cepnum]);
1279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        break;
1280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    default:
1281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_ERROR(("unknown type wantStaticOrDeltax = %i", wantStaticOrDeltax));
1282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return ivar;
1284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            default:
1286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICODBG_ERROR(("unknown type wantMeanOrIvar = %i", wantMeanOrIvar));
1287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return 0;
1288b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return 0;
1291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
1294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Retrieve actual values for MGC from PDF resource - Variant "Direct"
1295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    pdf :  pointer to picoos_uint8, sequence of pdf vectors, each vector of length 1+ceporder*2+numdeltas*3+ceporder*3
1296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    indices : indices of pdf vectors for all frames in current sentence
1297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    activeEndPos :  ??
1298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cepnum :  cepstral dimension to be treated
1299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    smoothcep :  ??
1300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  the actual value retrieved
1301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
1302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
1303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void getDirect(picokpdf_PdfMUL pdf, picoos_uint16 *indices,
1305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint16 activeEndPos,
1306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 cepnum, picoos_int16 *smoothcep)
1307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 i;
1309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 j;
1310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 vecstart;
1311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 mean, ivar;
1312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 prev_mean;
1313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 vecsize = pdf->vecsize;
1314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 order = pdf->ceporder;
1315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    j = cepnum;
1317b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    prev_mean = 0;
1318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i = 0; i < activeEndPos; i++) {
1319b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (i > 0 && indices[i] == indices[i - 1]) {
1320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            mean = prev_mean;
1321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            vecstart = indices[i] * vecsize;
1323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            mean = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTMEAN,
1324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTSTATIC);
1325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            ivar = getFromPdf(pdf, vecstart, cepnum, PICOCEP_WANTIVAR,
1326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOCEP_WANTSTATIC);
1327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            prev_mean = mean = picocep_fixptdiv(mean, ivar, pdf->bigpow);
1328b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1329b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        smoothcep[j] = (picoos_int16)(mean/(1<<pdf->meanpow));
1330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        j += order;
1331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
1335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Retrieve actual values for voicing from PDF resource
1336b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    pdf :  pointer to picoos_uint8, sequence of pdf vectors, each vector of length 1+ceporder*2+numdeltas*3+ceporder*3
1337b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    indices : indices of pdf vectors for all frames in current sentence
1338b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    activeEndPos : end position of indices to be considered
1339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return    smoothcep : the values retrieved
1340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
1341b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
1342b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void getVoiced(picokpdf_PdfMUL pdf, picoos_uint16 *indices,
1344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint16 activeEndPos,
1345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 *smoothcep)
1346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 i, j;
1348b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 vecstart;
1349b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 vecsize = pdf->vecsize;
1350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1351b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (pdf->numvuv == 0) {
1352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* do nothing */
1353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1354b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        for (i = 0, j = 0; i < activeEndPos; i++, j++) {
1355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            vecstart = indices[i] * vecsize;
1356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            smoothcep[j] = pdf->content[vecstart]; /* odd value is voiced, even if unvoiced */
1357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** reads platform-independent uint16 from buffer at *pos and advances *pos
1362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    buf : buffer picoos_uint8
1363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    *pos : start position inside buffer of pi uint16
1364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return   the uint16
1365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
1366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
1367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint16 get_pi_uint16(picoos_uint8 * buf, picoos_uint16 *pos)
1369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 res;
1371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    res = buf[(*pos)] | ((picoos_uint16) buf[(*pos) + 1] << 8);
1372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *pos += 2;
1373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return res;
1374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
1376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Looks up indices of one phone item and fills index buffers. Consumes Item
1377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    cep :  the CEP PU sub object pointer
1378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    ihead : pointer to the start of the phone item
1379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
1380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
1381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void treat_phone(cep_subobj_t * cep, picodata_itemhead_t * ihead)
1383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 state, frame, frames;
1385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 indlfz, indmgc;
1386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 pos;
1387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8  bufferFull;
1388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* treat all states
1390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     *    for each state, repeat putting the index into the index buffer framesperstate times.
1391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     */
1392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* set state and frame to the first state and frame in the phone to be considered */
1393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    state = 0; /* the first state to be considered */
1394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    frame = 0; /* the first frame to be considered */
1395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* numFramesPerState: 2 byte, lf0Index: 2 byte, mgcIndex: 2 byte -> 6 bytes per state */
1396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("skipping to phone state %i ",state));
1397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pos = cep->inReadPos + PICODATA_ITEM_HEADSIZE + state * 6;
1398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*  */
1399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("state info starts at inBuf pos %i ",pos));
1400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* get the current frames per state */
1401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    frames = get_pi_uint16(cep->inBuf, &pos);
1402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*  */
1403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("number of frames for this phone state: %i",frames));
1404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*  */
1405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("PARSE starting with frame %i",frame));
1406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    bufferFull = cep->indexWritePos >= PICOCEP_MAXWINLEN;
1408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((state < ihead->info2) && (bufferFull == FALSE)) {
1409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* get the current state's lf0 and mgc indices and adjust according to state */
1411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /*   the indices have to be calculated as follows:
1412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         *   new index = (index-1) + stateoffset(state) */
1413b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        indlfz = get_pi_uint16(cep->inBuf, &pos); /* lfz index */
1415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        indlfz += -1 + cep->pdflfz->stateoffset[state]; /* transform index */
1416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        indmgc = get_pi_uint16(cep->inBuf, &pos); /* mgc index */
1417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        indmgc += -1 + cep->pdfmgc->stateoffset[state]; /* transform index */
1418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* are we reaching the end of the index buffers? */
1420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if ((cep->indexWritePos - frame) + frames > PICOCEP_MAXWINLEN) {
1421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* number of frames that will still fit */
1422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            frames = PICOCEP_MAXWINLEN - (cep->indexWritePos - frame);
1423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            bufferFull = TRUE;
1424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICODBG_DEBUG(("smoothing buffer full at state=%i frame=%i",state, frame));
1425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        while (frame < frames) {
1427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->indicesMGC[cep->indexWritePos] = indmgc;
1428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->indicesLFZ[cep->indexWritePos] = indlfz;
1429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->phoneId[cep->indexWritePos] = ihead->info1;
1430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            cep->indexWritePos++;
1431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            frame++;
1432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* proceed to next state */
1434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_DEBUG(("finished state %i with %i frames, now at index write pos %i",
1435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        state, frames,cep->indexWritePos));
1436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        state++;
1437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (state < ihead->info2) {
1438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            frame = 0;
1439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            frames = get_pi_uint16(cep->inBuf, &pos);
1440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1442b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* consume the phone item */
1443b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep->inReadPos = cep->nextInPos;
1444b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* */
1445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("finished phone, advancing inReadPos to %i",cep->inReadPos));
1446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
1449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Returns true if an Item has to be forwarded to next PU
1450b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param   ihead : pointer to item head structure
1451b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  TRUE : the item should be forwarded
1452b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  FALSE : the item should be consumed
1453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
1454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
1455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint8 forwardingItem(picodata_itemhead_t * ihead)
1457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((PICODATA_ITEM_CMD == ihead->type) && (PICODATA_ITEMINFO1_CMD_IGNSIG
1459b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            == ihead->info1)) {
1460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return FALSE;
1461b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1462b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return TRUE;
1463b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1464b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1465b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1466b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
1467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * performs a step of the cep processing
1468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    this : pointer to current PU (Control Unit)
1469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    mode : mode for the PU (not used)
1470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @param    numBytesOutput : pointer to output number fo bytes produced
1471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @return  one of the "picodata_step_result_t" values
1472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callgraph
1473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @callergraph
1474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picodata_step_result_t cepStep(register picodata_ProcessingUnit this,
1476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int16 mode, picoos_uint16 * numBytesOutput)
1477b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    register cep_subobj_t * cep;
1479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picodata_itemhead_t ihead /* , ohead */;
1480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 * icontents;
1481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    pico_status_t sResult = PICO_OK;
1482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 blen, clen;
1483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 numinb, numoutb;
1484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if defined (PICO_DEBUG)
1486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_char msgstr[PICOCEP_MSGSTR_SIZE];
1487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
1488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    numinb = 0;
1489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    numoutb = 0;
1490b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == this || NULL == this->subObj) {
1492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICODATA_PU_ERROR;
1493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cep = (cep_subobj_t *) this->subObj;
1495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    mode = mode; /* avoid warning "var not used in this function"*/
1496b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1497b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*Init number of output bytes*/
1498b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *numBytesOutput = 0;
1499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1500b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (1) { /* exit via return */
1501b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_DEBUG(("doing pu state %i", cep->procState));
1503b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1504b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        switch (cep->procState) {
1505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_STEPSTATE_COLLECT:
1507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* *************** item collector ***********************************/
1508b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1509b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_TRACE(("COLLECT"));
1510b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1511b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /*collecting items from the PU input buffer*/
1512b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                sResult = picodata_cbGetItem(this->cbIn,
1513b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        &(cep->inBuf[cep->inWritePos]), cep->inBufSize
1514b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                - cep->inWritePos, &blen);
1515b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (PICO_EOF == sResult) { /* there are no more items available and we always need more data here */
1516b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("COLLECT need more data, returning IDLE"));
1517b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_IDLE;
1518b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1519b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_DEBUG(("got item, status: %d", sResult));
1521b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1522b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if ((PICO_OK == sResult) && (blen > 0)) {
1523b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* we now have one item */
1524b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->inWritePos += blen;
1525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = PICOCEP_STEPSTATE_PROCESS_PARSE;
1526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else {
1527b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* ignore item and stay in collect */
1528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_ERROR(("COLLECT got bad result %i", sResult));
1529b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->inReadPos = cep->inWritePos = 0;
1530b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1531b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* return PICODATA_PU_ATOMIC; */
1532b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1533b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1534b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_STEPSTATE_PROCESS_PARSE:
1535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* **************** put item indices into index buffers (with repetition)  ******************/
1536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_TRACE(("PARSE"));
1538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1539b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_DEBUG(("getting info from inBuf in range: [%i,%i[", cep->inReadPos, cep->inWritePos));
1540b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (cep->inWritePos <= cep->inReadPos) {
1541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* no more items in inBuf */
1542b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* we try to get more data */
1543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("no more items in inBuf, try to collect more"));
1544b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* cep->needMoreInput = TRUE; */
1545b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->inReadPos = cep->inWritePos = 0;
1546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = PICOCEP_STEPSTATE_COLLECT;
1547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
1548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1549b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* look at the current item */
1550b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /*verify that current item is valid */
1551b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (!picodata_is_valid_item(cep->inBuf + cep->inReadPos,
1552b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->inWritePos - cep->inReadPos)) {
1553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_ERROR(("found invalid item"));
1554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    sResult = picodata_get_iteminfo(
1555b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->inBuf + cep->inReadPos, cep->inWritePos
1556b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    - cep->inReadPos, &ihead, &icontents);PICODBG_DEBUG(("PARSE bad item %s",picodata_head_to_string(&ihead,msgstr,PICOCEP_MSGSTR_SIZE)));
1557b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1558b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_ERROR;
1559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1560b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1561b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                sResult = picodata_get_iteminfo(cep->inBuf + cep->inReadPos,
1562b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->inWritePos - cep->inReadPos, &ihead, &icontents);
1563b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1564b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (PICO_EXC_BUF_UNDERFLOW == sResult) {
1565b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* no more items in inBuf */
1566b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* we try to get more data */
1567b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("no more items in inBuf, try to collect more"));
1568b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* cep->needMoreInput = TRUE; */
1569b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->inReadPos = cep->inWritePos = 0;
1570b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = PICOCEP_STEPSTATE_COLLECT;
1571b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
1572b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else if (PICO_OK != sResult) {
1573b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_ERROR(("unknown exception (sResult == %i)",sResult));
1574b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return (picodata_step_result_t) picoos_emRaiseException(
1575b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            this->common->em, sResult, NULL, NULL);
1576b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
1577b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1578b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1579b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_DEBUG(("PARSE looking at item %s",picodata_head_to_string(&ihead,msgstr,PICOCEP_MSGSTR_SIZE)));
1580b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1581b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cep->nextInPos = PICODATA_ITEM_HEADSIZE + ihead.len;
1582b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1583b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* we decide what to do next depending on the item and the state of the index buffer:
1584b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 * - process buffer if buffer not empty and sentence end or flush or ignsig/start (don't consume item yet)
1585b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 * - fill buffer with (part of) phone contents if item is a phone
1586b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 * - consume or copy for later output otherwise
1587b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 */
1588b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1589b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (cep->inIgnoreState) {
1590b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if ((PICODATA_ITEM_CMD == ihead.type)
1591b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            && (PICODATA_ITEMINFO1_CMD_IGNSIG == ihead.info1)
1592b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            && (PICODATA_ITEMINFO2_CMD_END == ihead.info2)) {
1593b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->inIgnoreState = 0;
1594b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }PICODBG_DEBUG(("cep: PARSE consuming item of inBuf"));
1595b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->inReadPos = cep->nextInPos;
1596b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
1597b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1598b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1599b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* see if it is a sentence end boundary or termination boundary (flush) and there are indices to smooth -> smooth */
1600b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if ((PICODATA_ITEM_BOUND == ihead.type)
1601b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        && ((PICODATA_ITEMINFO1_BOUND_SEND == ihead.info1)
1602b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                || (PICODATA_ITEMINFO1_BOUND_TERM == ihead.info1))
1603b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        && (cep->indexWritePos > 0)) {
1604b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* we smooth the buffer */
1605b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->activeEndPos = cep->indexWritePos;
1606b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->sentenceEnd = TRUE;
1607b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* output whatever we got */
1608b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("cep: PARSE found sentence terminator; setting activeEndPos to %i",cep->activeEndPos));
1609b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = PICOCEP_STEPSTATE_PROCESS_SMOOTH;
1610b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
1611b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else if (PICODATA_ITEM_PHONE == ihead.type) {
1612b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* it is a phone */
1613b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("cep: PARSE treating PHONE"));
1614b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    treat_phone(cep, &ihead);
1615b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1616b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else {
1617b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if ((PICODATA_ITEM_CMD == ihead.type)
1618b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            && (PICODATA_ITEMINFO1_CMD_IGNSIG == ihead.info1)
1619b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            && (PICODATA_ITEMINFO2_CMD_START == ihead.info2)) {
1620b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->inIgnoreState = 1;
1621b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
1622b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* sentence end or flush remaining after frame or other non-processable item, e.g. command */
1623b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* do we have to forward? */
1624b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if (forwardingItem(&ihead)) {
1625b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* if no active frames, output immediately */
1626b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        if (cep->indexWritePos <= 0) {
1627b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* copy item to outBuf */
1628b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            PICODBG_DEBUG(("PARSE copy item in inBuf to outBuf"));
1629b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            picodata_copy_item(cep->inBuf + cep->inReadPos,
1630b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cep->inWritePos - cep->inReadPos,
1631b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cep->outBuf, cep->outBufSize, &blen);
1632b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->outWritePos += blen;
1633b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            PICODATA_INFO_ITEM(this->voice->kbArray[PICOKNOW_KBID_DBG],
1634b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    (picoos_uint8 *)"cep: do forward item ",
1635b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cep->outBuf, PICODATA_MAX_ITEMSIZE);
1636b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* output item and then go to parse to treat a new item. */
1637b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->feedFollowState
1638b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    = PICOCEP_STEPSTATE_PROCESS_PARSE;
1639b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->procState = PICOCEP_STEPSTATE_FEED;
1640b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        } else if ((cep->headxWritePos < PICOCEP_MAXNR_HEADX)
1641b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                && (cep->cbufWritePos + ihead.len
1642b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        < cep->cbufBufSize)) {
1643b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* there is enough space to store item */
1644b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            PICODBG_DEBUG(("unhandled item (type %c, length %i). Storing associated with index %i",ihead.type, ihead.len, cep->indexWritePos));
1645b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            sResult
1646b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    = picodata_get_itemparts(
1647b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                            cep->inBuf + cep->inReadPos,
1648b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                            cep->inWritePos - cep->inReadPos,
1649b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                            &(cep->headx[cep->headxWritePos].head),
1650b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                            &(cep->cbuf[cep->cbufWritePos]),
1651b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                            cep->cbufBufSize
1652b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                                    - cep->cbufWritePos, &clen);
1653b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1654b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            if (sResult != PICO_OK) {
1655b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                PICODBG_ERROR(("problem getting item parts"));
1656b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                picoos_emRaiseException(this->common->em,
1657b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        sResult, NULL, NULL);
1658b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                return PICODATA_PU_ERROR;
1659b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            }
1660b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* remember sync position */
1661b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->headx[cep->headxWritePos].frame
1662b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    = cep->indexWritePos;
1663b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1664b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            if (clen > 0) {
1665b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                cep->headx[cep->headxWritePos].cind
1666b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                        = cep->cbufWritePos;
1667b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                cep->cbufWritePos += clen;
1668b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            } else {
1669b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                cep->headx[cep->headxWritePos].cind = 0;
1670b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            }
1671b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->headxWritePos++;
1672b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        } else {
1673b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* buffer full, smooth and output whatever we got */
1674b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            PICODBG_DEBUG(("PARSE is forced to smooth prematurely; setting activeEndPos to %i", cep->activeEndPos));
1675b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->procState = PICOCEP_STEPSTATE_PROCESS_SMOOTH;
1676b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* don't consume item yet */
1677b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            break;
1678b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        }
1679b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    } else {
1680b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }PICODBG_DEBUG(("cep: PARSE consuming item of inBuf"));
1681b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->inReadPos = cep->nextInPos;
1682b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1683b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1684b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1685b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_STEPSTATE_PROCESS_SMOOTH:
1686b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* **************** smooth (indexed) coefficients and store smoothed in outBuffers  ****************/
1687b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1688b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_TRACE(("SMOOTH"));
1689b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                {
1690b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picokpdf_PdfMUL pdf;
1691b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1692b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* picoos_uint16 framesTreated = 0; */
1693b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_uint8 cepnum;
1694b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_uint16 N;
1695b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1696b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    N = cep->activeEndPos; /* numframes in current step */
1697b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1698b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* the range to be smoothed starts at 0 and is N long */
1699b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1700b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* smooth each cepstral dimension separately */
1701b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* still to be experimented if higher order coeff can remain unsmoothed, i.e. simple copy from pdf */
1702b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1703b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* reset the f0, ceps and voiced outfuffers */
1704b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outXCepReadPos = cep->outXCepWritePos = 0;
1705b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outVoicedReadPos = cep->outVoicedWritePos = 0;
1706b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outF0ReadPos = cep->outF0WritePos = 0;
1707b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1708b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("smoothing %d frames\n", N));
1709b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1710b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* smooth f0 */
1711b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    pdf = cep->pdflfz;
1712b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    for (cepnum = 0; cepnum < pdf->ceporder; cepnum++) {
1713b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        if (cep->activeEndPos <= 0) {
1714b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* do nothing */
1715b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        } else if (3 < N) {
1716b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            makeWUWandWUm(cep, pdf, cep->indicesLFZ, 0, N,
1717b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cepnum); /* update diag0, diag1, diag2, WUm */
1718b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            invMatrix(cep, N, cep->outF0 + cep->outF0WritePos, cepnum, pdf,
1719b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    PICOCEP_LFZINVPOW, PICOCEP_LFZDOUBLEDEC);
1720b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        } else {
1721b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            getDirect(pdf, cep->indicesLFZ, cep->activeEndPos,
1722b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cepnum, cep->outF0 + cep->outF0WritePos);
1723b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        }
1724b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }/* end for cepnum  */
1725b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outF0WritePos += cep->activeEndPos * pdf->ceporder;
1726b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1727b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* smooth mgc */
1728b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    pdf = cep->pdfmgc;
1729b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    for (cepnum = 0; cepnum < pdf->ceporder; cepnum++) {
1730b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        if (cep->activeEndPos <= 0) {
1731b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            /* do nothing */
1732b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        } else if (3 < N) {
1733b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            makeWUWandWUm(cep, pdf, cep->indicesMGC, 0, N,
1734b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cepnum); /* update diag0, diag1, diag2, WUm */
1735b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            invMatrix(cep, N, cep->outXCep
1736b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                            + cep->outXCepWritePos, cepnum,
1737b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    pdf, PICOCEP_MGCINVPOW,
1738b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    PICOCEP_MGCDOUBLEDEC);
1739b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        } else {
1740b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            getDirect(pdf, cep->indicesMGC, cep->activeEndPos,
1741b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cepnum, cep->outXCep + cep->outXCepWritePos);
1742b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        }
1743b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }/* end for cepnum  */
1744b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outXCepWritePos += cep->activeEndPos * pdf->ceporder;
1745b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1746b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    getVoiced(pdf, cep->indicesMGC, cep->activeEndPos, cep->outVoiced
1747b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    + cep->outVoicedWritePos);
1748b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outVoicedWritePos += cep->activeEndPos;
1749b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1750b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1751b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* setting indexReadPos to the next active index to be used. (will be advanced by FRAME when
1752b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 * reading the phoneId */
1753b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cep->indexReadPos = 0;
1754b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cep->procState = PICOCEP_STEPSTATE_PROCESS_FRAME;
1755b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                return PICODATA_PU_BUSY; /*data to feed*/
1756b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1757b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1758b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1759b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_STEPSTATE_PROCESS_FRAME:
1760b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1761b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* *************** creating output items (type FRAME) ***********************************/
1762b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1763b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_TRACE(("FRAME"));
1764b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1765b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if ((cep->headxBottom < cep->headxWritePos)
1766b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        && (cep->headx[cep->headxBottom].frame
1767b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                <= cep->indexReadPos)) {
1768b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1769b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* output item in headx/cbuf */
1770b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* copy item to outBuf */
1771b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("FRAME copy item in inBuf to outBuf"));
1772b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picodata_put_itemparts(
1773b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            &(cep->headx[cep->headxBottom].head),
1774b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            &(cep->cbuf[cep->headx[cep->headxBottom].cind]),
1775b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->headx[cep->headxBottom].head.len, cep->outBuf,
1776b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->outBufSize, &blen);
1777b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outWritePos += blen;
1778b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* consume item in headx/cbuf */
1779b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("PARSE consuming item of headx/cbuf"));
1780b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->headxBottom++;
1781b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1782b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* output item and then go to parse to treat a new item. */
1783b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->feedFollowState = PICOCEP_STEPSTATE_PROCESS_FRAME;
1784b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = PICOCEP_STEPSTATE_FEED;
1785b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    break;
1786b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1787b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1788b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (cep->indexReadPos < cep->activeEndPos) {
1789b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /*------------  there are frames to output ----------------------------------------*/
1790b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* still frames to output, create new FRAME_PAR item */
1791b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1792b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->nNumFrames++;
1793b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1794b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("FRAME creating FRAME_PAR: active: [0,%i[, read=%i, write=%i",
1795b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cep->activeEndPos, cep->indexReadPos, cep->indexWritePos
1796b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            ));
1797b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1798b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* create FRAME_PAR items from cep->outXX one by one */
1799b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1800b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* converting the ceps shorts into floats:
1801b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     * scmeanpow = pdf->bigpow - pdf->meanpow;
1802b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     * for all sval:
1803b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     *   fval = (picoos_single) sval / scmeanpow;
1804b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                     */
1805b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1806b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outWritePos = cep->outReadPos = 0;
1807b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outBuf[cep->outWritePos++] = cep->framehead.type;
1808b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outBuf[cep->outWritePos++] = cep->framehead.info1;
1809b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outBuf[cep->outWritePos++] = cep->framehead.info2;
1810b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->outBuf[cep->outWritePos++] = cep->framehead.len;
1811b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1812b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("FRAME  writing position after header: %i",cep->outWritePos));
1813b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1814b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    {
1815b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        picoos_uint16 tmpUint16;
1816b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        picoos_int16 tmpInt16;
1817b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        picoos_uint16 i;
1818b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1819b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* */
1820b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODBG_DEBUG(("FRAME reading phoneId[%i] = %c:",cep->indexReadPos, cep->phoneId[cep->indexReadPos]));
1821b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        /* */
1822b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1823b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        tmpUint16
1824b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                = (picoos_uint16) cep->phoneId[cep->indexReadPos];
1825b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1826b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        picoos_mem_copy((void *) &tmpUint16,
1827b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                (void *) &cep->outBuf[cep->outWritePos],
1828b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                sizeof(tmpUint16));
1829b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1830b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->outWritePos += sizeof(tmpUint16);
1831b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1832b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODBG_DEBUG(("FRAME  writing position after phone id: %i",cep->outWritePos));
1833b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1834b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        for (i = 0; i < cep->pdflfz->ceporder; i++) {
1835b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1836b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            tmpUint16 = (cep->outVoiced[cep->outVoicedReadPos]
1837b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    & 0x01) ? cep->outF0[cep->outF0ReadPos]
1838b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    : (picoos_uint16) 0;
1839b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1840b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            picoos_mem_copy((void *) &tmpUint16,
1841b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    (void *) &cep->outBuf[cep->outWritePos],
1842b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    sizeof(tmpUint16));
1843b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->outWritePos += sizeof(tmpUint16);
1844b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1845b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            tmpUint16
1846b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    = (picoos_uint16) (cep->outVoiced[cep->outVoicedReadPos]);
1847b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            picoos_mem_copy((void *) &tmpUint16,
1848b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    (void *) &cep->outBuf[cep->outWritePos],
1849b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    sizeof(tmpUint16));
1850b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->outWritePos += sizeof(tmpUint16);
1851b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            tmpUint16
1852b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    = (picoos_uint16) (cep->outF0[cep->outF0ReadPos]);
1853b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            picoos_mem_copy((void *) &tmpUint16,
1854b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    (void *) &cep->outBuf[cep->outWritePos],
1855b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    sizeof(tmpUint16));
1856b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->outWritePos += sizeof(tmpUint16);
1857b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1858b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->outVoicedReadPos++;
1859b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->outF0ReadPos++;
1860b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        }
1861b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1862b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODBG_DEBUG(("FRAME writing position after f0: %i",cep->outWritePos));
1863b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1864b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        for (i = 0; i < cep->pdfmgc->ceporder; i++) {
1865b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            tmpInt16 = cep->outXCep[cep->outXCepReadPos++];
1866b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            picoos_mem_copy((void *) &tmpInt16,
1867b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    (void *) &cep->outBuf[cep->outWritePos],
1868b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    sizeof(tmpInt16));
1869b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                            cep->outWritePos += sizeof(tmpInt16);
1870b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        }
1871b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1872b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODBG_DEBUG(("FRAME  writing position after cepstrals: %i",cep->outWritePos));
1873b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1874b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        tmpUint16
1875b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                = (picoos_uint16) cep->indicesMGC[cep->indexReadPos++];
1876b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1877b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        picoos_mem_copy((void *) &tmpUint16,
1878b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                (void *) &cep->outBuf[cep->outWritePos],
1879b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                sizeof(tmpUint16));
1880b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1881b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODBG_DEBUG(("FRAME  writing position after mgc index: %i",cep->outWritePos));
1882b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1883b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->outWritePos += sizeof(tmpUint16);
1884b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1885b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
1886b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* finished to create FRAME_PAR, now output and then come back*/
1887b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->feedFollowState = PICOCEP_STEPSTATE_PROCESS_FRAME;
1888b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = PICOCEP_STEPSTATE_FEED;
1889b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1890b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else if (cep->sentenceEnd) {
1891b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /*------------  no more frames to output at end of sentence ----------------------------------------*/
1892b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_INFO(("End of sentence - Processed frames : %d",
1893b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                    cep->nNumFrames));
1894b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->nNumFrames = 0;PICODBG_DEBUG(("FRAME no more active frames for this sentence"));
1895b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* no frames left in this sentence*/
1896b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* reset for new sentence */
1897b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    initSmoothing(cep);
1898b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->sentenceEnd = FALSE;
1899b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->indexReadPos = cep->indexWritePos = 0;
1900b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->activeEndPos = PICOCEP_MAXWINLEN;
1901b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->headxBottom = cep->headxWritePos = 0;
1902b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->cbufWritePos = 0;
1903b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = PICOCEP_STEPSTATE_PROCESS_PARSE;
1904b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else {
1905b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /*------------  no more frames can be output but sentence end not reached ----------------------------------------*/
1906b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("Maximum number of frames per sentence reached"));
1907b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = PICOCEP_STEPSTATE_PROCESS_PARSE;
1908b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1909b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /*----------------------------------------------------*/
1910b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1911b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1912b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOCEP_STEPSTATE_FEED:
1913b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* ***********************************************************************/
1914b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* FEED: combine input item with pos/phon pairs to output item */
1915b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* ***********************************************************************/
1916b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1917b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_DEBUG(("FEED"));
1918b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1919b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_DEBUG(("FEED putting outBuf item into cb"));
1920b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1921b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /*feeding items to PU output buffer*/
1922b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                sResult = picodata_cbPutItem(this->cbOut, cep->outBuf,
1923b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->outBufSize, &blen);
1924b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1925b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (PICO_EXC_BUF_OVERFLOW == sResult) {
1926b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* we have to redo this item */
1927b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("FEED got overflow, returning PICODATA_PU_OUT_FULL"));
1928b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_OUT_FULL;
1929b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else if (PICO_OK == sResult) {
1930b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1931b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if (cep->outBuf[0] != 'k') {
1932b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        PICODATA_INFO_ITEM(this->voice->kbArray[PICOKNOW_KBID_DBG],
1933b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                (picoos_uint8 *)"cep: ",
1934b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                                cep->outBuf, PICODATA_MAX_ITEMSIZE);
1935b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
1936b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1937b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    *numBytesOutput += blen;
1938b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /*-------------------------*/
1939b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /*reset the output pointers*/
1940b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /*-------------------------*/
1941b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    if (cep->outReadPos >= cep->outWritePos) {
1942b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->outReadPos = 0;
1943b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        cep->outWritePos = 0;
1944b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
1945b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = cep->feedFollowState;
1946b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("FEED ok, going back to procState %i", cep->procState));
1947b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return PICODATA_PU_BUSY;
1948b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else {
1949b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_DEBUG(("FEED got exception %i when trying to output item",sResult));
1950b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    cep->procState = cep->feedFollowState;
1951b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    return (picodata_step_result_t) sResult;
1952b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1953b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1954b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1955b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            default:
1956b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /*NOT feeding items*/
1957b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                sResult = PICO_EXC_BUF_IGNORE;
1958b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1959b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }/*end switch (cep->procState) */
1960b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICODATA_PU_BUSY; /*check if there is more data to process after feeding*/
1961b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1962b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }/*end while*/
1963b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* we should never come here */
1964b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICODATA_PU_ERROR;
1965b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}/*cepStep*/
1966b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1967b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Picocep.c end */
1968