Home | History | Annotate | Download | only in lib
      1 /*
      2  * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /**
     17  * @file picosig.c
     18  *
     19  * Signal Generation PU - Implementation
     20  *
     21  * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
     22  * All rights reserved.
     23  *
     24  * History:
     25  * - 2009-04-20 -- initial version
     26  *
     27  */
     28 
     29 #include "picoos.h"
     30 #include "picodsp.h"
     31 #include "picosig2.h"
     32 #include "picodata.h"
     33 #include "picosig.h"
     34 #include "picodbg.h"
     35 #include "picokpdf.h"
     36 
     37 #ifdef __cplusplus
     38 extern "C" {
     39 #endif
     40 #if 0
     41 }
     42 #endif
     43 
     44 #define PICOSIG_IN_BUFF_SIZE PICODATA_BUFSIZE_SIG   /*input buffer size for SIG */
     45 #define PICOSIG_OUT_BUFF_SIZE PICODATA_BUFSIZE_SIG  /*output buffer size for SIG*/
     46 
     47 #define PICOSIG_COLLECT     0
     48 #define PICOSIG_SCHEDULE    1
     49 #define PICOSIG_PLAY        2
     50 #define PICOSIG_PROCESS     3
     51 #define PICOSIG_FEED        4
     52 
     53 /*----------------------------------------------------------
     54  // Internal function declarations
     55  //---------------------------------------------------------*/
     56 
     57 static picodata_step_result_t sigStep(register picodata_ProcessingUnit this,
     58         picoos_int16 mode, picoos_uint16 * numBytesOutput);
     59 
     60 /*----------------------------------------------------------
     61  // Name    :   sig_subobj
     62  // Function:   subobject definition for the sig processing
     63  // Shortcut:   sig
     64  //---------------------------------------------------------*/
     65 typedef struct sig_subobj
     66 {
     67     /*----------------------PU voice management------------------------------*/
     68     /* picorsrc_Voice voice; */
     69     /*----------------------PU state management------------------------------*/
     70     picoos_uint8 procState; /* where to take up work at next processing step */
     71     picoos_uint8 retState;  /* where to return after next processing step */
     72     picoos_uint8 needMoreInput; /* more data necessary to start processing   */
     73     /*----------------------PU input management------------------------------*/
     74     picoos_uint8 inBuf[PICOSIG_IN_BUFF_SIZE]; /* internal input buffer */
     75     picoos_uint16 inBufSize;/* actually allocated size */
     76     picoos_uint16 inReadPos, inWritePos; /* next pos to read/write from/to inBuf*/
     77     /*Input audio file management*/
     78     picoos_char sInSDFileName[255];
     79     picoos_SDFile sInSDFile;
     80     picoos_uint32 sInSDFilePos;
     81     /*----------------------PU output management-----------------------------*/
     82     picoos_uint8 outBuf[PICOSIG_OUT_BUFF_SIZE]; /* internal output buffer */
     83     picoos_uint16 outBufSize;                /* actually allocated size */
     84     picoos_uint16 outReadPos, outWritePos;  /* next pos to read/write from/to outBuf*/
     85     picoos_bool outSwitch;                  /* output destination switch 0:buffer, 1:file*/
     86     picoos_char sOutSDFileName[255];        /* output file name */
     87     picoos_SDFile sOutSDFile;               /* output file handle */
     88     picoos_single fSampNorm;                /* running normalization factor */
     89     picoos_uint32 nNumFrame;                /* running count for frame number in output items */
     90     /*---------------------- other working variables ---------------------------*/
     91     picoos_uint8 innerProcState; /*where to take up work at next processing step*/
     92     /*-----------------------Definition of the local storage for this PU--------*/
     93     sig_innerobj_t sig_inner;
     94     picoos_single pMod; /*pitch modifier*/
     95     picoos_single vMod; /*Volume modifier*/
     96     picoos_single sMod; /*speaker modifier*/
     97     /*knowledge bases */
     98     picokpdf_PdfMUL pdflfz, pdfmgc;
     99     picoos_uint32 scmeanpowLFZ, scmeanpowMGC;
    100     picoos_uint32 scmeanLFZ, scmeanMGC;
    101     picokpdf_PdfPHS pdfphs;
    102 
    103 } sig_subobj_t;
    104 
    105 /* ******************************************************************************
    106  *   generic PU management
    107  ********************************************************************************/
    108 
    109 /**
    110  * initialization of the PU (processing unit)
    111  * @param    this : sig PU object
    112  * @return  PICO_OK : init ok
    113  * @return  PICO_ERR_OTHER : init failed
    114  * @callgraph
    115  * @callergraph
    116  */
    117 static pico_status_t sigInitialize(register picodata_ProcessingUnit this, picoos_int32 resetMode)
    118 {
    119     sig_subobj_t *sig_subObj;
    120     if (NULL == this || NULL == this->subObj) {
    121         return PICO_ERR_OTHER;
    122     }
    123     sig_subObj = (sig_subobj_t *) this->subObj;
    124     sig_subObj->inBufSize = PICOSIG_IN_BUFF_SIZE;
    125     sig_subObj->outBufSize = PICOSIG_OUT_BUFF_SIZE;
    126     sig_subObj->inReadPos = 0;
    127     sig_subObj->inWritePos = 0;
    128     sig_subObj->outReadPos = 0;
    129     sig_subObj->outWritePos = 0;
    130     sig_subObj->needMoreInput = 0;
    131     sig_subObj->procState = PICOSIG_COLLECT;
    132     sig_subObj->retState = PICOSIG_COLLECT;
    133     sig_subObj->innerProcState = 0;
    134     sig_subObj->nNumFrame = 0;
    135 
    136     /*-----------------------------------------------------------------
    137      * MANAGE Item I/O control management
    138      ------------------------------------------------------------------*/
    139     sig_subObj->sInSDFile = NULL;
    140     sig_subObj->sInSDFilePos = 0;
    141     sig_subObj->sInSDFileName[0] = '\0';
    142     sig_subObj->outSwitch = 0; /*PU sends output to buffer (nextPU)*/
    143     sig_subObj->sOutSDFile = NULL;
    144     sig_subObj->sOutSDFileName[0] = '\0';
    145     sig_subObj->nNumFrame = 0;
    146 
    147     /*-----------------------------------------------------------------
    148      * MANAGE LINGWARE INITIALIZATION IF NEEDED
    149      ------------------------------------------------------------------*/
    150     if (resetMode == PICO_RESET_FULL) {
    151         /*not done when resetting SOFT*/
    152         sig_subObj->pdfmgc = picokpdf_getPdfMUL(
    153                 this->voice->kbArray[PICOKNOW_KBID_PDF_MGC]);
    154         sig_subObj->pdflfz = picokpdf_getPdfMUL(
    155                 this->voice->kbArray[PICOKNOW_KBID_PDF_LFZ]);
    156         sig_subObj->pdfphs = picokpdf_getPdfPHS(
    157                 this->voice->kbArray[PICOKNOW_KBID_PDF_PHS]);
    158 
    159         sig_subObj->scmeanpowLFZ = sig_subObj->pdflfz->bigpow
    160                 - sig_subObj->pdflfz->meanpow;
    161         sig_subObj->scmeanpowMGC = sig_subObj->pdfmgc->bigpow
    162                 - sig_subObj->pdfmgc->meanpow;
    163         sig_subObj->scmeanLFZ = (1 << (picoos_uint32) sig_subObj->scmeanpowLFZ);
    164         sig_subObj->scmeanMGC = (1 << (picoos_uint32) sig_subObj->scmeanpowMGC);
    165         sig_subObj->fSampNorm = PICOSIG_NORM1 * sig_subObj->pdfmgc->amplif;
    166         /*-----------------------------------------------------------------
    167          * Initialize memory for DSP
    168          * ------------------------------------------------------------------*/
    169         sigDspInitialize(&(sig_subObj->sig_inner), resetMode);
    170         /*-----------------------------------------------------------------
    171          * Initialize modifiers
    172          * ------------------------------------------------------------------*/
    173         /*pitch , volume , speaker modifiers*/
    174         sig_subObj->pMod = 1.0f;
    175         sig_subObj->vMod = 1.0f;
    176         sig_subObj->sMod = 1.0f;
    177     } else {
    178         /*-----------------------------------------------------------------
    179          * Initialize memory for DSP
    180          * ------------------------------------------------------------------*/
    181         sigDspInitialize(&(sig_subObj->sig_inner), resetMode);
    182     }
    183 
    184 
    185     return PICO_OK;
    186 }/*sigInitialize*/
    187 
    188 /**
    189  * terminates the PU (processing unit)
    190  * @param    this : sig PU object
    191  * @return  PICO_OK : termination ok
    192  * @return  PICO_ERR_OTHER : termination failed
    193  * @callgraph
    194  * @callergraph
    195  */
    196 static pico_status_t sigTerminate(register picodata_ProcessingUnit this)
    197 {
    198 
    199     sig_subobj_t *sig_subObj;
    200     if (NULL == this || NULL == this->subObj) {
    201         return PICO_ERR_OTHER;
    202     }
    203     sig_subObj = (sig_subobj_t *) this->subObj;
    204 
    205     return PICO_OK;
    206 }/*sigTerminate*/
    207 
    208 /**
    209  * deallocates the PU (processing unit) sub object
    210  * @param    this : sig PU object
    211  * @param    mm : the engine memory manager
    212  * @return  PICO_OK : deallocation ok
    213  * @return  PICO_ERR_OTHER : deallocation failed
    214  * @callgraph
    215  * @callergraph
    216  */
    217 static pico_status_t sigSubObjDeallocate(register picodata_ProcessingUnit this,
    218         picoos_MemoryManager mm)
    219 {
    220     sig_subobj_t *sig_subObj;
    221     if ((NULL == this) || ((this)->subObj == NULL)) {
    222         return PICO_ERR_OTHER;
    223     }
    224     sig_subObj = (sig_subobj_t *) (this)->subObj;
    225 
    226     if (sig_subObj->sInSDFile != NULL) {
    227         picoos_sdfCloseIn(this->common, &(sig_subObj->sInSDFile));
    228         sig_subObj->sInSDFile = NULL;
    229         sig_subObj->sInSDFileName[0] = '\0';
    230     }
    231 
    232     if (sig_subObj->sOutSDFile != NULL) {
    233         picoos_sdfCloseOut(this->common, &(sig_subObj->sOutSDFile));
    234         sig_subObj->sOutSDFile = NULL;
    235         sig_subObj->sOutSDFileName[0] = '\0';
    236     }
    237 
    238     sigDeallocate(mm, &(sig_subObj->sig_inner));
    239 
    240     picoos_deallocate(this->common->mm, (void *) &this->subObj);
    241 
    242     return PICO_OK;
    243 }/*sigSubObjDeallocate*/
    244 
    245 /**
    246  * creates a new sig processing unit
    247  * @param    mm : the engine memory manager
    248  * @param    common : the engine common object
    249  * @param    cbIn : the PU input buffer
    250  * @param    cbOut : the PU output buffer
    251  * @param    voice : the voice descriptor object
    252  * @return  a valid PU handle if creation is OK
    253  * @return  NULL if creation is !=OK
    254  * @callgraph
    255  * @callergraph
    256  */
    257 picodata_ProcessingUnit picosig_newSigUnit(picoos_MemoryManager mm,
    258         picoos_Common common, picodata_CharBuffer cbIn,
    259         picodata_CharBuffer cbOut, picorsrc_Voice voice)
    260 {
    261     sig_subobj_t *sig_subObj;
    262 
    263     picodata_ProcessingUnit this = picodata_newProcessingUnit(mm, common, cbIn,
    264             cbOut, voice);
    265     if (NULL == this) {
    266         return NULL;
    267     }
    268     this->initialize = sigInitialize;
    269 
    270     PICODBG_DEBUG(("picosig_newSigUnit -- creating SIG PU"));
    271     /*Init function pointers*/
    272     this->step = sigStep;
    273     this->terminate = sigTerminate;
    274     this->subDeallocate = sigSubObjDeallocate;
    275     /*sub obj allocation*/
    276     this->subObj = picoos_allocate(mm, sizeof(sig_subobj_t));
    277 
    278     if (NULL == this->subObj) {
    279         PICODBG_ERROR(("Error in Sig Object allocation"));
    280         picoos_deallocate(mm, (void *) &this);
    281         return NULL;
    282     }
    283     sig_subObj = (sig_subobj_t *) this->subObj;
    284 
    285     /*-----------------------------------------------------------------
    286      * Allocate memory for DSP inner algorithms
    287      * ------------------------------------------------------------------*/
    288     if (sigAllocate(mm, &(sig_subObj->sig_inner)) != 0) {
    289         PICODBG_ERROR(("Error in Sig Sub Object Allocation"));
    290          picoos_deallocate(mm, (void *) &this);
    291         return NULL;
    292     }
    293 
    294     /*-----------------------------------------------------------------
    295      * Initialize memory for DSP (this may be re-used elsewhere, e.g.Reset)
    296      * ------------------------------------------------------------------*/
    297     if (PICO_OK != sigInitialize(this, PICO_RESET_FULL)) {
    298         PICODBG_ERROR(("Error in iSig Sub Object initialization"));
    299         sigDeallocate(mm, &(sig_subObj->sig_inner));
    300         picoos_deallocate(mm, (void *) &this);
    301         return NULL;
    302     }PICODBG_DEBUG(("SIG PU creation succeded!!"));
    303     return this;
    304 }/*picosig_newSigUnit*/
    305 
    306 /**
    307  * pdf access for phase
    308  * @param    this : sig object pointer
    309  * @param    phsIndex : index of phase vectot in the pdf
    310  * @param    phsVect : pointer to base of array where to store the phase values
    311  * @param    numComponents : pointer to the variable to store the number of components
    312  * @return   PICO_OK : pdf retrieved
    313  * @return   PICO_ERR_OTHER : pdf not retrieved
    314  * @callgraph
    315  * @callergraph
    316  */
    317 static pico_status_t getPhsFromPdf(register picodata_ProcessingUnit this,
    318         picoos_uint16 phsIndex, picoos_int32 *phsVect,
    319         picoos_int16 *numComponents)
    320 {
    321     sig_subobj_t *sig_subObj;
    322     picokpdf_PdfPHS pdf;
    323     static int nFrame = 0;
    324 
    325     picoos_uint32 nIndexValue;
    326     picoos_uint8 *nCurrIndexOffset, *nContent;
    327     picoos_uint16 nI;
    328 
    329     if (NULL == this || NULL == this->subObj) {
    330         return PICODATA_PU_ERROR;
    331     }
    332     sig_subObj = (sig_subobj_t *) this->subObj;
    333     pdf = sig_subObj->pdfphs;
    334     /*check incoming index*/
    335     if (phsIndex >= pdf->numvectors) {
    336         return PICODATA_PU_ERROR;
    337     }
    338     nCurrIndexOffset = ((picoos_uint8*) pdf->indexBase) + phsIndex * sizeof(picoos_uint32);
    339     nIndexValue = (0xFF000000 & ((*(nCurrIndexOffset+3)) << 24)) | (0x00FF0000 & ((*(nCurrIndexOffset+2)) << 16)) |
    340                   (0x0000FF00 & ((*(nCurrIndexOffset+1)) << 8))  | (0x000000FF & ((*nCurrIndexOffset)));
    341     nContent = pdf->contentBase;
    342     nContent += nIndexValue;
    343     *numComponents = (picoos_int16) *nContent++;
    344     if (*numComponents>PICODSP_PHASEORDER) {
    345         PICODBG_DEBUG(("WARNING : Frame %d -- Phase vector[%d] Components = %d --> too big\n",  nFrame, phsIndex, *numComponents));
    346         *numComponents = PICODSP_PHASEORDER;
    347     }
    348     for (nI=0; nI<*numComponents; nI++) {
    349         phsVect[nI] = (picoos_int32) *nContent++;
    350     }
    351     for (nI=*numComponents; nI<PICODSP_PHASEORDER; nI++) {
    352         phsVect[nI] = 0;
    353     }
    354     nFrame++;
    355     return PICO_OK;
    356 }/*getPhsFromPdf*/
    357 
    358 /**
    359  * processes one item with sig algo
    360  * @param    this : the PU object pointer
    361  * @param    inReadPos : read position in input buffer
    362  * @param    numinb : number of bytes in input buffer (including header)
    363  * @param    outWritePos : write position in output buffer
    364  * @param    numoutb : number of bytes produced in output buffer
    365  * @return  PICO_OK : processing successful and terminated
    366  * @return  PICO_STEP_BUSY : processing successful but still things to do
    367  * @return  PICO_ERR_OTHER : errors
    368  * @remarks processes a full input item
    369  * @remarks input data is one or more item, taken from local storage
    370  * @remarks output data is one or more item, written in local storage
    371  * @callgraph
    372  * @callergraph
    373  */
    374 static pico_status_t sigProcess(register picodata_ProcessingUnit this,
    375         picoos_uint16 inReadPos, picoos_uint16 numinb,
    376         picoos_uint16 outWritePos, picoos_uint16 *numoutb)
    377 {
    378 
    379     register sig_subobj_t * sig_subObj;
    380     picoos_int16 n_i;
    381     picoos_int16 n_frames, n_count;
    382     picoos_int16 *s_data, offset;
    383     picoos_int32 f_data, mlt, *t1, *tmp1, *tmp2;
    384     picoos_uint16 tmp_uint16;
    385     picopal_int16 tmp_int16;
    386     picoos_uint16 i, cnt;
    387     picoos_int16 hop_p_half;
    388 
    389     sig_subObj = (sig_subobj_t *) this->subObj;
    390 
    391     numinb = numinb; /* avoid warning "var not used in this function"*/
    392 
    393     /*defaults to 0 for output bytes*/
    394     *numoutb = 0;
    395 
    396     /*Input buffer contains an item FRAME_PAR*/
    397     switch (sig_subObj->innerProcState) {
    398 
    399         case 0:
    400             /*---------------------------------------------
    401              Shifting old values
    402              ---------------------------------------------*/
    403             for (n_count = 0; n_count < CEPST_BUFF_SIZE-1; n_count++) {
    404                 sig_subObj->sig_inner.F0Buff[n_count]=sig_subObj->sig_inner.F0Buff[n_count+1];
    405                 sig_subObj->sig_inner.PhIdBuff[n_count]=sig_subObj->sig_inner.PhIdBuff[n_count+1];
    406                 sig_subObj->sig_inner.VoicingBuff[n_count]=sig_subObj->sig_inner.VoicingBuff[n_count+1];
    407                 sig_subObj->sig_inner.FuVBuff[n_count]=sig_subObj->sig_inner.FuVBuff[n_count+1];
    408             }
    409             for (n_count = 0; n_count < PHASE_BUFF_SIZE-1; n_count++) {
    410                 sig_subObj->sig_inner.VoxBndBuff[n_count]=sig_subObj->sig_inner.VoxBndBuff[n_count+1];
    411             }
    412 
    413             tmp1 = sig_subObj->sig_inner.CepBuff[0];
    414             for (n_count = 0; n_count < CEPST_BUFF_SIZE-1; n_count++) {
    415                 sig_subObj->sig_inner.CepBuff[n_count]=sig_subObj->sig_inner.CepBuff[n_count+1];
    416             }
    417             sig_subObj->sig_inner.CepBuff[CEPST_BUFF_SIZE-1]=tmp1;
    418 
    419             tmp1 = sig_subObj->sig_inner.PhsBuff[0];
    420             for (n_count = 0; n_count < PHASE_BUFF_SIZE-1; n_count++) {
    421                 sig_subObj->sig_inner.PhsBuff[n_count]=sig_subObj->sig_inner.PhsBuff[n_count+1];
    422             }
    423             sig_subObj->sig_inner.PhsBuff[PHASE_BUFF_SIZE-1]=tmp1;
    424 
    425             /*---------------------------------------------
    426              Frame related initializations
    427              ---------------------------------------------*/
    428             sig_subObj->sig_inner.prevVoiced_p = sig_subObj->sig_inner.voiced_p;
    429             /*---------------------------------------------
    430              Get input data from PU buffer in internal buffers
    431              -------------------------------------------------*/
    432             /*load the phonetic id code*/
    433             picoos_mem_copy((void *) &sig_subObj->inBuf[inReadPos
    434                     + sizeof(picodata_itemhead_t)],                   /*src*/
    435             (void *) &tmp_uint16, sizeof(tmp_uint16));                /*dest+size*/
    436             sig_subObj->sig_inner.PhIdBuff[CEPST_BUFF_SIZE-1] = (picoos_int16) tmp_uint16; /*store into newest*/
    437             tmp_uint16 = (picoos_int16) sig_subObj->sig_inner.PhIdBuff[0];                 /*assign oldest*/
    438             sig_subObj->sig_inner.phId_p = (picoos_int16) tmp_uint16;                      /*assign oldest*/
    439 
    440             /*load pitch values*/
    441             for (i = 0; i < sig_subObj->pdflfz->ceporder; i++) {
    442                 picoos_mem_copy((void *) &(sig_subObj->inBuf[inReadPos
    443                         + sizeof(picodata_itemhead_t) + sizeof(tmp_uint16) + 3
    444                         * i * sizeof(tmp_uint16)]),                   /*src*/
    445                 (void *) &tmp_uint16, sizeof(tmp_uint16));            /*dest+size*/
    446 
    447                 sig_subObj->sig_inner.F0Buff[CEPST_BUFF_SIZE-1] = (picoos_int16) tmp_uint16;/*store into newest*/
    448                 tmp_uint16 = (picoos_int16) sig_subObj->sig_inner.F0Buff[0];                /*assign oldest*/
    449 
    450                 /*convert in float*/
    451                 sig_subObj->sig_inner.F0_p
    452                         = (tmp_uint16 ? ((picoos_single) tmp_uint16
    453                                 / sig_subObj->scmeanLFZ) : (picoos_single) 0.0);
    454 
    455                 if (sig_subObj->sig_inner.F0_p != (picoos_single) 0.0f) {
    456                     sig_subObj->sig_inner.F0_p = (picoos_single) exp(
    457                             (picoos_single) sig_subObj->sig_inner.F0_p);
    458 
    459                 }
    460                 /* voicing */
    461                 picoos_mem_copy((void *) &(sig_subObj->inBuf[inReadPos
    462                         + sizeof(picodata_itemhead_t) + sizeof(tmp_uint16) + 3
    463                         * i * sizeof(tmp_uint16) + sizeof(tmp_uint16)]),/*src*/
    464                 (void *) &tmp_uint16, sizeof(tmp_uint16));              /*dest+size*/
    465 
    466                 sig_subObj->sig_inner.VoicingBuff[CEPST_BUFF_SIZE-1] = (picoos_int16) tmp_uint16;/*store into newest*/
    467                 tmp_uint16 = (picoos_int16) sig_subObj->sig_inner.VoicingBuff[0];                /*assign oldest*/
    468 
    469                 sig_subObj->sig_inner.voicing = (picoos_single) ((tmp_uint16
    470                         & 0x01) * 8 + (tmp_uint16 & 0x0e) / 2)
    471                         / (picoos_single) 15.0f;
    472 
    473                 /* unrectified f0 */
    474                 picoos_mem_copy((void *) &(sig_subObj->inBuf[inReadPos
    475                         + sizeof(picodata_itemhead_t) + sizeof(tmp_uint16) + 3
    476                         * i * sizeof(tmp_uint16) + 2 * sizeof(tmp_uint16)]),/*src*/
    477                 (void *) &tmp_uint16, sizeof(tmp_uint16));                  /*dest+size*/
    478 
    479                 sig_subObj->sig_inner.FuVBuff[CEPST_BUFF_SIZE-1] = (picoos_int16) tmp_uint16;/*store into newest*/
    480                 tmp_uint16 = (picoos_int16) sig_subObj->sig_inner.FuVBuff[0];                /*assign oldest*/
    481 
    482                 sig_subObj->sig_inner.Fuv_p = (picoos_single) tmp_uint16
    483                         / sig_subObj->scmeanLFZ;
    484                 sig_subObj->sig_inner.Fuv_p = (picoos_single) EXP((double)sig_subObj->sig_inner.Fuv_p);
    485             }
    486             /*load cep values*/
    487             offset = inReadPos + sizeof(picodata_itemhead_t)
    488                     + sizeof(tmp_uint16) +
    489                     3 * sig_subObj->pdflfz->ceporder * sizeof(tmp_int16);
    490 
    491             tmp1 = sig_subObj->sig_inner.CepBuff[CEPST_BUFF_SIZE-1];   /*store into CURR */
    492             tmp2 = sig_subObj->sig_inner.CepBuff[0];                   /*assign oldest*/
    493 
    494             for (i = 0; i < sig_subObj->pdfmgc->ceporder; i++) {
    495                 picoos_mem_copy((void *) &(sig_subObj->inBuf[offset + i
    496                         * sizeof(tmp_int16)]),                /*src*/
    497                 (void *) &tmp_int16, sizeof(tmp_int16));    /*dest+size*/
    498 
    499                 tmp1 [i] = (picoos_int32) tmp_int16;
    500                 sig_subObj->sig_inner.wcep_pI[i] = (picoos_int32) tmp2[i];
    501             }
    502 
    503             if (sig_subObj->inBuf[inReadPos+ 3] > sig_subObj->inBuf[inReadPos+ 2]*2 + 8) {
    504                 /*load phase values*/
    505                 /*get the index*/
    506                 picoos_mem_copy((void *) &(sig_subObj->inBuf[offset + sig_subObj->pdfmgc->ceporder
    507                         * sizeof(tmp_int16)]),                /*src*/
    508                 (void *) &tmp_int16, sizeof(tmp_int16));    /*dest+size*/
    509 
    510                 /*store into buffers*/
    511                 tmp1 = sig_subObj->sig_inner.PhsBuff[PHASE_BUFF_SIZE-1];
    512                 /*retrieve values from pdf*/
    513                 getPhsFromPdf(this, tmp_int16, tmp1, &(sig_subObj->sig_inner.VoxBndBuff[PHASE_BUFF_SIZE-1]));
    514             } else {
    515                 /* no support for phase found */
    516                 sig_subObj->sig_inner.VoxBndBuff[PHASE_BUFF_SIZE-1] = 0;
    517             }
    518 
    519             /*pitch modifier*/
    520             sig_subObj->sig_inner.F0_p *= sig_subObj->pMod;
    521             sig_subObj->sig_inner.Fuv_p *= sig_subObj->pMod;
    522             if (sig_subObj->sig_inner.F0_p > 0.0f) {
    523                 sig_subObj->sig_inner.voiced_p = 1;
    524             } else {
    525                 sig_subObj->sig_inner.voiced_p = 0;
    526             }
    527             sig_subObj->sig_inner.n_available++;
    528             if (sig_subObj->sig_inner.n_available>3)  sig_subObj->sig_inner.n_available = 3;
    529 
    530             if (sig_subObj->sig_inner.n_available < 3) {
    531                 return PICO_STEP_BUSY;
    532             }
    533 
    534             sig_subObj->innerProcState = 3;
    535             return PICO_STEP_BUSY;
    536 
    537         case 3:
    538             /*Convert from mfcc to power spectrum*/
    539             save_transition_frame(&(sig_subObj->sig_inner));
    540             mel_2_lin_lookup(&(sig_subObj->sig_inner), sig_subObj->scmeanpowMGC);
    541             sig_subObj->innerProcState += 1;
    542             return PICO_STEP_BUSY;
    543 
    544         case 4:
    545             /*Reconstruct PHASE SPECTRUM */
    546             phase_spec2(&(sig_subObj->sig_inner));
    547             sig_subObj->innerProcState += 1;
    548             return PICO_STEP_BUSY;
    549 
    550         case 5:
    551             /*Prepare Envelope spectrum for inverse FFT*/
    552             env_spec(&(sig_subObj->sig_inner));
    553             sig_subObj->innerProcState += 1;
    554             return PICO_STEP_BUSY;
    555 
    556         case 6:
    557             /*Generate the impulse response of the vocal tract */
    558             impulse_response(&(sig_subObj->sig_inner));
    559             sig_subObj->innerProcState += 1;
    560             return PICO_STEP_BUSY;
    561 
    562         case 7:
    563             /*Sum up N impulse responses according to excitation  */
    564             td_psola2(&(sig_subObj->sig_inner));
    565             sig_subObj->innerProcState += 1;
    566             return PICO_STEP_BUSY;
    567 
    568         case 8:
    569             /*Ovladd */
    570             overlap_add(&(sig_subObj->sig_inner));
    571             sig_subObj->innerProcState += 1;
    572             return PICO_STEP_BUSY;
    573 
    574         case 9:
    575             /*-----------------------------------------
    576              Save the output FRAME item (0:hop-1)
    577              swap remaining buffer
    578              ---------------------------------------------*/
    579             n_frames = 2;
    580             *numoutb = 0;
    581             hop_p_half = (sig_subObj->sig_inner.hop_p) / 2;
    582             for (n_count = 0; n_count < n_frames; n_count++) {
    583                 sig_subObj->outBuf[outWritePos]
    584                         = (picoos_uint8) PICODATA_ITEM_FRAME;
    585                 sig_subObj->outBuf[outWritePos + 1]
    586                         = (picoos_uint8) (hop_p_half);
    587                 sig_subObj->outBuf[outWritePos + 2]
    588                         = (picoos_uint8) (sig_subObj->nNumFrame % ((hop_p_half)));
    589                 sig_subObj->outBuf[outWritePos + 3]
    590                         = (picoos_uint8) sig_subObj->sig_inner.hop_p;
    591                 s_data = (picoos_int16 *) &(sig_subObj->outBuf[outWritePos + 4]);
    592 
    593                 /*range control and clipping*/
    594                 mlt = (picoos_int32) ((sig_subObj->fSampNorm * sig_subObj->vMod)
    595                         * PICODSP_END_FLOAT_NORM);
    596                 t1 = &(sig_subObj->sig_inner.WavBuff_p[n_count * (hop_p_half)]);
    597                 for (n_i = 0; n_i < hop_p_half; n_i++) { /*Normalization*/
    598                     f_data = *t1++ * mlt;
    599                     if (f_data >= 0)
    600                         f_data >>= 14;
    601                     else
    602                         f_data = -(-f_data >> 14);
    603                     if (f_data > PICOSIG_MAXAMP)
    604                         f_data = PICOSIG_MAXAMP;
    605                     if (f_data < PICOSIG_MINAMP)
    606                         f_data = PICOSIG_MINAMP;
    607                     *s_data = (picoos_int16) (f_data);
    608                     s_data++;
    609                 }
    610                 sig_subObj->nNumFrame = sig_subObj->nNumFrame + 1;
    611                 *numoutb += ((picoos_int16) n_i * sizeof(picoos_int16)) + 4;
    612                 outWritePos += *numoutb;
    613             }/*end for n_count*/
    614             /*Swap remaining buffer*/
    615             cnt = sig_subObj->sig_inner.m2_p - sig_subObj->sig_inner.hop_p;
    616             tmp1 = sig_subObj->sig_inner.WavBuff_p;
    617             tmp2
    618                     = &(sig_subObj->sig_inner.WavBuff_p[sig_subObj->sig_inner.hop_p]);
    619             FAST_DEVICE(cnt,*(tmp1++)=*(tmp2++);)
    620             ;
    621             cnt = sig_subObj->sig_inner.m2_p - (sig_subObj->sig_inner.m2_p
    622                     - sig_subObj->sig_inner.hop_p);
    623             FAST_DEVICE(cnt,*(tmp1++)=0;)
    624             ;
    625             sig_subObj->innerProcState = 0; /*reset to step 0*/
    626             sig_subObj->nNumFrame += 2;
    627             return PICO_OK;
    628         default:
    629             return PICO_ERR_OTHER;
    630     }
    631     return PICO_ERR_OTHER;
    632 }/*sigProcess*/
    633 
    634 /**
    635  * selects items to be dealth with by this PU
    636  * @param    item : pointer to current item head
    637  * @return  TRUE : item should be managed
    638  * @return  FALSE : item should be passed on next PU
    639  * @remarks item pointed to by *item should be already valid
    640  * @callgraph
    641  * @callergraph
    642  */
    643 static pico_status_t sig_deal_with(const picoos_uint8 *item)
    644 {
    645     picodata_itemhead_t head;
    646     pico_status_t s_result;
    647     s_result = FALSE;
    648     head.type = item[0];
    649     head.info1 = item[1];
    650     head.info2 = item[2];
    651     head.len = item[3];
    652     switch (head.type) {
    653         case PICODATA_ITEM_FRAME_PAR:
    654             /*the only item that is managed by sig, so far, is "FRAME_PAR"*/
    655             s_result = TRUE;
    656             break;
    657         case PICODATA_ITEM_CMD:
    658             if ((head.info1 == PICODATA_ITEMINFO1_CMD_PLAY) || (head.info1
    659                     == PICODATA_ITEMINFO1_CMD_SAVE) || (head.info1
    660                     == PICODATA_ITEMINFO1_CMD_UNSAVE)) {
    661                 if (head.info2 == PICODATA_ITEMINFO2_CMD_TO_SIG) {
    662                     return TRUE;
    663                 }
    664             }
    665             if ((head.info1 == PICODATA_ITEMINFO1_CMD_PITCH) || (head.info1
    666                     == PICODATA_ITEMINFO1_CMD_VOLUME) || (head.info1
    667                     == PICODATA_ITEMINFO1_CMD_SPEAKER)) {
    668                 return TRUE;
    669             }
    670             break;
    671         default:
    672             break;
    673     }
    674     return s_result;
    675 } /*sig_deal_with*/
    676 
    677 /**
    678  * selects items to be managed as commands by this PU
    679  * @param    item : pointer to current item head
    680  * @return  TRUE : item should be managed as a command
    681  * @return  FALSE : item is not a PU command
    682  * @remarks item pointed to by *item should be already valid
    683  * @callgraph
    684  * @callergraph
    685  */
    686 static pico_status_t sig_is_command(const picoos_uint8 *item)
    687 {
    688     picodata_itemhead_t head;
    689     head.type = item[0];
    690     head.info1 = item[1];
    691     head.info2 = item[2];
    692     head.len = item[3];
    693     switch (head.type) {
    694         case PICODATA_ITEM_CMD:
    695             if ((head.info1 == PICODATA_ITEMINFO1_CMD_PLAY) || (head.info1
    696                     == PICODATA_ITEMINFO1_CMD_SAVE) || (head.info1
    697                     == PICODATA_ITEMINFO1_CMD_UNSAVE)) {
    698                 if (head.info2 == PICODATA_ITEMINFO2_CMD_TO_SIG) {
    699                     return TRUE;
    700                 }
    701             }
    702             if ((head.info1 == PICODATA_ITEMINFO1_CMD_PITCH) || (head.info1
    703                     == PICODATA_ITEMINFO1_CMD_VOLUME) || (head.info1
    704                     == PICODATA_ITEMINFO1_CMD_SPEAKER)) {
    705                 return TRUE;
    706             }
    707             break;
    708         default:
    709             break;
    710     }
    711     return FALSE;
    712 } /*sig_is_command*/
    713 
    714 /**
    715  * performs a step of the sig processing
    716  * @param    this : pointer to current PU (Control Unit)
    717  * @param    mode : mode for the PU
    718  * @param    numBytesOutput : pointer to number of bytes produced (output)
    719  * @param    this : pointer to current PU (Control Unit)
    720  * @return  one of the "picodata_step_result_t" values
    721  * @callgraph
    722  * @callergraph
    723  */
    724 static picodata_step_result_t sigStep(register picodata_ProcessingUnit this,
    725         picoos_int16 mode, picoos_uint16 * numBytesOutput)
    726 {
    727     register sig_subobj_t * sig_subObj;
    728     pico_status_t s_result;
    729     picoos_bool b_res;
    730     pico_status_t s_deal_with;
    731     picoos_uint16 blen;
    732     picoos_uint16 numinb, numoutb;
    733     pico_status_t rv;
    734     picoos_int16 *s_data;
    735     picoos_int16 hop_p_half;
    736     picoos_uint32 n_samp, n_i;
    737     picoos_char s_temp_file_name[255];
    738     picoos_uint32 n_start, n_fram, n_bytes;
    739     picoos_single f_value;
    740     picoos_uint16 n_value;
    741     picoos_uint32 n_pos;
    742     /*wav file play volume control*/
    743     picoos_int16 *s_t1;
    744     picoos_int32 sf_data, sf_mlt;
    745     picoos_uint32 sf;
    746     picoos_encoding_t enc;
    747     picoos_uint32 numSamples;
    748 
    749     numinb = 0;
    750     numoutb = 0;
    751     rv = PICO_OK;
    752     s_result = PICO_OK;
    753 
    754     if (NULL == this || NULL == this->subObj) {
    755         return PICODATA_PU_ERROR;
    756     }
    757     sig_subObj = (sig_subobj_t *) this->subObj;
    758 
    759     /*Init number of output bytes*/
    760     *numBytesOutput = 0;
    761 
    762     mode = mode; /* avoid warning "var not used in this function" */
    763 
    764     while (1) { /* exit via return */
    765 
    766         PICODBG_DEBUG(("picosig.sigStep -- doing state %i",sig_subObj->procState));
    767 
    768         switch (sig_subObj->procState) {
    769 
    770             case PICOSIG_COLLECT:
    771                 /* ************** item collector ***********************************/
    772                 /*collecting items from the PU input buffer*/
    773                 s_result = picodata_cbGetItem(this->cbIn,
    774                         &(sig_subObj->inBuf[sig_subObj->inWritePos]),
    775                         sig_subObj->inBufSize - sig_subObj->inWritePos, &blen);
    776 
    777                 PICODBG_DEBUG(("picosig.sigStep -- got item, status: %d",rv));
    778 
    779                 if (s_result == PICO_EOF) {
    780                     /*no items available : remain in state 0 and return idle*/
    781                     return PICODATA_PU_IDLE;
    782                 }
    783                 if ((PICO_OK == s_result) && (blen > 0)) {
    784                     /* we now have one item : CHECK IT */
    785                     s_result = picodata_is_valid_item(
    786                             &(sig_subObj->inBuf[sig_subObj->inWritePos]), blen);
    787                     if (s_result != TRUE) {
    788                         PICODBG_DEBUG(("picosig.sigStep -- item is not valid: discard"));
    789                         /*Item not valid : remain in state PICOSIG_COLLECT*/
    790                         return PICODATA_PU_BUSY;
    791                     }
    792                     /*item ok: it could be sent to schedule state*/
    793                     sig_subObj->inWritePos += blen;
    794                     sig_subObj->needMoreInput = FALSE;
    795                     sig_subObj->procState = PICOSIG_SCHEDULE;
    796                     /* uncomment next to split into two steps */
    797                     return PICODATA_PU_ATOMIC;
    798                 }
    799                 /*no EOF, no OK --> errors : remain in state PICOSIG_COLLECT and return error*/
    800                 return PICODATA_PU_ERROR;
    801                 break;
    802 
    803             case PICOSIG_SCHEDULE:
    804                 /* *************** item processing ***********************************/
    805                 numinb = PICODATA_ITEM_HEADSIZE
    806                         + sig_subObj->inBuf[sig_subObj->inReadPos + 3];
    807 
    808                 /*verify that current item has to be dealth with by this PU*/
    809                 s_deal_with = sig_deal_with(
    810                         &(sig_subObj->inBuf[sig_subObj->inReadPos]));
    811 
    812                 switch (s_deal_with) {
    813 
    814                     case TRUE:
    815                         /* we have to manage this item */
    816                         if (FALSE == sig_is_command(
    817                                 &(sig_subObj->inBuf[sig_subObj->inReadPos])))
    818                         {
    819                             /*no commands, item to deal with : switch to process state*/
    820                             sig_subObj->procState = PICOSIG_PROCESS;
    821                             sig_subObj->retState = PICOSIG_COLLECT;
    822                             return PICODATA_PU_BUSY; /*data still to process or to feed*/
    823 
    824                         } else {
    825 
    826                             /*we need to manage this item as a SIG command-item*/
    827 
    828                             switch (sig_subObj->inBuf[sig_subObj->inReadPos + 1]) {
    829 
    830                                 case PICODATA_ITEMINFO1_CMD_PLAY:
    831                                     /*CMD recognized : consume the command */
    832                                     sig_subObj->inReadPos += numinb;
    833                                     if (sig_subObj->inReadPos
    834                                             >= sig_subObj->inWritePos) {
    835                                         sig_subObj->inReadPos = 0;
    836                                         sig_subObj->inWritePos = 0;
    837                                     }
    838                                     /*default next state setting*/
    839                                     sig_subObj->procState =
    840                                        sig_subObj->retState = PICOSIG_COLLECT;
    841 
    842                                     /*--------- wav file play management --------------*/
    843                                     if (sig_subObj->sInSDFile != NULL) {
    844                                         /*input wav file is already open : return*/
    845                                         return PICODATA_PU_BUSY;
    846                                     }
    847                                     /*get temp file name*/
    848                                     picoos_strlcpy(
    849                                             (picoos_char*) s_temp_file_name,
    850                                             (picoos_char*) &(sig_subObj->inBuf[sig_subObj->inReadPos
    851                                                     + 4]),
    852                                             sig_subObj->inBuf[sig_subObj->inReadPos
    853                                                     + 3] + 1);
    854                                     /*avoid input/output file name clashes*/
    855                                     if (sig_subObj->sOutSDFile != NULL) {
    856                                         if (picoos_strncmp(
    857                                                 (picoos_char*) s_temp_file_name,
    858                                                 (picoos_char*) sig_subObj->sOutSDFileName,
    859                                                 picoos_strlen(
    860                                                         (picoos_char*) s_temp_file_name))
    861                                                 == 0) {
    862                                             PICODBG_WARN(("input and output files has the same name!\n"));
    863                                             return PICODATA_PU_BUSY;
    864                                         }
    865                                     }
    866                                     /*actual sampled data file open*/
    867                                     b_res = picoos_sdfOpenIn(this->common,
    868                                                 &(sig_subObj->sInSDFile),
    869                                         s_temp_file_name, &sf,
    870                                                 &enc, &numSamples);
    871                                     if (b_res != TRUE) {
    872                                         PICODBG_DEBUG(("Error on opening file %s\n", s_temp_file_name));
    873                                         sig_subObj->sInSDFile = NULL;
    874                                         sig_subObj->sInSDFileName[0] = '\0';
    875                                         return PICODATA_PU_BUSY;
    876                                     }
    877                                     /*input file handle is now valid : store filename*/
    878                                     picoos_strlcpy(
    879                                             (picoos_char*) sig_subObj->sInSDFileName,
    880                                             (picoos_char*) s_temp_file_name,
    881                                             sig_subObj->inBuf[sig_subObj->inReadPos
    882                                                     + 3] + 1);
    883                                     sig_subObj->sInSDFilePos = 0;
    884                                     /*switch to state PLAY and return*/
    885                                     sig_subObj->procState =
    886                                         sig_subObj->retState = PICOSIG_PLAY;
    887                                     return PICODATA_PU_BUSY;
    888                                     break;
    889 
    890                                 case PICODATA_ITEMINFO1_CMD_SAVE:
    891                                     /*CMD recognized : consume the command */
    892                                     sig_subObj->inReadPos += numinb;
    893                                     if (sig_subObj->inReadPos
    894                                             >= sig_subObj->inWritePos) {
    895                                         sig_subObj->inReadPos = 0;
    896                                         sig_subObj->inWritePos = 0;
    897                                     }
    898                                     /*prepare return state*/
    899                                     sig_subObj->procState = PICOSIG_COLLECT;
    900                                     sig_subObj->retState = PICOSIG_COLLECT;
    901                                     /*check about output file*/
    902                                     if ((sig_subObj->sOutSDFile != NULL)
    903                                             || (sig_subObj->outSwitch == 1)) {
    904                                         /*output sig file is already active : return*/
    905                                         return PICODATA_PU_BUSY;
    906                                     }
    907                                     /*get temp file name*/
    908                                     picoos_strlcpy(
    909                                             (picoos_char*) s_temp_file_name,
    910                                             (picoos_char*) &(sig_subObj->inBuf[sig_subObj->inReadPos
    911                                                     + 4]),
    912                                             sig_subObj->inBuf[sig_subObj->inReadPos
    913                                                     + 3] + 1);
    914                                     /*check extension*/
    915                                     if (picoos_has_extension(s_temp_file_name,
    916                                             PICODATA_PUTYPE_WAV_OUTPUT_EXTENSION)
    917                                             == FALSE){
    918                                         /*extension unsupported : return*/
    919                                         return PICODATA_PU_BUSY;
    920                                     }
    921                                     /*avoid input/output file name clashes*/
    922                                     if (sig_subObj->sInSDFile != NULL) {
    923                                         if (picoos_strncmp(
    924                                                 (picoos_char*) sig_subObj->sInSDFileName,
    925                                                 (picoos_char*) s_temp_file_name,
    926                                                 picoos_strlen(
    927                                                         (picoos_char*) sig_subObj->sInSDFileName))
    928                                                 == 0) {
    929                                             /*input and output files has the same name : do not allow opening for writing*/
    930                                             PICODBG_WARN(("input and output files has the same name!\n"));
    931                                             return PICODATA_PU_BUSY;
    932                                         }
    933                                     }
    934                                     /*try to open*/
    935                                     picoos_sdfOpenOut(this->common,
    936                                             &(sig_subObj->sOutSDFile),
    937                                             s_temp_file_name,
    938                                             SAMPLE_FREQ_16KHZ, PICOOS_ENC_LIN);
    939                                     if (sig_subObj->sOutSDFile == NULL) {
    940                                         PICODBG_DEBUG(("Error on opening file %s\n", sig_subObj->sOutSDFileName));
    941                                         sig_subObj->outSwitch = 0;
    942                                         sig_subObj->sOutSDFileName[0] = '\0';
    943                                     } else {
    944                                         /*open OK*/
    945                                         sig_subObj->outSwitch = 1;
    946                                         /*store output filename*/
    947                                         picoos_strlcpy(
    948                                                 (picoos_char*) sig_subObj->sOutSDFileName,
    949                                                 (picoos_char*) s_temp_file_name,
    950                                                 sig_subObj->inBuf[sig_subObj->inReadPos + 3] + 1);
    951                                     }
    952                                     return PICODATA_PU_BUSY;
    953                                     break;
    954 
    955                                 case PICODATA_ITEMINFO1_CMD_UNSAVE:
    956                                     /*CMD recognized : consume the command */
    957                                     sig_subObj->inReadPos += numinb;
    958                                     if (sig_subObj->inReadPos
    959                                             >= sig_subObj->inWritePos) {
    960                                         sig_subObj->inReadPos = 0;
    961                                         sig_subObj->inWritePos = 0;
    962                                     }
    963                                     /*prepare return state*/
    964                                     sig_subObj->procState = PICOSIG_COLLECT;
    965                                     sig_subObj->retState = PICOSIG_COLLECT;
    966                                     /*close the output file if any*/
    967                                     if ((sig_subObj->sOutSDFile == NULL)
    968                                             || (sig_subObj->outSwitch == 0)) {
    969                                         /*output sig file is not active : return*/
    970                                         PICODBG_DEBUG(("Error on requesting a binary samples file output closing : no file output handle exist\n"));
    971                                         return PICODATA_PU_BUSY;
    972                                     }
    973                                     picoos_sdfCloseOut(this->common,
    974                                             &(sig_subObj->sOutSDFile));
    975                                     sig_subObj->outSwitch = 0;
    976                                     sig_subObj->sOutSDFile = NULL;
    977                                     sig_subObj->sOutSDFileName[0] = '\0';
    978                                     return PICODATA_PU_BUSY;
    979                                     break;
    980 
    981                                 case PICODATA_ITEMINFO1_CMD_PITCH:
    982                                 case PICODATA_ITEMINFO1_CMD_VOLUME:
    983                                 case PICODATA_ITEMINFO1_CMD_SPEAKER:
    984                                     n_pos = 4;
    985                                     picoos_read_mem_pi_uint16(
    986                                             &(sig_subObj->inBuf[sig_subObj->inReadPos]),
    987                                             &n_pos, &n_value);
    988                                     b_res = FALSE;
    989                                     switch (sig_subObj->inBuf[sig_subObj->inReadPos + 2]) {
    990                                         case 'a' :
    991                                         /*absloute modifier*/
    992                                         f_value = (picoos_single) n_value
    993                                                 / (picoos_single) 100.0f;
    994                                             b_res = TRUE;
    995                                             break;
    996                                         case 'r' :
    997                                             /*relative modifier*/
    998                                             f_value = (picoos_single) n_value
    999                                                     / (picoos_single) 1000.0f;
   1000                                             b_res = TRUE;
   1001                                             break;
   1002                                         default :
   1003                                             f_value = (picoos_single)0; /*avoid warnings*/
   1004                                             break;
   1005                                     }
   1006                                     if (b_res) {
   1007                                         switch (sig_subObj->inBuf[sig_subObj->inReadPos + 1]) {
   1008                                             case PICODATA_ITEMINFO1_CMD_PITCH :
   1009                                             sig_subObj->pMod = f_value;
   1010                                                 break;
   1011                                             case PICODATA_ITEMINFO1_CMD_VOLUME :
   1012                                             sig_subObj->vMod = f_value;
   1013                                                 break;
   1014                                             case PICODATA_ITEMINFO1_CMD_SPEAKER :
   1015                                             sig_subObj->sMod = f_value;
   1016                                             sig_subObj->sig_inner.sMod_p
   1017                                                     = sig_subObj->sMod;
   1018                                             /*call the function needed to initialize the speaker factor*/
   1019                                             mel_2_lin_init(
   1020                                                     &(sig_subObj->sig_inner));
   1021                                                  break;
   1022                                             default :
   1023                                                 break;
   1024                                         }
   1025                                     }
   1026 
   1027                                     /*CMD recognized : consume the command */
   1028                                     sig_subObj->inReadPos += numinb;
   1029                                     if (sig_subObj->inReadPos
   1030                                             >= sig_subObj->inWritePos) {
   1031                                         sig_subObj->inReadPos = 0;
   1032                                         sig_subObj->inWritePos = 0;
   1033                                     }
   1034                                     /*prepare proc state*/
   1035                                     sig_subObj->procState = PICOSIG_COLLECT;
   1036                                     sig_subObj->retState = PICOSIG_COLLECT;
   1037                                     return PICODATA_PU_BUSY;
   1038                                     break;
   1039                                 default:
   1040                                     break;
   1041                             }/*switch command type*/
   1042                         } /*end if is command*/
   1043                         break;
   1044 
   1045                     case FALSE:
   1046 
   1047                         /*we DO NOT have to deal with this item on this PU.
   1048                          * Normally these are still alive boundary or flush items*/
   1049                         /*copy item from PU input to PU output buffer,
   1050                          * i.e. make it ready to FEED*/
   1051                         s_result = picodata_copy_item(
   1052                                 &(sig_subObj->inBuf[sig_subObj->inReadPos]),
   1053                                 numinb,
   1054                                 &(sig_subObj->outBuf[sig_subObj->outWritePos]),
   1055                                 sig_subObj->outBufSize - sig_subObj->outWritePos,
   1056                                 &numoutb);
   1057                         if (s_result != PICO_OK) {
   1058                             /*item not prepared properly to be sent to next PU :
   1059                              * do not change state and retry next time*/
   1060                             sig_subObj->procState = PICOSIG_SCHEDULE;
   1061                             sig_subObj->retState = PICOSIG_COLLECT;
   1062                             return PICODATA_PU_BUSY; /*data still to process or to feed*/
   1063                         }
   1064 
   1065                         /*if end of sentence reset number of frames(only needed for debugging purposes)*/
   1066                         if ((sig_subObj->inBuf[sig_subObj->inReadPos]
   1067                                 == PICODATA_ITEM_BOUND)
   1068                                 && ((sig_subObj->inBuf[sig_subObj->inReadPos + 1]
   1069                                         == PICODATA_ITEMINFO1_BOUND_SEND)
   1070                                         || (sig_subObj->inBuf[sig_subObj->inReadPos
   1071                                                 + 1]
   1072                                                 == PICODATA_ITEMINFO1_BOUND_TERM))) {
   1073                             PICODBG_INFO(("End of sentence - Processed frames : %d",
   1074                                             sig_subObj->nNumFrame));
   1075                             sig_subObj->nNumFrame = 0;
   1076                         }
   1077 
   1078                         /*item processed and put in oputput buffer : consume the item*/
   1079                             sig_subObj->inReadPos += numinb;
   1080                         sig_subObj->outWritePos += numoutb;
   1081                             if (sig_subObj->inReadPos >= sig_subObj->inWritePos) {
   1082                                 /* inBuf exhausted */
   1083                                 sig_subObj->inReadPos = 0;
   1084                                 sig_subObj->inWritePos = 0;
   1085                                 sig_subObj->needMoreInput = FALSE;
   1086                             }
   1087                             sig_subObj->procState = PICOSIG_FEED;
   1088                             sig_subObj->retState = PICOSIG_COLLECT;
   1089                         return PICODATA_PU_BUSY; /*data still to process or to feed*/
   1090                         break;
   1091 
   1092                     default:
   1093                         break;
   1094                 }/*end switch s_deal_with*/
   1095 
   1096                 break; /*end case sig_schedule*/
   1097 
   1098             case PICOSIG_PROCESS:
   1099                 /* *************** item processing ***********************************/
   1100                 numinb = PICODATA_ITEM_HEADSIZE
   1101                         + sig_subObj->inBuf[sig_subObj->inReadPos + 3];
   1102 
   1103                 /*Process a full item*/
   1104                 s_result = sigProcess(this, sig_subObj->inReadPos, numinb,
   1105                         sig_subObj->outWritePos, &numoutb);
   1106 
   1107                 if (s_result == PICO_OK) {
   1108                     sig_subObj->inReadPos += numinb;
   1109                     if (sig_subObj->inReadPos >= sig_subObj->inWritePos) {
   1110                         sig_subObj->inReadPos = 0;
   1111                         sig_subObj->inWritePos = 0;
   1112                         sig_subObj->needMoreInput = FALSE;
   1113                     }
   1114                     sig_subObj->outWritePos += numoutb;
   1115                     sig_subObj->procState = PICOSIG_FEED;
   1116                     sig_subObj->retState = PICOSIG_COLLECT;
   1117                     PICODBG_DEBUG(("picosig.sigStep -- leaving PICO_PROC, inReadPos = %i, outWritePos = %i",sig_subObj->inReadPos, sig_subObj->outWritePos));
   1118                     return PICODATA_PU_BUSY; /*data to feed*/
   1119                 }
   1120                 return PICODATA_PU_BUSY; /*data still to process : remain in PROCESS STATE*/
   1121                 break;
   1122 
   1123             case PICOSIG_PLAY:
   1124 
   1125                 /*management of wav file play*/
   1126                 s_data = (picoos_int16 *) &(sig_subObj->outBuf[sig_subObj->outWritePos + 4]);
   1127                 hop_p_half = sig_subObj->sig_inner.hop_p / 2;
   1128                 /*read directly into PU output buffer*/
   1129                 n_samp = hop_p_half;
   1130                 b_res = picoos_sdfGetSamples(sig_subObj->sInSDFile,
   1131                         sig_subObj->sInSDFilePos, &n_samp, s_data);
   1132                 sig_subObj->sInSDFilePos += n_samp;
   1133 
   1134                 if ((FALSE == b_res) || (0 == n_samp)) {
   1135                     /*file play is complete or file read error*/
   1136                     picoos_sdfCloseIn(this->common, &(sig_subObj->sInSDFile));
   1137                     sig_subObj->sInSDFile = NULL;
   1138                     sig_subObj->sInSDFileName[0] = '\0';
   1139                     sig_subObj->procState = PICOSIG_COLLECT;
   1140                     sig_subObj->retState = PICOSIG_COLLECT;
   1141                     return PICODATA_PU_BUSY; /*check if data in input buffer*/
   1142                 }
   1143                 /*-----------------------------------*/
   1144                 /*Volume control of wav file playback*/
   1145                 /*    (code borrowed from sigProcess)*/
   1146                 /*Volume mod and clipping control    */
   1147                 /*     directly into PU output buffer*/
   1148                 /*-----------------------------------*/
   1149                 sf_mlt = (picoos_int32) ((sig_subObj->vMod) * 16.0f);
   1150                 s_t1 = &(s_data[0]);
   1151 
   1152                 for (n_i = 0; n_i < n_samp; n_i++) {
   1153                     if (*s_t1 != 0) {
   1154                         sf_data = (picoos_int32) (*s_t1) * sf_mlt;
   1155                         sf_data >>= 4;
   1156                         if (sf_data > PICOSIG_MAXAMP) {
   1157                             sf_data = PICOSIG_MAXAMP;
   1158                         } else if (sf_data < PICOSIG_MINAMP) {
   1159                             sf_data = PICOSIG_MINAMP;
   1160                         }
   1161                         *s_t1 = (picoos_int16) (sf_data);
   1162                     }
   1163                     s_t1++;
   1164                 }
   1165                 /*Add header info*/
   1166                 sig_subObj->outBuf[sig_subObj->outWritePos]
   1167                         = (picoos_uint8) PICODATA_ITEM_FRAME;
   1168                 sig_subObj->outBuf[sig_subObj->outWritePos + 1]
   1169                         = (picoos_uint8) n_samp;
   1170                 sig_subObj->outBuf[sig_subObj->outWritePos + 2]
   1171                         = (picoos_uint8) (sig_subObj->nNumFrame % (hop_p_half)); /*number of frame % 64*/
   1172                 sig_subObj->outBuf[sig_subObj->outWritePos + 3]
   1173                         = (picoos_uint8) n_samp * 2;
   1174                 /*Item content*/
   1175                 sig_subObj->outWritePos += (n_samp * sizeof(picoos_int16)) + 4; /*including header*/
   1176                 sig_subObj->procState = PICOSIG_FEED;
   1177                 sig_subObj->retState = PICOSIG_PLAY;
   1178                 break;
   1179 
   1180             case PICOSIG_FEED:
   1181                 /* ************** item output/feeding ***********************************/
   1182                 switch (sig_subObj->outSwitch) {
   1183                     case 0:
   1184                         /*feeding items to PU output buffer*/
   1185                         s_result = picodata_cbPutItem(this->cbOut,
   1186                                 &(sig_subObj->outBuf[sig_subObj->outReadPos]),
   1187                                 sig_subObj->outWritePos - sig_subObj->outReadPos,
   1188                                 &numoutb);
   1189                         break;
   1190                     case 1:
   1191                         /*feeding items to file*/
   1192                         if (sig_subObj->outBuf[sig_subObj->outReadPos]
   1193                                 == PICODATA_ITEM_FRAME) {
   1194                             if ((sig_subObj->sOutSDFile) != NULL) {
   1195                                 n_start = (picoos_uint32) (sig_subObj->outReadPos)
   1196                                                 + PICODATA_ITEM_HEADSIZE;
   1197                                 n_bytes = (picoos_uint32) sig_subObj->outBuf[(sig_subObj->outReadPos)
   1198                                                 + PICODATA_ITEMIND_LEN];
   1199                                 n_fram = (picoos_uint32) sig_subObj->outBuf[(sig_subObj->outReadPos)
   1200                                                 + PICODATA_ITEMIND_INFO2];
   1201                                 if (picoos_sdfPutSamples(
   1202                                         sig_subObj->sOutSDFile,
   1203                                         n_bytes / 2,
   1204                                         (picoos_int16*) &(sig_subObj->outBuf[n_start]))) {
   1205                                     PICODBG_DEBUG(("Nframe:%d - Nbytes %d\n", n_fram, n_bytes));
   1206                                     numoutb = n_bytes + 4;
   1207                                     s_result = PICO_OK;
   1208                                     /* also feed item to next PU */
   1209                                     s_result = picodata_cbPutItem(
   1210                                                     this->cbOut,
   1211                                                     &(sig_subObj->outBuf[sig_subObj->outReadPos]),
   1212                                                     sig_subObj->outWritePos
   1213                                                             - sig_subObj->outReadPos,
   1214                                                     &numoutb);
   1215                                 } else {
   1216                                     /*write error : close file + cleanup handles*/
   1217                                     if (sig_subObj->sOutSDFile != NULL) {
   1218                                         picoos_sdfCloseOut(this->common, &(sig_subObj->sOutSDFile));
   1219                                         sig_subObj->sOutSDFile = NULL;
   1220                                     }
   1221                                     sig_subObj->sOutSDFileName[0] = '\0';
   1222                                     sig_subObj->outSwitch = 0;
   1223                                     PICODBG_DEBUG(("Error in writing :%d bytes to output file %s\n", numoutb, &(sig_subObj->sOutSDFileName[0])));
   1224                                     s_result = PICO_ERR_OTHER;
   1225                                 }
   1226                             }
   1227                         } else {
   1228                             /*continue to feed following PU with items != FRAME */
   1229                             s_result = picodata_cbPutItem(
   1230                                             this->cbOut,
   1231                                             &(sig_subObj->outBuf[sig_subObj->outReadPos]),
   1232                                 sig_subObj->outWritePos  - sig_subObj->outReadPos,
   1233                                             &numoutb);
   1234                         }
   1235                         break;
   1236                     default:
   1237                         s_result = PICO_ERR_OTHER;
   1238                         break;
   1239                 }
   1240                 PICODBG_DEBUG(("picosig.sigStep -- put item, status: %d",s_result));
   1241 
   1242                 if (PICO_OK == s_result) {
   1243 
   1244                     sig_subObj->outReadPos += numoutb;
   1245                     *numBytesOutput = numoutb;
   1246                     /*-------------------------*/
   1247                     /*reset the output pointers*/
   1248                     /*-------------------------*/
   1249                     if (sig_subObj->outReadPos >= sig_subObj->outWritePos) {
   1250                         sig_subObj->outReadPos = 0;
   1251                         sig_subObj->outWritePos = 0;
   1252                         sig_subObj->procState = sig_subObj->retState;
   1253                     }
   1254                     return PICODATA_PU_BUSY;
   1255 
   1256                 } else if (PICO_EXC_BUF_OVERFLOW == s_result) {
   1257 
   1258                     PICODBG_DEBUG(("picosig.sigStep ** feeding, overflow, PICODATA_PU_OUT_FULL"));
   1259                     return PICODATA_PU_OUT_FULL;
   1260 
   1261                 } else if ((PICO_EXC_BUF_UNDERFLOW == s_result)
   1262                         || (PICO_ERR_OTHER == s_result)) {
   1263 
   1264                     PICODBG_DEBUG(("picosig.sigStep ** feeding problem, discarding item"));
   1265                     sig_subObj->outReadPos = 0;
   1266                     sig_subObj->outWritePos = 0;
   1267                     sig_subObj->procState = sig_subObj->retState;
   1268                     return PICODATA_PU_ERROR;
   1269 
   1270                 }
   1271                 break;
   1272             default:
   1273                 /*NOT feeding items*/
   1274                 s_result = PICO_EXC_BUF_IGNORE;
   1275                 break;
   1276         }/*end switch*/
   1277         return PICODATA_PU_BUSY; /*check if there is more data to process after feeding*/
   1278 
   1279     }/*end while*/
   1280     return PICODATA_PU_IDLE;
   1281 }/*sigStep*/
   1282 
   1283 #ifdef __cplusplus
   1284 }
   1285 #endif
   1286 
   1287 /* Picosig.c end */
   1288