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

📄 atom_interpolate.c

📁 LastWave
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (coeff2C <= coeff2M || coeff2C <= coeff2P) {       //Warningf("TimeInterpolation : not a strict maximum %g %g %g!",coeff2M,coeff2C,coeff2P);      return(NO);    }     ParabolaInterpolateMax(coeff2M,coeff2C,coeff2P,rate,&dTimeId);     *pParamVal = atom->timeId + dTimeId;    return(YES);    /***************************************/    /* Interpolation on the freq parameter */    /***************************************/  case FreqParameter :    /* We get the value on three points to interpolate */    if(GetNeighborsData(atom,dict,channel,RealStft,FREQ_NEIGHBOR,&rate,&coeff2M,&coeff2C,&coeff2P,NULL,NULL,NULL)==NO) {      //Warningf("FreqInterpolation : no neighbor available");      return(NO);    }    if (coeff2C <= coeff2M || coeff2C <= coeff2P) {       //Warningf("FreqInterpolation : not a strict maximum %g %g %g!",coeff2M,coeff2C,coeff2P);      return(NO);    }    ParabolaInterpolateMax(coeff2M,coeff2C,coeff2P,rate,&dFreqId);    *pParamVal = atom->freqId + dFreqId;    return(YES);    /***************************** **********/    /* Interpolation on the chirp parameter */    /****************************** *********/  case ChirpParameter :    /* TODO : enable GetNeihborsData from already chirped atom */    if(GetNeighborsData(atom,dict,channel,ComplexStft,FREQ_NEIGHBOR,&rate,&realM,&realC,&realP,&imagM,&imagC,&imagP)==NO) {      //Warningf("ChirpInterpolation : no neighbor available");      return(NO);    }    /* Conversion to log-amplitude and phase */    Cartesian2LogPolar(realM,imagM,&logAmpM,&phaseM);    Cartesian2LogPolar(realC,imagC,&logAmpC,&phaseC);    Cartesian2LogPolar(realP,imagP,&logAmpP,&phaseP);    ParabolaInterpolate(logAmpM,logAmpC,logAmpP,rate,&aLogAmp,&b,&c,&dFreqId);    ParabolaInterpolate(phaseM,phaseC,phaseP,rate,&aPhi,&b,&c,&kPhi);    /* Perform estimation based on the interpolated parabolas */    if(EstimateChirp(atom,aLogAmp,aPhi,rate,&dChirpId,&windowSize)==NO) {      //Warningf("ChirpInterpolation : incompatible model");      return(NO);    }    freqId  = atom->freqId +dFreqId;    chirpId = atom->chirpId+dChirpId;    /* Check whether the estimated chirplet is aliased */    if(!INRANGE(0,freqId-chirpId*atom->windowSize/2,GABOR_NYQUIST_FREQID)        || !INRANGE(0,freqId+chirpId*atom->windowSize/2,GABOR_NYQUIST_FREQID)) {      //Warningf("ChirpInterpolation : the estimated chirplet would be aliased");      return(NO);    }    *pAuxParamVal = freqId;    *pParamVal    = chirpId;    return(YES);  default :    Errorf("EstimateAtomParameter (Weired) : bad parameter type %d",paramType);  }}/* Performs a series of global optimizations on a molecule, using a dictionary. */void OptimizeMolecule(MOLECULE molecule,DICT dict,LISTV optimizations){  unsigned short k;  unsigned char channel;  ATOM atom;  /* Optimizations options */  unsigned short i;  char *type=NULL;  VALUE value=NULL;  LWFLOAT f;  STRVALUE str=NULL;  LISTV  lv=NULL;  char* rangeName=NULL;  RANGE range=NULL;    // TODO : get rid of that ?  char borderType      = BorderPad0;  LWFLOAT coeffR,coeffI;    SIGNAL signal = NULL;    char flagTouched = NO;  unsigned int nAtoms,nAtomsAux;  LWFLOAT timeId,freqId,chirpId;  LWFLOAT meanTimeId,meanFreqId,meanFreq0Id,meanFreqKId,meanChirpId;    if(optimizations==NULL) return;    /* Now, perform the optimizations that are asked for */  i=0;  while(i<optimizations->length) {    type = GetListvNth(optimizations,i,&value,&f);    // All optimizations options so far are &strings    if(type!=strType)       Errorf("OptimizeMolecule : Weired");    str = CastValue(value,STRVALUE);    /*      * Interpolation of the time : jointly across partials and channels     */    if(!strcmp(str->str,"time")) {      /* First, estimate the average time over partials and channels */      meanTimeId = 0.0;      nAtoms = 0;      for(k = 0; k < molecule->dim; k++) {	channel = 0;	//    for(channel = 0; channel < molecule->nChannels; channel++) {	atom = GetMoleculeAtom(molecule,channel,k);	if(EstimateAtomParameter(atom,dict,channel,TimeParameter,&timeId,NULL)) {	  meanTimeId+=timeId;	  nAtoms++;	}       }      /* Then, set the new time of all these atoms */      if(nAtoms>0) {	meanTimeId /= nAtoms;	meanTimeId  = QuantizeParameter(meanTimeId,AtomTimeResolution);	for(k = 0; k < molecule->dim; k++) {	  channel = 0;	  //    for(channel = 0; channel < molecule->nChannels; channel++) {	  atom = GetMoleculeAtom(molecule,channel,k);	  atom->timeId = meanTimeId;	  flagTouched = YES;	}      }      i++;continue;    }    /*     * Interpolation of the frequency : jointly over channels     * for each partial     */    if(!strcmp(str->str,"freq")) {      /* The estimate is different for each partial */      for(k = 0; k < molecule->dim; k++) {	/* First, estimate over the channels for the current partial */	meanFreqId = 0.0;	nAtoms     = 0;	channel    = 0;	//    for(channel = 0; channel < molecule->nChannels; channel++) {	atom = GetMoleculeAtom(molecule,channel,k);	if(EstimateAtomParameter(atom,dict,channel,FreqParameter,&freqId,NULL)) {	  meanFreqId+=freqId;	  nAtoms++;	}  	/* Then. set the new frequency for all channels */	if(nAtoms>0) {	  meanFreqId /= nAtoms;	  meanFreqId  = QuantizeParameter(meanFreqId,AtomFreqResolution);	  channel = 0;	  //    for(channel = 0; channel < molecule->nChannels; channel++) {	  atom = GetMoleculeAtom(molecule,channel,k);	  atom->freqId = meanFreqId;	  flagTouched = YES;	}      }      i++;continue;    }	    /*     * Interpolation of the chirp : jointly across partials and channels     * the frequency is estimated jointly across channels for each partial     */    if(!strcmp(str->str,"chirp")) {      /* First, estimate the average chirp over partials and channels */      meanChirpId = 0.0;      nAtoms = 0;      for(k = 0; k < molecule->dim; k++) {	/* Estimate the average frequency over channels for the current partial */	meanFreqId = 0.0;	nAtomsAux = 0;	channel = 0;	//    for(channel = 0; channel < molecule->nChannels; channel++) {	atom = GetMoleculeAtom(molecule,channel,k);	if(EstimateAtomParameter(atom,dict,channel,ChirpParameter,&chirpId,&freqId)) {	  meanChirpId += chirpId;	  meanFreqId  += freqId;	  nAtoms++;	  nAtomsAux++;	} 		/* Then, set the new frequency of all channels of the current partial */	if(nAtomsAux>0) {	  meanFreqId /= nAtomsAux;	  meanFreqId  = QuantizeParameter(meanFreqId,AtomFreqResolution);	  channel = 0;	  //    for(channel = 0; channel < molecule->nChannels; channel++) {	  atom = GetMoleculeAtom(molecule,channel,k);	  atom->freqId = meanFreqId;	  flagTouched = YES;	}      }            /* Eventually, set the new chirp of all channels of all partials */      if(nAtoms>0) {	meanChirpId /= nAtoms;	meanChirpId  = QuantizeParameter(meanChirpId,AtomChirpResolution);	for(k = 0; k < molecule->dim; k++) {	  channel = 0;	  //    for(channel = 0; channel < molecule->nChannels; channel++) {	  atom = GetMoleculeAtom(molecule,channel,k);	  /* The first partial */	  if(k == 0) {	    meanFreq0Id   = atom->freqId;	    atom->chirpId = meanChirpId;	  } else {	    /* The other partials */	    if(meanFreq0Id==0.0) {	      Warningf("meanFreq0Id==%g",meanFreq0Id);	      atom->chirpId = meanChirpId*(k+1);	    } else {	      meanFreqKId = atom->freqId;	      atom->chirpId = meanChirpId*meanFreqKId/meanFreq0Id;	    }	  }	  flagTouched = YES;	}      }      i++;continue;    }         /*      * Recompute all the coefficients     */    if(!strcmp(str->str,"recompute")) {      flagTouched = YES;      i++;continue;    }    // DEBUG : shall we do that or just continue ?    Errorf("OptimizeMolecule : unknown optimization '%s'",str->str);    }  /* Actually recompute all coefficients */  molecule->coeff2 = 0.0;  for(k = 0; k < molecule->dim; k++) {    channel = 0;    //    for(channel = 0; channel < molecule->nChannels; channel++) {    atom = GetMoleculeAtom(molecule,channel,k);    signal = GetChannel(dict,channel);    SCAtomInnerProduct(signal,atom,borderType,&coeffR,&coeffI);    atom->coeffR = coeffR;    atom->coeffI = coeffI;    CastAtomReal(atom);    molecule->coeff2 += atom->coeff2;  } }// OLD STUFF/* We increase the octave as long as it increases the coeff2 */static void EstimateScale(ATOM atom,DICT dict,unsigned char channel){  SUBDICT subDict = NULL;  STFT    stft    = NULL;  SIGNAL  signal  = NULL;  // TODO : other border types  char borderType = BorderPad0;  ATOM copy = NULL;  int atomTimeIdMin,atomTimeIdMax;  /* Checking */  CheckAtom(atom);  signal = GetChannel(dict,channel);  /* First we recompute the inner product */  SCAtomInnerProduct(signal,atom,borderType,&(atom->coeffR),&(atom->coeffI));  CastAtomReal(atom);  copy = CopyAtom(atom,copy);  /*   * We try to increase the size of the atom as long as    * -it is possible   * -it increases its coeff2   */  while(1) {    /* Case where the window size is too big */    if(copy->windowSize > STFT_MAX_WINDOWSIZE) break;    ComputeWindowSupport(copy->windowSize,copy->windowShape,copy->timeId,&atomTimeIdMin,&atomTimeIdMax);    if(atomTimeIdMin < 0 || atomTimeIdMax >= dict->signalSize) break;    /* Case where the window size is not available */    if((subDict = GetStftSubDict(dict,channel,ComplexStft,copy->windowShape,copy->windowSize,NULL))==NULL) break;    stft  = (STFT)subDict->dataContainer;    // TODO : use flagCausal ?    if(!INRANGE(stft->firstp,copy->timeId,stft->lastp)) break;    /* Compute the coeff2 */    SCAtomInnerProduct(GetChannel(dict,channel),copy,borderType,&(copy->coeffR),&(copy->coeffI));    CastAtomReal(copy);    /* If increasing the windowSize 'increased' the coeff2, we shall try increasing again */    if(copy->coeff2 >= atom->coeff2) {      atom = CopyAtom(copy,atom);    }    copy->windowSize *= 2;  }}/* Performs a series of optimizations on an atom/a molecule, using a dictionary. */static void OptimizeAtom(ATOM atom,DICT dict,LISTV optimizations) {  /* Optimizations options */  unsigned short i;  char *type=NULL;  VALUE value=NULL;  LWFLOAT f;  STRVALUE str=NULL;  LISTV  lv=NULL;  char* rangeName=NULL;  RANGE range=NULL;  unsigned char channel;// TODO : pass as an argument of OptimizeAtom!  // TODO : get rid of that ?  char borderType      = BorderPad0;  LWFLOAT coeffR,coeffI;  SIGNAL signal = NULL;  static ATOM copy = NULL;  LWFLOAT timeId,freqId,chirpId;  if(dict->nChannels > 1) Errorf("OptimizeAtom : cannot deal with multichannel dictionaries");  if(optimizations==NULL) return;  /* Now, perform the optimizations that are asked for */  // NOTE THAT THIS WILL CHANGE A LOT IN THE NEAR FUTURE!  i=0;  while(i<optimizations->length) {    type = GetListvNth(optimizations,i,&value,&f);    // All optimizations options so far are &strings    if(type==strType) {      str = CastValue(value,STRVALUE);      /* Interpolation in Time and Frequency if asked */      if(!strcmp(str->str,"freqtime")) {	// MEANINGLESS!!!	channel = 0;	// TODO : when result is NO, take it into account ????	if(EstimateAtomParameter(atom,dict,channel,FreqParameter,&freqId,NULL)==NO) freqId = atom->freqId;	if(EstimateAtomParameter(atom,dict,channel,TimeParameter,&timeId,NULL)==NO) timeId = atom->timeId;	// TODO : move this to another task	timeId = QuantizeParameter(timeId,AtomTimeResolution);	freqId = QuantizeParameter(freqId,AtomFreqResolution);	/* Set the interpolated time and frequency */	signal = GetChannel(dict,channel);	copy = CopyAtom(atom,copy);	copy->freqId = freqId; 	copy->timeId = timeId;	/* 	 * This ensures compliance of copy with CheckAtom in SCAtomInnerProduct	 * if copy->freqId==0 or copy->freqId==GABOR_NYQUIST_FREQID	 */	copy->coeffI = 0.0; 	/* Recompute the inner-product */	// TODO : move from here ??	SCAtomInnerProduct(signal,copy,borderType,&(copy->coeffR),&(copy->coeffI));	CastAtomReal(copy);	if (copy->coeff2 > atom->coeff2) 	  atom = CopyAtom(copy,atom);	else {	  // DEBUG	  Warningf("Bad Interpolation");	  PrintAtom(atom,NO);	  PrintAtom(copy,NO);	  SCAtomInnerProduct(signal,atom,borderType,&(atom->coeffR),&(atom->coeffI));  	  CastAtomReal(atom);	}	i++;continue;      }       /* Interpolation in Frequency and Chirp (and scale) if asked */      if(!strcmp(str->str,"chirp")) {	// MEANINGLESS!!!	channel = 0;	// TODO : when result is NO, take it into account	// WARNING : this modifies atom->freqId too !	if(EstimateAtomParameter(atom,dict,channel,ChirpParameter,&chirpId,&freqId)==NO) {	  freqId  = atom->freqId;	  chirpId = atom->chirpId;	}	QuantizeParameter(freqId,AtomFreqResolution);	QuantizeParameter(chirpId,AtomChirpResolution);	atom->freqId  = freqId;	atom->chirpId = chirpId;	// TODO : separate chirp/scale	// DEBUG#ifdef DEBUG_SCALE	Printf("s : %d ",atom->windowSize);#endif	EstimateScale(atom,dict,channel);#ifdef DEBUG_SCALE	// DEBUG	Printf("-> %d\n",atom->windowSize);#endif	i++;continue;      }       /* Recompute the coefficient if asked */      // TODO : do that automatically exactly when needed without asking ?      if(!strcmp(str->str,"recompute")) {	// MEANINGLESS!!!	channel = 0;	signal = GetChannel(dict,channel);	SCAtomInnerProduct(signal,atom,borderType,&coeffR,&coeffI);	atom->coeffR = coeffR;	atom->coeffI = coeffI;      }     }    i++;continue;  }  CastAtomReal(atom);}void OldOptimizeMolecule(MOLECULE molecule,DICT dict,LISTV optimizations) {  unsigned short k;  unsigned char channel = 0;  ATOM atom;  if(optimizations==NULL) return;  // TODO : joint optimization over all harmonics (for chirp of harmonic atoms ...)  // TODO : joint optimization over channels  // Optimize and recompute the molecule->coeff2  molecule->coeff2 = 0.0;  for(k = 0; k < molecule->dim; k++) {    atom = GetMoleculeAtom(molecule,channel,k);    OptimizeAtom(atom,dict,optimizations);    molecule->coeff2 += atom->coeff2;  }}/* EOF */

⌨️ 快捷键说明

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