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

📄 atom.c

📁 LastWave
💻 C
📖 第 1 页 / 共 3 页
字号:
    // Init for += syntax    time = TimeId2Time(atom,atom->timeId);    if(SetFloatField(&time,arg,0)==NULL) return(NULL);    timeId = Time2TimeId(atom,time);  }   /* Some checkings */  if(!INRANGE(0,timeId,atom->signalSize-1)) {    if(flagId)      SetErrorf("Cannot set atom.timeId=%g because atom.signalSize-1=%d",timeId,atom->signalSize-1);    else       SetErrorf("Cannot set atom.time=%g (should be in [0,%g])",time,TimeId2Time(atom,atom->signalSize-1));    return(NULL);  }  atom->timeId = timeId;  return(numType);}  /* * The freq(Id) fields */static char *freqIdDoc = "{[= <freqId>]} {Sets/Gets the frequency center of an atom in sample coordinates, i.e. an index 0 <= freqId <= atom.freqIdNyquist.}";static char *freqDoc = "{[= <freq>]} {Sets/Gets the frequency center of an atom in real coordinates, i.e. the real frequency in Hertz.}";void *GetFreqAtomV(ATOM atom,void **arg){  char *field = ARG_G_GetField(arg);  /* Documentation */  if (atom == NULL) {    if(!strcmp(field,"freq")) return(freqDoc);    if(!strcmp(field,"freqId")) return(freqIdDoc);  }  if(!strcmp(field,"freq")) return(GetFloatField(FreqId2Freq(atom,atom->freqId),arg));  if(!strcmp(field,"freqId")) return(GetFloatField(atom->freqId,arg));}void *SetFreqAtomV(ATOM atom,void **arg){  char *field = ARG_G_GetField(arg);  char flagId = NO;  LWFLOAT freq,freqId;  /* Documentation */  if (atom == NULL) {    if(!strcmp(field,"freq")) return(freqDoc);    if(!strcmp(field,"freqId")) return(freqIdDoc);  }  if(!strcmp(field,"freqId"))    flagId = YES;  else if(!strcmp(field,"freq")) flagId = NO;  else Errorf("SetFreqAtomV : Weird field %s",field);  if(flagId) {    // Init for += syntax    freqId = atom->freqId;    if(SetFloatField(&freqId,arg,FieldPositive)==NULL) return(NULL);  }  else {    // Init for += syntax    freq   = FreqId2Freq(atom,atom->freqId);    if(SetFloatField(&freq,arg,FieldPositive)==NULL) return(NULL);    freqId = Freq2FreqId(atom,freq);  }  /* Some checkings */  if(freqId > GABOR_NYQUIST_FREQID) {    if(flagId)      SetErrorf("Cannot set atom.freqId=%g because atom.freqIdNyquist=%d",freqId,GABOR_NYQUIST_FREQID);    else      SetErrorf("Cannot set atom.freq=%g (should be in [0,%g]",freq,FreqNyquist(atom));    return(NULL);  }  if(atom->coeffI != 0.0 && (freqId == 0 || freqId == GABOR_NYQUIST_FREQID)) {    if(flagId)       SetErrorf("Cannot set atom.freqId=0 or %d (Nyquist) because atom.coeffI=%g (try setting atom.coeffI=0 first)",GABOR_NYQUIST_FREQID,atom->coeffI);    else       SetErrorf("Cannot set atom.freq=0 or %g (Nyquist) because atom.coeffI=%g (try setting atom.coeffI=0 first)",atom->coeffI,FreqNyquist(atom));    return(NULL);  }  // If the freqId changed we have to recompute the 'GG' of the atom  // to keep coherent  if(atom->freqId == freqId) return(numType);  atom->freqId = freqId;  SetAtomGG(atom);  // DEBUG TODO : remove!  if(atom->realGG*atom->realGG+atom->imagGG*atom->imagGG>1) {    PrintInfoValue(atom);    Errorf("SetFreqAtomV : (Weired) bad GG (%g %g)",atom->realGG,atom->imagGG);  }  return(numType);}  /* * The chirp(Id) fields */static char *chirpIdDoc = "{[= <chirpId>]} {Sets/Gets the chirp rate of an atom in sample coordinates, i.e. an index chirpId with |chirpId| <= atom.freqIdNyquist/2.}";static char *chirpDoc = "{[= <chirp>]} {Sets/Gets the chirp rate of an atom in real coordinates, i.e. the real frequency slope in Hertz per second.}";void *GetChirpAtomV(ATOM atom,void **arg){  char *field = ARG_G_GetField(arg);  /* Documentation */  if (atom == NULL) {    if(!strcmp(field,"chirp")) return(chirpDoc);    if(!strcmp(field,"chirpId")) return(chirpIdDoc);  }  if(!strcmp(field,"chirp"))      return(GetFloatField(ChirpId2Chirp(atom,atom->chirpId),arg));  if(!strcmp(field,"chirpId"))    return(GetFloatField(atom->chirpId,arg));}void *SetChirpAtomV(ATOM atom,void **arg){  char *field = ARG_G_GetField(arg);  char flagId = NO;  LWFLOAT chirp,chirpId;  /* Documentation */  if (atom == NULL){    if(!strcmp(field,"chirp")) return(chirpDoc);    if(!strcmp(field,"chirpId")) return(chirpIdDoc);  }  if(!strcmp(field,"chirpId"))    flagId = YES;  else if(!strcmp(field,"chirp")) flagId = NO;  else Errorf("SetChirpAtomV : Weird field %s",field);  if(flagId) {    // Init for += syntax    chirpId = atom->chirpId;    if(SetFloatField(&chirpId,arg,0)==NULL) return(NULL);  }  else {    // Init for += syntax    chirp = ChirpId2Chirp(atom,atom->chirpId);    if(SetFloatField(&chirp,arg,0)==NULL) return(NULL);    chirpId = Chirp2ChirpId(atom,chirp);  }   /* Some checkings */  if(!INRANGE(-GABOR_MAX_CHIRPID,chirpId,GABOR_MAX_CHIRPID)) {    if(flagId)      SetErrorf("Cannot set atom.chirpId=%g (its absolute value should be at most %g)",chirpId,GABOR_MAX_CHIRPID);    else      SetErrorf("Cannot set atom.chirp=%g (its absolute value should be at most %g)",chirp,ChirpId2Chirp(atom,GABOR_MAX_CHIRPID));    return(NULL);  }  // If the chirpId changed we have to recompute the 'GG' of the atom  // to keep coherent  if(atom->chirpId == chirpId) return(numType);  atom->chirpId = chirpId;  SetAtomGG(atom);  // DEBUG TODO : remove!  if(atom->realGG*atom->realGG+atom->imagGG*atom->imagGG>1) {    PrintInfoValue(atom);    Errorf("SetChirpAtomV : (Weired) bad GG (%g %g)",atom->realGG,atom->imagGG);  }  return(numType);}  #ifdef ATOM_ADVANCED/* * The inner-product <g,_g> between a (normalized) complex atom * and its complex conjugate. */static char *ggDoc = "{} {Gets a listv {real imag} that corresponds to the (complex) inner-product <g,_g> between a (normalized) complex atom 'g' and its complex conjugate '_g'. The value of <g,_g> depends on the windowShape, windowSize, frequency and chirp parameters. It is used to compute the energy ||P_{g,_g}s||^2 of the projection of a (real valued) signal 's' on the subspace spanned by 'g' and '_g' from the complex inner product <s,g>. WARNING : this is a read-only field. If you type 'atom.gg[0]=1' it will be accepted but what will be performed is similar to 'l=atom.gg; l[0]=1'.}";void *GetGGAtomV(ATOM atom, void **arg){  LISTV lv;  /* Documentation */  if (atom == NULL) return(ggDoc);  lv = TNewListv();  AppendFloat2Listv(lv,atom->realGG);  AppendFloat2Listv(lv,atom->imagGG);  return(GetValueField(lv,arg));}#endif //ATOM_ADVANCED/* * The coeff fields : coeff2,phase  */static char *coeff2Doc = "{[= <coeff2>]} {Sets/Gets the atom squared coefficient.}";static char *phaseDoc = "{[= <phase>]} {Sets/Gets the atom phase (which is defined modulo 1).}";static char *coeffDoc = "{} {Gets the atom complex coefficient.}";static LWFLOAT _ComputePhase(LWFLOAT cosPhase,LWFLOAT sinPhase){  LWFLOAT phase;  phase = atan2(sinPhase,cosPhase)/(2*M_PI);  if (phase<0)     phase = 1+phase;  if(phase >= 1.0) phase = phase-1.0;  return(phase);}void *GetCoeffAtomV(ATOM atom, void **arg){  char *field = ARG_G_GetField(arg);  LWFLOAT phase;  LISTV lv;  /* Documentation */  if (atom == NULL) {    if(!strcmp(field,"coeff2")) return(coeff2Doc);    if(!strcmp(field,"phase"))  return(phaseDoc);    if(!strcmp(field,"coeff"))  return(coeffDoc);  }  CheckAtomReal(atom);  if(!strcmp(field,"coeff2"))  return(GetFloatField(atom->coeff2,arg));  if(!strcmp(field,"phase")) {    phase = _ComputePhase(atom->cosPhase,atom->sinPhase);    return(GetFloatField(phase,arg));  }  if(!strcmp(field,"coeff"))  {    lv = TNewListv();    AppendFloat2Listv(lv,atom->coeffR);    AppendFloat2Listv(lv,atom->coeffI);    return(GetValueField((VALUE)lv,arg));  }}void *SetCoeffAtomV(ATOM atom, void **arg){  char *field = ARG_G_GetField(arg);  LWFLOAT phase;  /* Documentation */  if (atom == NULL) {    if(!strcmp(field,"coeff2")) return(coeff2Doc);    if(!strcmp(field,"phase"))  return(phaseDoc);  }  if(!strcmp(field,"coeff2")) return(SetFloatField(&(atom->coeff2),arg,FieldSPositive));  if(!strcmp(field,"phase")) {    // Init for += syntax    phase = _ComputePhase(atom->cosPhase,atom->sinPhase);    if(SetFloatField(&phase,arg,0)==NULL) return(NULL);    if((atom->freqId == 0 || atom->freqId == GABOR_NYQUIST_FREQID)       && 2*phase != (int) 2*phase) {      SetErrorf("Cannot set <phase>=%g : should be 0 or 0.5 (modulo 1) when atom.freq==0 or Nyquist. Try changing atom.freq(Id) first.",phase);      return(NULL);    }    atom->cosPhase = cos(2*M_PI*(phase-(int)phase));    atom->sinPhase = sin(2*M_PI*(phase-(int)phase));    // DEBUG    Printf("%g %g %g\n",phase,atom->cosPhase,atom->sinPhase);    return(numType);  }}/* * A virtual field to build the atom in */static char *buildcDoc = "{[*opt,...] [:]} {Gets a pair {real imag} of signals where the normalized complex atom has been built.}";static char *buildrDoc = "{[*opt,...] [:]} {Gets a signal where the real atom has been built.}";static void *GetExtractBuildAtomV(ATOM atom,void **arg){  char *field = ARG_G_GetField(arg);  SIGNAL signalR = NULL;  SIGNAL signalI = NULL;  char borderType = Name2BorderType("pad0");// TODO an EXTRACT OPTION  char flagAtomSizeOnly = NO; // TODO AN EXTRACT OPTION  LISTV lv;  if(atom==NULL) {    if(!strcmp(field,"buildc")) return(buildcDoc);    if(!strcmp(field,"buildr")) return(buildrDoc);  }  // Temporary allocation of the output signal(s)  signalR = TNewSignal();  if(!strcmp(field,"buildc")) signalI = TNewSignal();  // Building the atom  BuildAtom(atom,signalR,signalI,borderType,flagAtomSizeOnly);  // Setting the output  if(!strcmp(field,"buildc")) {    lv = TNewListv();    AppendValue2Listv(lv,(VALUE)signalR);    AppendValue2Listv(lv,(VALUE)signalI);    return(GetValueField(lv,arg));  } else {    return(GetValueField(signalR,arg));  }}static char *buildExtractDoc = "{*sizeonly,*bperiodic,...} {*sizeonly : the signal(s) where the atom will be built will have exactly the size of the atom. Otherwise the atom.signalSize will be used.}";static char *buildExtractOptions[] = {"*bperiodic","*bmirror","*bmirror1","*bconst","*b0","*sizeonly",NULL};static void *GetExtractOptionsAtomV(ATOM atom, void **arg){  char *field;    field = ARG_G_GetField(arg);  // There is no extraction on the atom itself  if(field == NULL) return(NULL);   /* doc */  if (atom == NULL) {    if (!strcmp(field,"buildr")) return(buildExtractDoc);    if (!strcmp(field,"buildc")) return(buildExtractDoc);    // There is no extraction on atom itself nor on other fields    return(NULL);  }  if (!strcmp(field,"buildr")) return(buildExtractOptions);    if (!strcmp(field,"buildc")) return(buildExtractOptions);    return(NULL);}/* * Function to get the ExtractInfo for fields 'coeff' and 'build' (and 'gg' ?) */static void *GetExtractInfoAtomV(ATOM atom, void **arg){  static ExtractInfo extractInfo;    char *field = ARG_EI_GetField(arg);  unsigned long *options = ARG_EI_GetPOptions(arg);  // No extraction is available on atom itself  if(field==NULL) return(NULL);  if(!strcmp(field,"buildr") || !strcmp(field,"buildc")) {    SetErrorf("ExtractInfo for build not finalized");return(NULL);    extractInfo.nSignals = 1;    extractInfo.xmin = 0;    extractInfo.xmax = 1;    extractInfo.dx = 1;    extractInfo.xsignal = NULL;    extractInfo.flags = EIErrorBound;    return(&extractInfo);  }   return(NULL);}/* * The field list */struct field fieldsAtom[] = {  "dx",GetDxTFContentV,SetDxTFContentV,NULL,NULL,  "x0",GetX0TFContentV,SetX0TFContentV,NULL,NULL,  "signalSize",GetSignalSizeTFContentV,NULL,NULL,NULL,  "freqIdNyquist",GetFreqIdNyquistTFContentV,NULL,NULL,NULL,  "windowShape",GetWindowShapeAtomV,SetWindowShapeAtomV,NULL,NULL,  "windowSize",GetWindowSizeAtomV,SetWindowSizeAtomV,NULL,NULL,  "timeId",GetTimeAtomV,SetTimeAtomV,NULL,NULL,  "time",GetTimeAtomV,SetTimeAtomV,NULL,NULL,  "freqId",GetFreqAtomV,SetFreqAtomV,NULL,NULL,  "freq",GetFreqAtomV,SetFreqAtomV,NULL,NULL,  "chirp",GetChirpAtomV,SetChirpAtomV,NULL,NULL,  "chirpId",GetChirpAtomV,SetChirpAtomV,NULL,NULL,  "coeff2",GetCoeffAtomV,SetCoeffAtomV,NULL,NULL,  "phase",GetCoeffAtomV,SetCoeffAtomV,NULL,NULL,  "coeff",GetCoeffAtomV,NULL,NULL,NULL,  "buildr",GetExtractBuildAtomV,NULL,GetExtractOptionsAtomV,GetExtractInfoAtomV,  "buildc",GetExtractBuildAtomV,NULL,GetExtractOptionsAtomV,GetExtractInfoAtomV,  //  "build",GetExtractBuildAtomV,NULL,NULL,NULL,  "dt",GetDtDfAtomV,NULL,NULL,NULL,  "df",GetDtDfAtomV,NULL,NULL,NULL,  "support",GetDtDfAtomV,NULL,NULL,NULL,  "supportId",GetDtDfAtomV,NULL,NULL,NULL,#ifdef ATOM_ADVANCED  "gg",GetGGAtomV,NULL,NULL,NULL,#endif // ATOM_ADVANCED  NULL, NULL, NULL, NULL, NULL};/* * The type structure for ATOM */TypeStruct tsAtom = {  "{{{&atom} {This type is the basic type for time-frequency atoms that are used in Short Time Fourier Transform and Matching Pursuit decompositions.}}}",  /* Documentation */  &atomType,       /* The basic (unique) type name */  NULL,     /* The GetType function */                           DeleteAtom,     /* The Delete function */  NewAtom,     /* The New function */    CopyAtom,       /* The copy function */  ClearAtom,       /* The clear function */    ToStrAtom,       /* String conversion */  ShortPrintAtom,   /* The Print function : print the object when 'print' is called */  PrintInfoAtom,   /* The PrintInfo function : called by 'info' */  NULL,              /* The NumExtract function : used to deal with syntax like 10a */     fieldsAtom,      /* The list of fields */}; /* EOF */

⌨️ 快捷键说明

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