pf_lib.c
来自「LastWave」· C语言 代码 · 共 1,800 行 · 第 1/4 页
C
1,800 行
/*..........................................................................*//* *//* PARTITION FUNCTION 3.2 *//* *//* Copyright (C) 1998-2005 Benjamin Audit. *//* email : Benjamin.Audit@ens-lyon.fr *//* *//*..........................................................................*//* *//* This program is a free software, you can redistribute it and/or *//* modify it under the terms of the GNU General Public License as *//* published by the Free Software Foundation; either version 2 of the *//* License, or (at your option) any later version *//* *//* This program is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *//* GNU General Public License for more details. *//* *//* You should have received a copy of the GNU General Public License *//* along with this program (in a file named COPYRIGHT); *//* if not, write to the Free Software Foundation, Inc., *//* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* *//*..........................................................................*/#include "pf_lib.h"#include <stdlib.h>#include <string.h>#include <math.h>#include <float.h>#include <assert.h>#ifndef NOT_USED_WITH_LWextern void *Malloc(size_t size);extern void *Calloc(int n, size_t size);extern void Free(void * ptr);#define malloc Malloc#define calloc Calloc#define free Free#endif /* NOT_USED_WITH_LW */typedef struct PartitionFunctionCell{ double q; int size; double *sTq; double *sTqLogT; double *logSTq; double *sTqLogT_sTq; double *log2STq; double *sTqLogT_sTq2; double *logSTqSTqLogT_sTq;} *PartitionFunctionCell;struct PartitionFunction{ /* + 1 for the terminating null byte */ char method[PFMETHODSIZE+1]; double aMin; int octaveNumber; int voiceNumber; int indexMax; int signalSize; int signalNumber; int dimension; int qNumber; PartitionFunctionCell *cellArray;};/************************************************* * * Stupid functions to compare double and used by qsort * *************************************************/static int PFCompDouble(const double *d1,const double *d2){ if(*d1<*d2) return -1; else if(*d1 == *d2) return 0; else return +1;}static int PFCellCompQ(const PartitionFunctionCell *pfc1,const PartitionFunctionCell *pfc2){ return PFCompDouble(&(*pfc1)->q,&(*pfc2)->q);}/************************************************* * * DesAllocation of PartitionFunction(Cell)(Array) * *************************************************/static void PFCellDelete(PartitionFunctionCell pfc){ if( pfc == NULL ) return; /* We only use one memory allocation for the 7 arrays */ free(pfc->sTq); free(pfc);}static void PFCellArrayDelete(PartitionFunctionCell *cellArray,int qNumber){ int nq; if( cellArray == NULL ) return; assert(qNumber > 0); for(nq = 0; nq < qNumber; nq++) PFCellDelete(cellArray[nq]); free(cellArray);}void PFDelete(PartitionFunction pf){ if( pf == NULL ) return; PFCellArrayDelete(pf->cellArray,pf->qNumber); free(pf);}/************************************************* * * Allocation of PartitionFunction(Cell)(Array) * *************************************************//* Returns an initialized cell (using q and size) in which the space for the double *s is allocated and initialised to 0 Returns NULL if it fails or if size <= 0 */static PartitionFunctionCell PFCellNew(double q,int size){ PartitionFunctionCell pfc; if( size <= 0 ) return NULL; pfc = (PartitionFunctionCell) malloc(sizeof(struct PartitionFunctionCell)); if( pfc == NULL ) return NULL; /* We use one memory allocation for the 7 arrays */ pfc->sTq = (double*) calloc(7*size,sizeof(double)); if( pfc->sTq == NULL ) { free(pfc); return NULL; } pfc->sTqLogT = pfc->sTq + size; pfc->logSTq = pfc->sTq + 2*size; pfc->sTqLogT_sTq = pfc->sTq + 3*size; pfc->log2STq = pfc->sTq + 4*size; pfc->sTqLogT_sTq2 = pfc->sTq + 5*size; pfc->logSTqSTqLogT_sTq = pfc->sTq + 6*size; pfc->q = q; pfc->size = size; return pfc;}/* Returns a pointer to a new PartitionFunctionCell, copy of pfc or NULL if it fails */static PartitionFunctionCell PFCellCopy(const PartitionFunctionCell pfc){ PartitionFunctionCell pfcNew; if(pfc == NULL) return NULL; pfcNew = PFCellNew(pfc->q,pfc->size); if(pfcNew == NULL) return NULL; /* This is correct because we use only one memory allocation for the 7 arrays */ memcpy(pfcNew->sTq,pfc->sTq,7*pfc->size*sizeof(double)); return pfcNew;}/* It returns a PartitionFunctionCell * pointing to qNumber initialized cells (using size and qArray) in which the space for the double *s is allocated and initialised to 0 */static PartitionFunctionCell *PFCellArrayNew(int size,int qNumber, double *qArray){ int nq; PartitionFunctionCell *cellArray; assert( size > 0 && qNumber > 0 ); cellArray = (PartitionFunctionCell *) malloc(qNumber*sizeof(PartitionFunctionCell)); if( cellArray == NULL ) return NULL; for(nq = 0; nq < qNumber; nq++) { cellArray[nq] = PFCellNew(qArray[nq],size); /* If we can't allocate one cell, we delete the one already allocated */ /* and we return NULL */ if( cellArray[nq] == NULL ) { for(nq--; nq >= 0; nq--) PFCellDelete(cellArray[nq]); free(cellArray); return NULL; } } return cellArray;}static PartitionFunctionCell *PFCellArrayConcat(int qNumber1,const PartitionFunctionCell *cellArray1,int qNumber2,const PartitionFunctionCell *cellArray2){ int nq; PartitionFunctionCell *cellArrayNew; cellArrayNew = (PartitionFunctionCell *) malloc((qNumber1+qNumber2)*sizeof(PartitionFunctionCell)); if(cellArrayNew == NULL) return NULL; for(nq=0;nq < qNumber1+qNumber2;nq++) { cellArrayNew[nq] = PFCellCopy( (nq < qNumber1) ? cellArray1[nq] : cellArray2[nq - qNumber1]); if(cellArrayNew[nq] == NULL) for(nq--;nq >= 0;nq--) { PFCellDelete(cellArrayNew[nq]); free(cellArrayNew); return NULL; } } /* Now we have to sort */ qsort((void *)cellArrayNew,qNumber1+qNumber2,sizeof(PartitionFunctionCell), (int (*) (const void *, const void *) ) &PFCellCompQ); return cellArrayNew;}/* Returns a pointer to a new PartitionFunctionCell *, copy of cellArray or NULL if it fails */static PartitionFunctionCell *PFCellArrayCopy(const PartitionFunctionCell *cellArray,int qNumber){ int nq; PartitionFunctionCell *cellArrayNew; if( (cellArray == NULL) || (qNumber <= 0) ) return NULL; cellArrayNew = (PartitionFunctionCell *) malloc(qNumber*sizeof(PartitionFunctionCell)); if( cellArray == NULL ) return NULL; for(nq=0;nq < qNumber;nq++) { cellArrayNew[nq] = PFCellCopy(cellArray[nq]); if(cellArrayNew[nq] == NULL) { for(nq--;nq >= 0;nq--) PFCellDelete(cellArrayNew[nq]); free(cellArrayNew); return NULL; } } return cellArrayNew;}/* Returns a new PartitionFunction initialized with non sense fields. Returns NULL if it fails. */PartitionFunction PFNew(void){ PartitionFunction pf; pf = (PartitionFunction) malloc(sizeof(struct PartitionFunction)); if( pf == NULL ) return NULL; pf->method[0] = '\0'; pf->aMin = -1.0; pf->octaveNumber = -1; pf->voiceNumber = -1; pf->indexMax = -2; pf->signalSize = -1; pf->signalNumber = -1; pf->dimension = -1; pf->qNumber = 0; pf->cellArray = NULL; return pf;}/* Returns a pointer to a new PartitionFunction, copy of pf or NULL if it fails */PartitionFunction PFCopy(const PartitionFunction pf){ PartitionFunction pfNew; PartitionFunctionCell *cellArray; if(pf == NULL) return NULL; if( PFIsValid(pf) != PFYes ) return NULL; if(pf->qNumber != 0) { cellArray = PFCellArrayCopy(pf->cellArray,pf->qNumber); if(cellArray == NULL) return NULL; } else cellArray = NULL; pfNew = PFNew(); if(pfNew == NULL) { PFCellArrayDelete(cellArray,pf->qNumber); return NULL; } strcpy(pfNew->method,pf->method); pfNew->aMin = pf->aMin; pfNew->octaveNumber = pf->octaveNumber; pfNew->voiceNumber = pf->voiceNumber; pfNew->indexMax = pf->indexMax; pfNew->signalSize = pf->signalSize; pfNew->signalNumber = pf->signalNumber; pfNew->dimension = pf->dimension; pfNew->qNumber = pf->qNumber; pfNew->cellArray = cellArray; return pfNew;}/* Set all the arrays to 0 */static void PFCReset(PartitionFunctionCell pfc){ int i; for(i=0;i<pfc->size;i++) { pfc->sTq[i] = 0.; pfc->sTqLogT[i] = 0.; pfc->logSTq[i] = 0.; pfc->sTqLogT_sTq[i] = 0.; pfc->log2STq[i] = 0.; pfc->sTqLogT_sTq2[i] = 0.; pfc->logSTqSTqLogT_sTq[i] = 0.; }}int PFReset(PartitionFunction pf){ int nq; if(pf == NULL) return PFNo; if( PFIsValid(pf) != PFYes ) return PFNo; for(nq=0;nq < pf->qNumber;nq++) PFCReset(pf->cellArray[nq]); pf->indexMax = -1; pf->signalNumber = 1; return PFYes;}/************************************************* * * functions to modify one field of a PartitionFunction * *************************************************/int PFSetMethod(PartitionFunction pf,const char *method){ if( pf == NULL ) return PFNo; if( method == NULL ) return PFNo; if( strlen(method) > PFMETHODSIZE) return PFNotValid; strcpy(pf->method,method); return PFYes;}int PFSetAMin(PartitionFunction pf,double aMin){ if( pf == NULL ) return PFNo; if( aMin <= 0 ) return PFNotValid; pf->aMin = aMin; return PFYes;}static int PFSetOctaveNumber(PartitionFunction pf,int octaveNumber){ if( pf == NULL ) return PFNo; if( octaveNumber <= 0) return PFNotValid; pf->octaveNumber = octaveNumber; return PFYes;}static int PFSetVoiceNumber(PartitionFunction pf,int voiceNumber){ if( pf == NULL ) return PFNo; if( voiceNumber <= 0) return PFNotValid; pf->voiceNumber = voiceNumber; return PFYes;} int PFSetSignalSize(PartitionFunction pf,int signalSize){ if( pf == NULL ) return PFNo; if( signalSize <= 0) return PFNotValid; pf->signalSize = signalSize; return PFYes;}int PFSetDimension(PartitionFunction pf,int dimension){ if( pf == NULL ) return PFNo; if( dimension <= 0) return PFNotValid; pf->dimension = dimension; return PFYes;}int PFSetQList(PartitionFunction pf,int qNumber,double *qArray)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?