pf_lib.c
来自「LastWave」· C语言 代码 · 共 1,800 行 · 第 1/4 页
C
1,800 行
{ int nq; PartitionFunctionCell *cellArray; if( pf == NULL ) return PFNo; if( (qNumber < 0) || (pf->octaveNumber <= 0) || (pf->voiceNumber <= 0) || ((qNumber == 0)&&(qArray != NULL)) ) return PFNotValid; if( qNumber == 0 ) { if(pf->cellArray != NULL) { PFCellArrayDelete(pf->cellArray,pf->qNumber); pf->cellArray = NULL; } pf->qNumber = 0; } else { /* We want the qs to be sorted in increasing order */ qsort((void *)qArray,qNumber,sizeof(double), (int (*) (const void *, const void *) ) PFCompDouble); /* each value can appear only once */ for(nq=0;nq < qNumber-1;nq++) if(qArray[nq] >= qArray[nq+1]) return PFNotValid; cellArray = PFCellArrayNew(pf->octaveNumber*pf->voiceNumber,qNumber, qArray); if( cellArray == NULL) return PFErrAlloc; if(pf->cellArray != NULL) PFCellArrayDelete(pf->cellArray,pf->qNumber); pf->cellArray = cellArray; pf->qNumber = qNumber; } pf->indexMax = -1; return PFYes;}/************************************************* * * functions to read one field of a PartitionFunction * *************************************************//* method must be able to contain at least PFMETHODSIZE+1 char */void PFGetMethod(const PartitionFunction pf,char *method){ strcpy(method,pf->method);}double PFGetAMin(const PartitionFunction pf){ return pf->aMin;}int PFGetOctaveNumber(const PartitionFunction pf){ return pf->octaveNumber;}int PFGetVoiceNumber(const PartitionFunction pf){ return pf->voiceNumber;}int PFGetIndexMax(const PartitionFunction pf){ return pf->indexMax;}int PFGetSignalSize(const PartitionFunction pf){ return pf->signalSize;}int PFGetSignalNumber(const PartitionFunction pf){ return pf->signalNumber;}int PFGetDimension(const PartitionFunction pf){ return pf->dimension;}int PFGetQNumber(const PartitionFunction pf){ return pf->qNumber;}/* One is supposed to have check qNumber before using thess functions so that enough space is available in qArray */void PFGetQList(const PartitionFunction pf,double *qArray){ int nq; for(nq=0;nq < pf->qNumber;nq++) qArray[nq] = pf->cellArray[nq]->q;}void PFGetQListFLOAT(const PartitionFunction pf,LWFLOAT *qArray){ int nq; for(nq=0;nq < pf->qNumber;nq++) qArray[nq] = (LWFLOAT) pf->cellArray[nq]->q;}/* One is supposed to have check qNumber before using thess functions so that indexQ is in [0,qNumber[ */double PFGetQ(const PartitionFunction pf,int indexQ){ if(indexQ < 0) return(-DBL_MAX); if(indexQ >= pf->qNumber) return(DBL_MAX); return( pf->cellArray[indexQ]->q);}LWFLOAT PFGetQFLOAT(const PartitionFunction pf,int indexQ){ if(indexQ < 0) return(-FLOAT_MAX); if(indexQ >= pf->qNumber) return(FLOAT_MAX); return( (LWFLOAT) pf->cellArray[indexQ]->q);}/************************************************* * * functions to access computed partition functions * *************************************************//* It returns the size of the sTq sTqLogT... arrays Very useful before calling PFAccesSig TQ | HQ | DQ. It returns 0 the list of q's is empty or -1 if pf is not valid */ int PFAccessSize(const PartitionFunction pf){ if(PFIsValid(pf) != PFYes) return -1; if(pf->qNumber == 0) return 0; return pf->octaveNumber*pf->voiceNumber;}/* return the index of a q in the qList of pf reurn -1 on failure */int PFAccessIndQ(const PartitionFunction pf,double q){ int nq; if( PFIsValid(pf) != PFYes ) return -1; if(pf->qNumber == 0) return -1; for(nq=0;nq < pf->qNumber;nq++) if(fabs(pf->cellArray[nq]->q - q) <= PFQDIFFMAX) return nq; return -1;}/* Sets the LWFLOAT array to Tau(q). Returns PFYes on success. Mode is either PFEXTENSIVE or PFINTENSIVE. tq must be able to contain the result (the size returned by PFAccessSize) */int PFAccessTQFLOAT(const PartitionFunction pf,int indexQ,int mode,LWFLOAT *tq){ int i; int size; PartitionFunctionCell pfc; if(pf == NULL) return PFNo; if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0) || (pf->qNumber <= indexQ) || (indexQ < 0) ) return PFNotValid; pfc = pf->cellArray[indexQ]; size = pfc->size; if( mode == PFEXTENSIVE ) { for(i=0;i < size;i++) { if(pfc->sTq[i] == 0) tq[i] = 0.0; else tq[i] = (LWFLOAT) log(pfc->sTq[i]); } } else if( mode == PFINTENSIVE ) { for(i=0;i <= pf->indexMax;i++) tq[i] = (LWFLOAT) ( pfc->logSTq[i]/(double) pf->signalNumber ); for(;i < size;i++) tq[i] = 0.0; } else return PFNotValid; return PFYes;}/* Sets the LWFLOAT array to var[Tau(q)]. Returns PFYes on success. vartq must be able to contain the result (the size returned by PFAccessSize) */int PFAccessVarTQFLOAT(const PartitionFunction pf,int indexQ,LWFLOAT *vartq){ int i; int size; double signalNumber; PartitionFunctionCell pfc; if(pf == NULL) return PFNo; if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0) || (pf->qNumber <= indexQ) || (indexQ < 0) || (pf->signalNumber < 2) ) return PFNotValid; pfc = pf->cellArray[indexQ]; size = pfc->size; signalNumber = (double) pf->signalNumber; for(i=0;i < size;i++) { for(i=0;i <= pf->indexMax;i++) vartq[i] = (LWFLOAT) ( (pfc->log2STq[i] - pfc->logSTq[i]*pfc->logSTq[i]/signalNumber)/(signalNumber - 1.0) ); for(;i < size;i++) vartq[i] = 0.0; } return PFYes;}/* Sets the LWFLOAT array to H(q). Returns PFYes on success. Mode is either PFEXTENSIVE or PFINTENSIVE. hq must be able to contain the result (the size returned by PFAccessSize) */int PFAccessHQFLOAT(const PartitionFunction pf,int indexQ,int mode,LWFLOAT *hq){ int i; int size; PartitionFunctionCell pfc; if(pf == NULL) return PFNo; if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0) || (pf->qNumber <= indexQ) || (indexQ < 0) ) return PFNotValid; pfc = pf->cellArray[indexQ]; size = pfc->size; if( mode == PFEXTENSIVE ) { for(i=0;i < size;i++) { if(pfc->sTq[i] == 0) hq[i] = 0.0; else hq[i] = (LWFLOAT) ( pfc->sTqLogT[i] / pfc->sTq[i]); } } else if( mode == PFINTENSIVE ) { for(i=0;i <= pf->indexMax;i++) hq[i] = (LWFLOAT) (pfc->sTqLogT_sTq[i] / (double) pf->signalNumber); for(;i < size;i++) hq[i] = 0.0; } else return PFNotValid; return PFYes;}/* Sets the LWFLOAT array to var[H(q)]. Returns PFYes on success. varhq must be able to contain the result (the size returned by PFAccessSize) */int PFAccessVarHQFLOAT(const PartitionFunction pf,int indexQ,LWFLOAT *varhq){ int i; int size; double signalNumber; PartitionFunctionCell pfc; if(pf == NULL) return PFNo; if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0) || (pf->qNumber <= indexQ) || (indexQ < 0) || (pf->signalNumber < 2) ) return PFNotValid; pfc = pf->cellArray[indexQ]; size = pfc->size; signalNumber = (double) pf->signalNumber; for(i=0;i < size;i++) { for(i=0;i <= pf->indexMax;i++) varhq[i] = (LWFLOAT) ( (pfc->sTqLogT_sTq2[i] - pfc->sTqLogT_sTq[i]*pfc->sTqLogT_sTq[i]/signalNumber)/(signalNumber - 1.0) ); for(;i < size;i++) varhq[i] = 0.0; } return PFYes;}/* Sets the LWFLOAT array to D(q). Returns PFYes on success. Mode is either PFEXTENSIVE or PFINTENSIVE. dq must be able to contain the result (the size returned by PFAccessSize) */int PFAccessDQFLOAT(const PartitionFunction pf,int indexQ,int mode,LWFLOAT *dq){ int i; int size; PartitionFunctionCell pfc; if(pf == NULL) return PFNo; if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0) || (pf->qNumber <= indexQ) || (indexQ < 0) ) return PFNotValid; pfc = pf->cellArray[indexQ]; size = pfc->size; if( mode == PFEXTENSIVE ) { for(i=0;i < size;i++) { if(pfc->sTq[i] == 0) dq[i] = 0.0; else dq[i] = (LWFLOAT) ( pfc->q*pfc->sTqLogT[i]/pfc->sTq[i] - log(pfc->sTq[i]) ); } } else if( mode == PFINTENSIVE ) { for(i=0;i <= pf->indexMax;i++) dq[i] = (LWFLOAT) ( (pfc->q*pfc->sTqLogT_sTq[i] - pfc->logSTq[i])/(double) pf->signalNumber ); for(;i < size;i++) dq[i] = 0.0; } else return PFNotValid; return PFYes;}/* Sets the LWFLOAT array to var[D(q)]. Returns PFYes on success. vardq must be able to contain the result (the size returned by PFAccessSize) */int PFAccessVarDQFLOAT(const PartitionFunction pf,int indexQ,LWFLOAT *vardq){ int i; int size; double signalNumber; double q; PartitionFunctionCell pfc; if(pf == NULL) return PFNo; if( (PFIsValid(pf) != PFYes) || (pf->qNumber == 0) || (pf->qNumber <= indexQ) || (indexQ < 0) || (pf->signalNumber < 2) ) return PFNotValid; pfc = pf->cellArray[indexQ]; size = pfc->size; signalNumber = (double) pf->signalNumber; q = pfc->q; for(i=0;i < size;i++) { for(i=0;i <= pf->indexMax;i++) vardq[i] = (LWFLOAT) ( (q*q*pfc->sTqLogT_sTq2[i] - 2*q*pfc->logSTqSTqLogT_sTq[i] + pfc->log2STq[i] - (q*pfc->sTqLogT_sTq[i] - pfc->logSTq[i])/signalNumber)/(signalNumber - 1.0) ); for(;i < size;i++) vardq[i] = 0.0; } return PFYes;}/************************************************* * * Initialisation of PartitionFunction * *************************************************//* It initialiszes pf for the computation of a new partition function. The arguments must be meaningful. Returns PFYes if it succeeds. */int PFInit(PartitionFunction pf,char *method,double aMin, int octaveNumber,int voiceNumber,int signalSize,int dimension, int qNumber,double *qArray){ /* Some verifications */ if( (pf == NULL) || (method == NULL) ) return PFNo; if(PFSetMethod(pf,method) != PFYes) return PFNotValid; if(PFSetAMin(pf,aMin ) != PFYes) return PFNotValid; if(PFSetOctaveNumber(pf,octaveNumber) != PFYes) return PFNotValid; if(PFSetVoiceNumber(pf,voiceNumber) != PFYes) return PFNotValid; pf->indexMax = -1; if(PFSetSignalSize(pf,signalSize) != PFYes) return PFNotValid; pf->signalNumber = 1; if(PFSetDimension(pf,dimension) != PFYes) return PFNotValid; if(PFSetQList(pf,qNumber,qArray) != PFYes) return PFNotValid; return PFYes;}/* Returns PFYes if pf is valid (meaningful content). But does not check the cellArray */static int _PFIsValid(PartitionFunction pf){ if(pf == NULL) return PFNo; if( (strlen(pf->method) > PFMETHODSIZE) || (pf->aMin <= 0) || (pf->octaveNumber <= 0) || (pf->voiceNumber <= 0 ) || (pf->indexMax < -1) || (pf->indexMax >= pf->voiceNumber*pf->octaveNumber) || (pf->signalSize <= 0) || (pf->signalNumber <= 0) || (pf->dimension <= 0) || (pf->qNumber < 0) ) return PFNotValid; return PFYes;}static int _PFCellArrayIsValid(PartitionFunctionCell *cellArray,int qNumber, int size){ int nq; if( cellArray == NULL ) return PFNotValid; for(nq=0;nq < qNumber;nq++) if(cellArray[nq]->size != size) return PFNotValid; /* The q have to be sorted in increasing order and each value can appear only once */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?