⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp_maxima.c

📁 LastWave
💻 C
📖 第 1 页 / 共 3 页
字号:
  Free(maxCoeffs);  return(NULL);}static void ClearMaxCoeffs(MAXCOEFFS maxCoeffs){  if(maxCoeffs == NULL) Errorf("ClearMaxCoeffs : NULL input");  maxCoeffs->size = 0;  maxCoeffs->coeff2Min = 0.0;  maxCoeffs->coeff2Max = 0.0;  // Note that we do NOT de-allocate the array and do not initialize it}static void DoubleSizeMaxCoeffs(MAXCOEFFS maxCoeffs){  if(maxCoeffs == NULL)  Errorf("DoubleSizeMaxCoeffs : NULL input");    // Case of a first allocation  if(maxCoeffs->sizeAlloc == 0) {    maxCoeffs->coeff2s   = FloatAlloc(MAXCOEFFS_SIZEMIN);    maxCoeffs->sizeAlloc = MAXCOEFFS_SIZEMIN;  }   // Case of a resize  else {    /* Reallocation */    maxCoeffs->coeff2s = (LWFLOAT *)Realloc(maxCoeffs->coeff2s,2*maxCoeffs->sizeAlloc*sizeof(LWFLOAT));    /* Update the allocated size */    maxCoeffs->sizeAlloc *= 2;  }}static void AppendCoeff2(MAXCOEFFS maxCoeffs,LWFLOAT coeff2){  // Case when we need more space to store the coeff2s  if(maxCoeffs->size == maxCoeffs->sizeAlloc) DoubleSizeMaxCoeffs(maxCoeffs);    /* Appending */  maxCoeffs->coeff2s[maxCoeffs->size] = coeff2;  maxCoeffs->size++;    /* Updating the bounds : first appended coeff2 or ... */  if (maxCoeffs->size == 1 || coeff2 < maxCoeffs->coeff2Min)     maxCoeffs->coeff2Min = coeff2;  if (coeff2 > maxCoeffs->coeff2Max)     maxCoeffs->coeff2Max = coeff2;}/**********************************************************//*  *	FIND THE RIGHT THRESHOLD IN ORDER TO GET NMAXIMA *//**********************************************************//* Quick-Sort procedure */static int   CmpFloat(const void* pArg1, const void* pArg2){  LWFLOAT arg1,arg2;    arg1 = *(LWFLOAT *)pArg1;  arg2 = *(LWFLOAT *)pArg2;  if(arg1 > arg2)    return(-1);  if(arg1 < arg2)    return(1);  return(0);}// Returns the threshold such that "exactly" 'nMaximaTarget' coeff2s are above // or equal to it. If the total number of coeff2s is too small, the threshold is // simply the minimum value of the coeff2s.static LWFLOAT QSortFindThreshold(MAXCOEFFS maxCoeffs,unsigned long nMaximaTarget){  qsort(maxCoeffs->coeff2s,maxCoeffs->size,sizeof(LWFLOAT),&CmpFloat);  return(maxCoeffs->coeff2s[MIN(nMaximaTarget,maxCoeffs->size)-1]);}static unsigned long CountMaximaAboveThreshold(MAXCOEFFS maxCoeffs,LWFLOAT threshold){  unsigned long i;  unsigned long n = 0;  for(i = 0; i < maxCoeffs->size; i++) {    if(maxCoeffs->coeff2s[i] >= threshold)  n++;  }  return(n);}// Returns a threshold such that "approximately" 'nMaximaTarget' coeff2s are above // or equal to it. If the total number of coeff2s is too small, the threshold is // simply the minimum value of the coeff2s.// By "approximately" it is meant that //   nMaximaTarget/MAXCOEFF2_TOLERANCE <= nMaxima <= nMaximaTarget*MAXCOEFF2_TOLERANCE#define MAXCOEFF2_TOLERANCE 1.2static LWFLOAT DichotomyFindThreshold(MAXCOEFFS maxCoeffs,unsigned long nMaximaTarget){  // The target range of   unsigned long nMaximaTargetMin = (unsigned long) (nMaximaTarget/MAXCOEFF2_TOLERANCE);  unsigned long nMaximaTargetMax = (unsigned long) (nMaximaTarget*MAXCOEFF2_TOLERANCE);  // The minimum threshold and the corresponding number of maxima  LWFLOAT	thresholdMin	= 0.0;  unsigned long nMaximaMin	= maxCoeffs->size;  // The maximum threshold and the corresponding number of maxima  LWFLOAT	thresholdMax	= maxCoeffs->coeff2Max;  unsigned long nMaximaMax	= 0;  // The 'average' threshold and the corresponding number of maxima  LWFLOAT	thresholdAverage;  unsigned long nMaximaAverage;    // For debug display only : count the number of iterations in the dichotomy  unsigned long nSteps = 0;    // In case there are not enough maxima available  if(nMaximaMin < nMaximaTarget) return(thresholdMin); // TODO : replace nMaximaTarget with nMaximaTargetMax  // There are enough maxima available, we have to find the right threshold  // We loop until one of the extremities of the range [nMaximaMax,nMaximaMin]   // is in the range [nMaximaTargetMin,nMaximaTargetMax]  while((nMaximaMax<nMaximaTargetMin) && (nMaximaMin>nMaximaTargetMax)) {    // Count maxima above the 'average' threshold    // TODO : look at the shape of decay of maxima to change the 'AVERAGE'     // (example : threshold = sqrt(thresholdMin*thresholdMax) ???)    thresholdAverage = (thresholdMin+thresholdMax)/2;    nMaximaAverage   = CountMaximaAboveThreshold(maxCoeffs,thresholdAverage);    // Case 1 : the 'average' threshold is fine    if(INRANGE(nMaximaTargetMin,nMaximaAverage,nMaximaTargetMax))       return(thresholdAverage);     // Case 2 : the 'average' threshold is too large    if(nMaximaAverage < nMaximaTargetMin) {      thresholdMax = thresholdAverage;      nMaximaMax   = nMaximaAverage;    }    // Case 3 : the 'average' threshold is too small    if(nMaximaAverage > nMaximaTargetMax) {      thresholdMin = thresholdAverage;      nMaximaMin   = nMaximaAverage;    }  }  // This code should never be reached !  Errorf("Should return a value");  return(0.0);}/*  * Find the local maximas from a STFT that are above a threshold * If STFT is not up to date, an error is generated. * If book!=NULL, appends to it the molecules corresponding to the found maxima if . * If maxCoeffs!=NULL, appends to it the value of the local maximum. * and thresholds them to append them in a book. * The molecules are neither interpolated nor chirped. */static void AppendMaximaFromStftSubDict(SUBDICT subDict,char flagCausal,char flagTimeMaxima,char flagFreqMaxima,					LWFLOAT threshold,BOOK book,MAXCOEFFS maxCoeffs){  STFT   stft;  MOLECULE molecule;  // TODO : change to unsigned long when prototype of QuantizeRangeLarge is changed  int timeIdMin,timeIdMax;  unsigned long timeId;  LWFLOAT *prevCoeffs,*coeffs,*nextCoeffs;  LWFLOAT prevCoeff2,coeff2,nextCoeff2;  unsigned long freqId,f;  LWFLOAT belowCoeff2,aboveCoeff2;  // TODO : replace with simple explicit arguments to GetMaxStftSubDict ???  static LISTV searchRange = NULL;  static LISTV lvTime = NULL;  static LISTV lvFreq = NULL;  if(searchRange==NULL) {    searchRange = NewListv();    lvTime = NewListv();    lvFreq = NewListv();    AppendStr2Listv(lvTime,"timeId");AppendInt2Listv(lvTime,0);    AppendStr2Listv(lvFreq,"freqId");AppendInt2Listv(lvFreq,0);    AppendValue2Listv(searchRange,(VALUE)lvTime);    AppendValue2Listv(searchRange,(VALUE)lvFreq);  }  // Basic checking :  // TODO : place in calling generic function  if(subDict->flagUpToDate==NO)    Errorf("AppendMaximaFromStftSubDict : subDict is out of date");  stft = (STFT)(subDict->dataContainer);  // TODO : remove when there is a calling generic function  if(GetTypeValue(stft)!=stftType)    Errorf("AppendMaximaFromStftSubDict : subDict is not of type '%s' but '%s'",stftType,GetTypeValue(stft));  if(stft->type!=RealStft && stft->type!=HighResStft && stft->type!=HarmoStft)    Errorf("AppendMaximaFromStftSubDict : cannot treat a stft of type '%s'",StftType2Name(stft->type));  // Initializing the book if necessary  if(book != NULL) {    ClearBook(book);    CopyFieldsTFContent(stft,book);  }  // The time range search   // TODO : simplify ?  if(flagCausal) QuantizeRangeLarge(stft->firstp,stft->lastp,stft->tRate,&timeIdMin,&timeIdMax);  else           QuantizeRangeLarge(0,stft->signalSize,stft->tRate,&timeIdMin,&timeIdMax);  timeIdMin = MAX(timeIdMin,0);  timeIdMax = MIN(timeIdMax,stft->tRate*(stft->nFrames-1));  // Loop on time  for(timeId = timeIdMin; timeId <= timeIdMax;timeId += stft->tRate) {    // Get the stft 'vertical' data    prevCoeffs    = nextCoeffs    = NULL;    GetStftData(stft,timeId,&coeffs,NULL);    // When not at the border, get the previous and next 'vertical' slices of data    if(timeId != timeIdMin && timeId != timeIdMax) {      GetStftData(stft,timeId-stft->tRate,&prevCoeffs,NULL);      GetStftData(stft,timeId+stft->tRate,&nextCoeffs,NULL);    }    // Loop on frequency    for(freqId  = stft->freqIdMin; freqId <= stft->freqIdMax; freqId += stft->fRate) {      // Get the 'center' coeff2 at location (timeId,freqId)      // TODO : GetStftValue(timeId,freqId) ??      f  = (freqId-stft->freqIdMin)/stft->fRate;      coeff2 = coeffs[f];      // Case where we look for maxima over time and we are not at the (time) border      if(flagTimeMaxima && prevCoeffs != NULL && nextCoeffs != NULL) {	prevCoeff2 = prevCoeffs[f];	nextCoeff2 = nextCoeffs[f];	// Detection ! Should be a local maximum, and above the threshold	if (coeff2 >= threshold && prevCoeff2 <= coeff2 && coeff2 > nextCoeff2) {	  if(maxCoeffs) AppendCoeff2(maxCoeffs,coeff2);	  if(book) {	    SetListvNthFloat(lvTime,1,timeId);	    SetListvNthFloat(lvFreq,1,freqId);	    molecule = NewMolecule();	    GetMaxSubDict(subDict,searchRange,NULL,(VALUE)molecule);	    AddMolecule2Book(book,molecule);	  }	  // We don't want to add the molecule a second time if it is also a freq maximum!	  continue;	}      }      // Case where we look for maxima over frequency and we are not at the (freq) border      if (flagFreqMaxima && freqId != stft->freqIdMin && freqId != stft->freqIdMax) {	belowCoeff2 = coeffs[f-1];	aboveCoeff2 = coeffs[f+1];	// Detection ! Should be a local maximum, and above the threshold	if (coeff2 >= threshold && belowCoeff2 <= coeff2 && coeff2 > aboveCoeff2) {	  if(maxCoeffs) AppendCoeff2(maxCoeffs,coeff2);	  if(book) {	    SetListvNthFloat(lvTime,1,timeId);	    SetListvNthFloat(lvFreq,1,freqId);	    molecule = NewMolecule();	    GetMaxSubDict(subDict,searchRange,NULL,(VALUE)molecule);	    AddMolecule2Book(book,molecule);	  }	  // We don't want to add the molecule a second time if it is also a ?? maximum!	  continue;	}      }    }  }}// TODO : void AppendMaximaFromSubDict(SUBDICT subdict,char flagCausal,char flagMaxType,LWFLOAT threshold,BOOK book,MAXCOEFFS maxCoeffs)// with flagMaxType = DictMaxTime|DictMaxFreq|DictMaxScale| ....// Inits a maximaDict : clears all local maxima and finds new ones from // the sub-dictionaries, which should be up to date (else an error is generated).static void PrivateInitMaximaDict(MAXIMADICT maximaDict) {  unsigned short i;  BOOK book;  SUBDICT subDict;  static MAXCOEFFS maxCoeffs = NULL;  // Initialize maxCoeffs  if(maxCoeffs == NULL)  maxCoeffs = NewMaxCoeffs();  else                   ClearMaxCoeffs(maxCoeffs);  // First loop to get the values of the local maxima  for(i = 0; i < maximaDict->size; i++) {    subDict = maximaDict->subDicts[i];    // TODO : check if we want both time and freq maxima, and if flagCausal==YES    AppendMaximaFromStftSubDict(subDict,YES,YES,YES,0.0,NULL,maxCoeffs);  }  // Find the right threshold  //  maximaDict->threshold = QSortFindThreshold(maxCoeffs,maximaDict->nMaximaTarget);  maximaDict->threshold = DichotomyFindThreshold(maxCoeffs,maximaDict->nMaximaTarget);  // Second loop to add the maxima greater than the threshold to the book  maximaDict->nMaxima = 0;  for(i = 0; i < maximaDict->size; i++) {    subDict = maximaDict->subDicts[i];    book    = maximaDict->books[i];    // TODO : check if we want both time and freq maxima, and if flagCausal==YES    AppendMaximaFromStftSubDict(subDict,YES,YES,YES,maximaDict->threshold,book,NULL);    maximaDict->nMaxima += book->size;    // TODO : perform optimization of molecules here if we want to  }}/************************************************************************//* *    Implementation of the SUBDICT methods  *    for MAXIMADICT sub-dictionaries *  TODO : help/doc on these functions *//************************************************************************/char GetMaxMaximaDictSubDict(SUBDICT subDict,LISTV searchRange,LWFLOAT *pMaxValue,VALUE result) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -