/** * Convert f0-contour with equal spaced sampling points to pitch markers. * * @param idSrc source f0-contour * @param idDst target pitch marker * @param n target sum of pitch marker lengths * @param srate sampling rate * @return O_K if sucessfull, not exec otherwise */ INT16 CGEN_PUBLIC CPMproc::F02pm(CData *idSrc, CData* idDst, INT32 n, INT32 srate) { INT16* p_pm = NULL; INT32 n_pm = 0; if(CData_IsEmpty(idSrc) == TRUE) return NOT_EXEC; if(n <= 0) return NOT_EXEC; DLPASSERT(CData_GetNComps(idSrc) == 1); CREATEVIRTUAL(CData,idSrc,idDst); CData_Reset(idDst, TRUE); dlm_f02pm((FLOAT64*)idSrc->XAddr(0,0), idSrc->GetNRecs(), &p_pm, &n_pm, n, srate); CData_AddComp(idDst, "pm", T_SHORT); CData_AddComp(idDst, "v/uv", T_SHORT); CData_Allocate(idDst, n_pm); ISETFIELD_RVALUE(idDst, "fsr", 1000.0/srate); dlp_memmove(idDst->XAddr(0,0), p_pm, 2*n_pm*sizeof(INT16)); /* clean up */ DESTROYVIRTUAL(idSrc,idDst) dlp_free(p_pm); return(O_K); }
INT16 CGEN_PUBLIC CFBAproc::AlignFramesToPitch(CData *idPitch, CData *idFea, CData* idNewFea) { CData* idAuxF = NULL; INT32 nSamplesP = 0; INT32 nFea = 0; INT32 nPer = 0; INT32 i = 0; INT32 j = 0; if(m_nSync) return O_K; if(idFea == NULL) return IERROR(this,ERR_NULLINST,0,0,0); if(idFea->IsEmpty()) return IERROR(idPitch,DATA_EMPTY,idPitch->m_lpInstanceName,0,0); if(idPitch == NULL) return IERROR(this,ERR_NULLINST,0,0,0); if(idPitch->IsEmpty()) return IERROR(idPitch,DATA_EMPTY,idPitch->m_lpInstanceName,0,0); if(idPitch->GetNComps()!=2 || !dlp_is_numeric_type_code(idPitch->GetCompType(0)) || !dlp_is_numeric_type_code(idPitch->GetCompType(1))) { return IERROR(this,FBA_BADARG,idPitch,"idPitch","contains invalid data."); } CREATEVIRTUAL(CData,idFea,idNewFea); ICREATEEX(CData,idAuxF ,"~idAuxF" ,NULL); if(idFea->m_lpTable->m_fsr <= 0.0) { idFea->m_lpTable->m_fsr = 1000.0 * (FLOAT64)m_nCrate / (FLOAT64)m_nSrate; } nFea = idFea->GetNRecs(); for(i = 0, j = 0, nSamplesP = 0; i < idPitch->GetNRecs(); i++, nSamplesP+=nPer) { nPer = (INT32)idPitch->Dfetch(i,0); while((idFea->m_lpTable->m_fsr * (FLOAT64)(j+0.5)) < (1000.0 * (FLOAT64)nSamplesP / (FLOAT64)m_nSrate)) j++; j = (j>=nFea) ? nFea-1 : j; idAuxF->SelectRecs(idFea,j,1); idNewFea->Cat(idAuxF); } IDESTROY(idAuxF); DESTROYVIRTUAL(idFea, idNewFea); return O_K; }
/* * Manual page at fst_man.def */ INT16 CGEN_PUBLIC CFst_Compose ( CFst* _this, CFst* itSrc1, CFst* itSrc2, INT32 nUnit1, INT32 nUnit2 ) { BOOL bNoeps; /* No implicit insertion of e.-loops */ BOOL bNoint; /* No intermediate symbols flag */ INT16 nCheck = 0; /* Verbose level */ INT16 nVirt = 0; /* Auxiliary: patching ovrl.args. bug*/ const char *err; /* Validate */ CHECK_THIS_RV(NOT_EXEC); CFst_Check(itSrc1); CFst_Check(itSrc2); if (itSrc1==NULL || itSrc2==NULL) { CFst_Reset(BASEINST(_this),TRUE); return O_K; } if (nUnit1<0 || nUnit1>=UD_XXU(itSrc1)) return IERROR(_this,FST_BADID,"unit",nUnit1,0); if (nUnit2<0 || nUnit2>=UD_XXU(itSrc2)) return IERROR(_this,FST_BADID,"unit",nUnit2,0); if (CFst_Wsr_GetType(itSrc1,NULL)!=CFst_Wsr_GetType(itSrc2,NULL)) return IERROR(_this,FST_INCOMPATIBLE,"weight semirings","itSrc1 and itSrc2",0); if (CData_FindComp(AS(CData,itSrc1->td),NC_TD_TIS)<0) return IERROR(_this,FST_MISS,"input symbol component" ,"","transition table of itSrc1"); if (CData_FindComp(AS(CData,itSrc1->td),NC_TD_TOS)<0) return IERROR(_this,FST_MISS,"output symbol component","","transition table of itSrc1"); if (CData_FindComp(AS(CData,itSrc2->td),NC_TD_TIS)<0) return IERROR(_this,FST_MISS,"input symbol component" ,"","transition table of itSrc2"); if (CData_FindComp(AS(CData,itSrc2->td),NC_TD_TOS)<0) return IERROR(_this,FST_MISS,"output symbol component","","transition table of itSrc2"); bNoeps = _this->m_bNoeps; bNoint = _this->m_bNoint; nCheck = BASEINST(_this)->m_nCheck; /* Initialize - NO RETURNS BEYOND THIS POINT */ /* HACK: Multiple overlapping arguments on _this not handled correctly by CREATEVIRTUAL --> */ if (_this==itSrc1 && _this==itSrc2) return IERROR(_this,ERR_GENERIC,"Invalid arguments",0,0); if (itSrc1==_this) { CREATEVIRTUAL(CFst,itSrc1,_this); nVirt=1; } else if (itSrc2==_this) { CREATEVIRTUAL(CFst,itSrc2,_this); nVirt=2; } /* <-- */ if((err=fstc_compose(itSrc1,nUnit1,itSrc2,nUnit2, bNoeps,bNoint,nCheck, _this))) return IERROR(_this,FST_INVALID,err,0,0); /* Copy input and output symbol tables */ CData_SelectComps(AS(CData,_this->is),AS(CData,itSrc1->is),IS_XXS(itSrc1)==UD_XXU(itSrc1)?nUnit1:0,1); CData_SelectComps(AS(CData,_this->os),AS(CData,itSrc2->os),OS_XXS(itSrc2)==UD_XXU(itSrc2)?nUnit2:0,1); /* Clean up */ if (nVirt==1) { DESTROYVIRTUAL(itSrc1,_this); } if (nVirt==2) { DESTROYVIRTUAL(itSrc2,_this); } CFst_Check(_this); CFst_TrimStates(_this,0); return O_K; }
/* * Manual page at fst_man.def */ INT16 CGEN_PUBLIC CFst_Product ( CFst* _this, CFst* itSrc1, CFst* itSrc2, INT32 nUnit1, INT32 nUnit2 ) { INT32 nC = 0; /* Current component */ INT32 nFCS2 = 0; /* 1st data comp. of state tab.itSrc2 */ INT32 nXCS1 = 0; /* No. of comps. of state tab. itSrc1 */ INT32 nXCS2 = 0; /* No. of comps. of state tab. itSrc2 */ INT32 nFCT2 = 0; /* 1st data comp. of trans.tab.itSrc2 */ INT32 nXCT1 = 0; /* No. of comps. of trans.tab. itSrc1 */ INT32 nXCT2 = 0; /* No. of comps. of trans.tab. itSrc2 */ INT32 nRls1 = 0; /* Rec. len. of state table of itSrc1 */ INT32 nRls2 = 0; /* Rec. len. of state table of itSrc2 */ INT32 nRlt1 = 0; /* Rec. len. of trans.table of itSrc1 */ INT32 nRlt2 = 0; /* Rec. len. of trans.table of itSrc2 */ FST_ITYPE nS1 = 0; FST_ITYPE nS2 = 0; FST_ITYPE nFS1 = 0; FST_ITYPE nFS2 = 0; FST_ITYPE nXS1 = 0; FST_ITYPE nXS2 = 0; FST_ITYPE nT = 0; FST_ITYPE nIni = 0; FST_ITYPE nTer = 0; FST_ITYPE nT1 = 0; FST_ITYPE nT2 = 0; FST_ITYPE nFT1 = 0; FST_ITYPE nFT2 = 0; FST_ITYPE nXT1 = 0; FST_ITYPE nXT2 = 0; char* lpsBuf = NULL; /* String buffer */ INT16 nVirt = 0; /* Auxiliary: patching ovrl.args. bug */ BOOL bNoloopsSave = FALSE; /* Save buffer for /noloops option */ /* Validate */ CHECK_THIS_RV(NOT_EXEC); if (itSrc1==NULL || itSrc2==NULL) { CFst_Reset(BASEINST(_this),TRUE); return O_K; } if (nUnit1<0 || nUnit1>=UD_XXU(itSrc1)) return IERROR(_this,FST_BADID,"unit",nUnit1,0); if (nUnit2<0 || nUnit2>=UD_XXU(itSrc2)) return IERROR(_this,FST_BADID,"unit",nUnit2,0); /* Initialize */ /* HACK: Multiple overlapping arguments on _this not handled correctly by CREATEVIRTUAL --> */ if (_this==itSrc1 && _this==itSrc2) return IERROR(_this,ERR_GENERIC,"Invalid arguments",0,0); if (itSrc1==_this) { CREATEVIRTUAL(CFst,itSrc1,_this); nVirt=1; } else if (itSrc2==_this) { CREATEVIRTUAL(CFst,itSrc2,_this); nVirt=2; } /* <-- */ bNoloopsSave = _this->m_bNoloops; CFst_Reset(BASEINST(_this),TRUE); _this->m_bNoloops = bNoloopsSave; /* Initialize destination state table */ nFS1 = UD_FS(itSrc1,nUnit1); nXS1 = UD_XS(itSrc1,nUnit1); nFS2 = UD_FS(itSrc2,nUnit2); nXS2 = UD_XS(itSrc2,nUnit2); nRls1 = CData_GetRecLen(AS(CData,itSrc1->sd)) - CData_GetCompOffset(AS(CData,itSrc1->sd),IC_SD_DATA); nRls2 = CData_GetRecLen(AS(CData,itSrc2->sd)) - CData_GetCompOffset(AS(CData,itSrc2->sd),IC_SD_DATA); nXCS1 = CData_GetNComps(AS(CData,itSrc1->sd)) - IC_SD_DATA; nXCS2 = CData_GetNComps(AS(CData,itSrc2->sd)) - IC_SD_DATA; nFCS2 = IC_SD_DATA + nXCS1; for (nC=IC_SD_DATA; nC<IC_SD_DATA+nXCS1; nC++) CData_AddComp ( AS(CData,_this->sd), CData_GetCname(AS(CData,itSrc1->sd),nC), CData_GetCompType(AS(CData,itSrc1->sd),nC) ); for (nC=IC_SD_DATA; nC<IC_SD_DATA+nXCS2; nC++) CData_AddComp ( AS(CData,_this->sd), CData_GetCname(AS(CData,itSrc2->sd),nC), CData_GetCompType(AS(CData,itSrc2->sd),nC) ); /* Initialize destination transition table */ nFT1 = UD_FT(itSrc1,nUnit1); nXT1 = UD_XT(itSrc1,nUnit1); nFT2 = UD_FT(itSrc2,nUnit2); nXT2 = UD_XT(itSrc2,nUnit2); nRlt1 = CData_GetRecLen(AS(CData,itSrc1->td)) - CData_GetCompOffset(AS(CData,itSrc1->td),IC_TD_DATA); nRlt2 = CData_GetRecLen(AS(CData,itSrc2->td)) - CData_GetCompOffset(AS(CData,itSrc2->td),IC_TD_DATA); nXCT1 = CData_GetNComps(AS(CData,itSrc1->td)) - IC_TD_DATA; nXCT2 = CData_GetNComps(AS(CData,itSrc2->td)) - IC_TD_DATA; nFCT2 = IC_TD_DATA + nXCT1; for (nC=IC_TD_DATA; nC<IC_TD_DATA+nXCT1; nC++) CData_AddComp ( AS(CData,_this->td), CData_GetCname(AS(CData,itSrc1->td),nC), CData_GetCompType(AS(CData,itSrc1->td),nC) ); for (nC=IC_TD_DATA; nC<IC_TD_DATA+nXCT2; nC++) CData_AddComp ( AS(CData,_this->td), CData_GetCname(AS(CData,itSrc2->td),nC), CData_GetCompType(AS(CData,itSrc2->td),nC) ); /* Copy input and output symbol tables */ CData_Copy(_this->is,itSrc1->is); CData_Copy(_this->os,itSrc2->os); /* Initialize destination unit */ lpsBuf = (char*)dlp_calloc ( CData_GetCompType(AS(CData,itSrc1->ud),IC_UD_NAME) + CData_GetCompType(AS(CData,itSrc2->ud),IC_UD_NAME) + 2, sizeof(char) ); sprintf ( lpsBuf,"%s.%s", (const char*)CData_XAddr(AS(CData,itSrc1->ud),nUnit1,IC_UD_NAME), (const char*)CData_XAddr(AS(CData,itSrc2->ud),nUnit2,IC_UD_NAME) ); CFst_Addunit(_this,lpsBuf); dlp_free(lpsBuf); /* Add product states */ CFst_Addstates(_this,0,nXS1*nXS2,FALSE); /* Copy state qualification (including final state flag) */ for (nS1=0; nS1<nXS1; nS1++) for (nS2=0; nS2<nXS2; nS2++) { if ((SD_FLG(itSrc1,nS1+nFS1)&0x01)==0x01 && (SD_FLG(itSrc2,nS2+nFS2)&0x01)==0x01) SD_FLG(_this,nS1*nXS2+nS2) |= 0x01; if (nRls1>0) dlp_memmove ( CData_XAddr(AS(CData,_this ->sd),nS1*nXS2+nS2,IC_SD_DATA), CData_XAddr(AS(CData,itSrc1->sd),nS1+nFS1 ,IC_SD_DATA), nRls1 ); if (nRls2>0) dlp_memmove ( CData_XAddr(AS(CData,_this ->sd),nS1*nXS2+nS2,nFCS2 ), CData_XAddr(AS(CData,itSrc2->sd),nS2+nFS2 ,IC_SD_DATA), nRls2 ); } CData_AddRecs(AS(CData,_this->td),nXT1*nXT2,_this->m_nGrany); /* Loop over all transitions of both factors */ for (nT=0, nT1=nFT1; nT1<nFT1+nXT1; nT1++) for (nT2=nFT2; nT2<nFT2+nXT2; nT2++, nT++) { /* Get product of initial and terminal state */ nIni = TD_INI(itSrc1,nT1)*nXS2 + TD_INI(itSrc2,nT2); nTer = TD_TER(itSrc1,nT1)*nXS2 + TD_TER(itSrc2,nT2); if (_this->m_bNoloops && nIni==nTer) continue; /* Add product transition */ *(FST_ITYPE*)CData_XAddr(AS(CData,_this->td),nT,IC_TD_INI) = nIni; *(FST_ITYPE*)CData_XAddr(AS(CData,_this->td),nT,IC_TD_TER) = nTer; /* Copy transition qualification */ dlp_memmove ( CData_XAddr(AS(CData,_this ->td),nT ,IC_TD_DATA), CData_XAddr(AS(CData,itSrc1->td),nT1,IC_TD_DATA), nRlt1 ); dlp_memmove ( CData_XAddr(AS(CData,_this ->td),nT ,nFCT2 ), CData_XAddr(AS(CData,itSrc2->td),nT2,IC_TD_DATA), nRlt2 ); } /* Finish destination instance */ CData_SelectRecs(AS(CData,_this->td),AS(CData,_this->td),0,nT); UD_XT(_this,0) = nT; /* TODO: Trim result !? */ /* Clean up */ if (nVirt==1) { DESTROYVIRTUAL(itSrc1,_this); } if (nVirt==2) { DESTROYVIRTUAL(itSrc2,_this); } return O_K; }
/** * Appends units from a source automaton instance to this instance. * * @param _this Pointer to destination automaton instance * @param itSrc Pointer to source automaton instance * @param nFirstUnit Index of first unit of <code>itSrc</code> to append to this instance * @param nCount Number of units to append * @return O_K if successfull, a (negative) error code otherwise */ INT16 CGEN_PUBLIC CFst_CatEx(CFst* _this, CFst* itSrc, INT32 nFirstUnit, INT32 nCount) { INT32 nU = 0; /* Current unit */ INT32 nXUd = 0; /* Number of units in destination */ INT32 nFSs = 0; /* First source state to append */ INT32 nXSs = 0; /* Number of source states to append */ INT32 nFTs = 0; /* First source transition to append */ INT32 nXTs = 0; /* Number of source transitions to append */ INT32 nXXSd = 0; /* Total number of states in destination */ INT32 nXXTd = 0; /* Total number of transitions in destination */ /* Validate */ CHECK_THIS_RV(NOT_EXEC); CFst_Check(_this); CFst_Check(itSrc); if (nFirstUnit < 0 ) nFirstUnit = 0; if (nFirstUnit+nCount > UD_XXU(itSrc)) nCount = UD_XXU(itSrc)-nFirstUnit; if (nCount <=0 ) return NOT_EXEC; /* Initialize */ CREATEVIRTUAL(CFst,itSrc,_this); /* If destination empty copy all properties from source */ if (UD_XXU(_this)==0) { CFst_Copy(BASEINST(_this),BASEINST(itSrc)); CData_SetNRecs(AS(CData,_this->ud),0); CData_SetNRecs(AS(CData,_this->sd),0); CData_SetNRecs(AS(CData,_this->td),0); CData_Reset(_this->is,0); CData_Reset(_this->os,0); } /* Get some metrics */ nXUd = UD_XXU(_this); nXXSd = UD_XXS(_this); nXXTd = UD_XXT(_this); nFSs = UD_FS(itSrc,nFirstUnit); nFTs = UD_FT(itSrc,nFirstUnit); for (nU=nFirstUnit,nXSs=0,nXTs=0; nU<nFirstUnit+nCount; nU++) { nXSs+=UD_XS(itSrc,nU); nXTs+=UD_XT(itSrc,nU); } /* Cat descriptor tables */ CDlpTable_CatEx(AS(CData,_this->ud)->m_lpTable,AS(CData,itSrc->ud)->m_lpTable,nFirstUnit,nCount); CDlpTable_CatEx(AS(CData,_this->sd)->m_lpTable,AS(CData,itSrc->sd)->m_lpTable,nFSs ,nXSs ); CDlpTable_CatEx(AS(CData,_this->td)->m_lpTable,AS(CData,itSrc->td)->m_lpTable,nFTs ,nXTs ); /* Adjust unit descriptions */ for (nU=nXUd; nU<nXUd+nCount; nU++) { UD_FS(_this,nU) += (nXXSd-nFSs); UD_FT(_this,nU) += (nXXTd-nFTs); } /* Copy input and output symbol table components */ if(!IS_XXS(_this) && IS_XXS(itSrc)) CData_Copy(_this->is,itSrc->is); if(!OS_XXS(_this) && OS_XXS(itSrc)) CData_Copy(_this->os,itSrc->os); /* Finalize */ DESTROYVIRTUAL(itSrc,_this); CFst_Check(_this); /* TODO: Remove after debugging */ return O_K; }
/* * Resample voiced parts of pitch to match a given mean fundamential frequency. * The length of voiced segments is preserved to avoid loss of synchronization * between pitch and corresponding signal * * @param idPitch Source data instance containing original pitch * @param idNewPitch Target data instance containing new pitch * @param nFFreq Target fundamential frequency (mean over voiced parts) */ INT16 CGEN_PUBLIC CFBAproc::ResamplePitch(CData *idPitch, CData *idNewPitch, INT32 nFFreq) { INT16 bVoiced = FALSE; INT32 i = 0; INT32 k = 0; INT32 nCount = 0; INT32 nStartL = 0; FLOAT32 nTargetPeriodLength = (FLOAT32)m_nSrate/(FLOAT32)nFFreq; FLOAT32 nMeanPeriodLengthL = 0.0; FLOAT32 nMeanPeriodLength = 0.0; CData* idVoiced = NULL; CData* idAux = NULL; // Validation if(idPitch == NULL) return IERROR(this,ERR_NULLINST,0,0,0); if(idPitch->IsEmpty()) return IERROR(idPitch,DATA_EMPTY,idPitch->m_lpInstanceName,0,0); if(nFFreq<50||nFFreq>500) return IERROR(this,FBA_BADARG,nFFreq,"nFFreq","a value between 50 and 500"); if ( idPitch->GetNComps()!=2 || !dlp_is_numeric_type_code(idPitch->GetCompType(0)) || !dlp_is_numeric_type_code(idPitch->GetCompType(1)) ) { return IERROR(this,FBA_BADARG,idPitch,"idPitch","contains invalid data."); } // Initialization CREATEVIRTUAL(CData,idPitch,idNewPitch); ICREATEEX(CData,idVoiced,"~idVoiced",NULL); ICREATEEX(CData,idAux ,"~idAux" ,NULL); idNewPitch->Reset(); idVoiced->AddComp("start",T_INT); idVoiced->AddComp("count",T_INT); idVoiced->AddComp("mplen",T_FLOAT); idVoiced->Alloc(10); // Determine start and length of voiced parts and mean of periods in samples for(i=0; i<idPitch->GetNRecs(); i++) { if(idPitch->Dfetch(i,1)>0) { if(bVoiced==FALSE) // Start of new voiced segment { bVoiced=TRUE; nStartL=i; nMeanPeriodLengthL=0; if(idVoiced->GetNRecs()==idVoiced->GetMaxRecs()) idVoiced->Realloc(idVoiced->GetNRecs()+10); idVoiced->IncNRecs(1); idVoiced->Dstore(i,idVoiced->GetNRecs()-1,0); } nMeanPeriodLength+=(INT32)idPitch->Dfetch(i,0); nMeanPeriodLengthL+=(INT32)idPitch->Dfetch(i,0); nCount++; } else if(bVoiced==TRUE) // End of voiced segment { bVoiced=FALSE; nMeanPeriodLengthL=nMeanPeriodLengthL/(FLOAT32)(i-nStartL); idVoiced->Dstore(i-nStartL,idVoiced->GetNRecs()-1,1); idVoiced->Dstore(nMeanPeriodLengthL,idVoiced->GetNRecs()-1,2); } } nMeanPeriodLength=nMeanPeriodLength/(FLOAT32)nCount; IFCHECK idVoiced->Print(); IFCHECK printf("\n Input mean period length in voiced parts: %f",nMeanPeriodLength); IFCHECK printf("\n Target mean period length: %f",nTargetPeriodLength); // Resample for(i=0,nStartL=0; i<idVoiced->GetNRecs(); i++) { INT32 j = 0; INT32 nSum = 0; INT32 nSumNew = 0; INT32 nDiff = 0; // Copy unvoiced idAux->SelectRecs(idPitch,nStartL,(INT32)idVoiced->Dfetch(i,0)-nStartL); idNewPitch->Cat(idAux); nStartL=(INT32)idVoiced->Dfetch(i,0)+(INT32)idVoiced->Dfetch(i,1); // Resample voiced idAux->SelectRecs(idPitch,(INT32)idVoiced->Dfetch(i,0),(INT32)idVoiced->Dfetch(i,1)); for(j=0,nSum=0;j<idAux->GetNRecs();j++) nSum+=(INT32)idAux->Dfetch(j,0); // Target sum idAux->Resample(idAux,nMeanPeriodLength/nTargetPeriodLength); idAux->Tconvert(idAux,T_FLOAT); idAux->Scalop(idAux,CMPLX(nTargetPeriodLength/nMeanPeriodLength),"mult"); idAux->Tconvert(idAux,T_INT); //DLPASSERT(FALSE); do { nSumNew=0; for(j=0,nSumNew=0;j<idAux->GetNRecs();j++) nSumNew+=(INT32)idAux->Dfetch(j,0); // New sum nDiff=nSumNew-nSum; // Distribute difference IFCHECK printf("\n Distribute difference d=%ld",(long)nDiff); for(j=0;j<idAux->GetNRecs()&&j<abs(nDiff);j++) { INT32 nValue = (INT32)idAux->Dfetch(j,0); if(nDiff<0) nValue+=1; else if(nDiff>0) nValue-=1; idAux->Dstore(nValue,j,0); } } while(nDiff!=0); //idAux->Fill_Int(1.0,0.0,1); for(k=0;k<idAux->GetNRecs();k++) idAux->Dstore(1.0,k,1); idNewPitch->Cat(idAux); } // Append last unvoiced segment nStartL = (INT32)idVoiced->Dfetch(idVoiced->GetNRecs()-1,0)+(INT32)idVoiced->Dfetch(idVoiced->GetNRecs()-1,1); idAux->SelectRecs(idPitch,nStartL,idPitch->GetNRecs()-nStartL); idNewPitch->Cat(idAux); DESTROYVIRTUAL(idPitch,idNewPitch); IDESTROY(idVoiced); IDESTROY(idAux); return O_K; }
INT16 CGEN_PUBLIC CFBAproc::AdjustSpeechRate(CData *idPitch, CData *idNewPitch, CData* idFea, CData* idNewFea, FLOAT32 rate) { INT16 bVoiced = FALSE; INT32 i = 0; INT32 k = 0; INT32 nCount = 0; INT32 nStartL = 0; FLOAT32 nMeanPeriodLengthL = 0.0; FLOAT32 nMeanPeriodLength = 0.0; CData* idVoiced = NULL; CData* idAuxP = NULL; CData* idAuxF = NULL; // Validation if(idPitch == NULL) return IERROR(this,ERR_NULLINST,0,0,0); if(idPitch->IsEmpty()) return IERROR(idPitch,DATA_EMPTY,idPitch->m_lpInstanceName,0,0); if ( idPitch->GetNComps()!=2 || !dlp_is_numeric_type_code(idPitch->GetCompType(0)) || !dlp_is_numeric_type_code(idPitch->GetCompType(1)) ) { return IERROR(this,FBA_BADARG,idPitch,"idPitch","contains invalid data."); } // Initialization CREATEVIRTUAL(CData,idPitch,idNewPitch); CREATEVIRTUAL(CData,idFea,idNewFea); ICREATEEX(CData,idVoiced,"~idVoiced",NULL); ICREATEEX(CData,idAuxP ,"~idAuxP" ,NULL); ICREATEEX(CData,idAuxF ,"~idAuxF" ,NULL); idNewPitch->Reset(); idVoiced->AddComp("start",T_INT); idVoiced->AddComp("count",T_INT); idVoiced->AddComp("mplen",T_FLOAT); idVoiced->Alloc(10); AlignFramesToPitch(idPitch, idFea, idFea); // Determine start and length of voiced parts and mean of periods in samples for(i=0; i<idPitch->GetNRecs(); i++) { if(idPitch->Dfetch(i,1)>0) { if(bVoiced==FALSE) // Start of new voiced segment { bVoiced=TRUE; nStartL=i; nMeanPeriodLengthL=0; if(idVoiced->GetNRecs()==idVoiced->GetMaxRecs()) idVoiced->Realloc(idVoiced->GetNRecs()+10); idVoiced->IncNRecs(1); idVoiced->Dstore(i,idVoiced->GetNRecs()-1,0); } nMeanPeriodLength+=(INT32)idPitch->Dfetch(i,0); nMeanPeriodLengthL+=(INT32)idPitch->Dfetch(i,0); nCount++; } else if(bVoiced==TRUE) // End of voiced segment { bVoiced=FALSE; nMeanPeriodLengthL=nMeanPeriodLengthL/(FLOAT32)(i-nStartL); idVoiced->Dstore(i-nStartL,idVoiced->GetNRecs()-1,1); idVoiced->Dstore(nMeanPeriodLengthL,idVoiced->GetNRecs()-1,2); } } nMeanPeriodLength=nMeanPeriodLength/(FLOAT32)nCount; IFCHECK idVoiced->Print(); IFCHECK printf("\n Input mean period length in voiced parts: %f",nMeanPeriodLength); // Resample for(i=0,nStartL=0; i<idVoiced->GetNRecs(); i++) { INT32 j = 0; INT32 nSum = 0; INT32 nRecOld = 0; INT32 nRecNew = 0; // Copy unvoiced idAuxP->SelectRecs(idPitch,nStartL,(INT32)idVoiced->Dfetch(i,0)-nStartL); idNewPitch->Cat(idAuxP); idAuxF->SelectRecs(idFea,nStartL,(INT32)idVoiced->Dfetch(i,0)-nStartL); idNewFea->Cat(idAuxF); nStartL=(INT32)idVoiced->Dfetch(i,0)+(INT32)idVoiced->Dfetch(i,1); // Resample voiced idAuxP->SelectRecs(idPitch,(INT32)idVoiced->Dfetch(i,0),(INT32)idVoiced->Dfetch(i,1)); nRecOld = idAuxP->GetNRecs(); for(j=0,nSum=0;j<nRecOld;j++) nSum+=(INT32)idAuxP->Dfetch(j,0); // Target sum idAuxP->Resample(idAuxP, rate); nRecNew = idAuxP->GetNRecs(); for(j=0;j<nRecNew;j++) { INT32 tmp = (INT32)idAuxP->Dfetch(j,0); tmp = (INT32)MAX(m_nSrate/500, tmp); tmp = (INT32)MIN(m_nSrate/50, tmp); idAuxP->Dstore(tmp,j,0); } //idAux->Fill_Int(1.0,0.0,1); for(k=0;k<nRecNew;k++) idAuxP->Dstore(1.0,k,1); for(k=0;k<nRecNew;k++) { j = (INT32)((FLOAT64)k * (FLOAT64)nRecOld / (FLOAT64)nRecNew + 0.5); idAuxF->SelectRecs(idFea,j+(INT32)idVoiced->Dfetch(i,0),1); idNewFea->Cat(idAuxF); } idNewPitch->Cat(idAuxP); } // Append last unvoiced segment nStartL = (INT32)idVoiced->Dfetch(idVoiced->GetNRecs()-1,0)+(INT32)idVoiced->Dfetch(idVoiced->GetNRecs()-1,1); idAuxP->SelectRecs(idPitch,nStartL,idPitch->GetNRecs()-nStartL); idNewPitch->Cat(idAuxP); idAuxF->SelectRecs(idFea,nStartL,idPitch->GetNRecs()-nStartL); idNewFea->Cat(idAuxF); DESTROYVIRTUAL(idPitch,idNewPitch); DESTROYVIRTUAL(idFea,idNewFea); IDESTROY(idVoiced); IDESTROY(idAuxP); IDESTROY(idAuxF); return O_K; }