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

📄 signal_alloc.c

📁 LastWave
💻 C
📖 第 1 页 / 共 4 页
字号:
 * * Very important procedure which has to be called each time one wants to use a signal. * It manages allocation. * It asks the signal 'signal' to be able to store a signal of type 'type' * and size 'size'. * * In any case it initializes all the fields except dx and x0 * */void SizeSignal(SIGNAL signal,int size,int type){  if (size < 0) Errorf("SizeSignal() : asked size is negative '%d'",size);    signal->type = type;    if (size == 0) {    signal->lastp = signal->firstp = signal->size = 0;    signal->param = 1;    return;  }          switch(type) {  	case YSIG:   	  if (signal->sizeMallocX != 0) {  		  Free(signal->X);  		  signal->X = NULL;  		  signal->sizeMallocX = 0;  	  }  	  if (signal->sizeMallocY < size) {      	  if (signal->sizeMallocY != 0) Free(signal->Y);      	  signal->Y = NULL;      	  signal->sizeMallocY = 0;      	  signal->size = 0;      	  signal->Y = FloatAlloc(size);      	  signal->sizeMallocY = size;       }       break;    case XYSIG:       if (signal->sizeMallocX < size) {      	if (signal->sizeMallocX != 0) Free(signal->X);      	signal->X = NULL;     	signal->sizeMallocX = 0;      	signal->X = FloatAlloc(size);      	signal->sizeMallocX = size;      }      if (signal->sizeMallocY < size) {      	if (signal->sizeMallocY != 0) Free(signal->Y);    	signal->Y = NULL;      	signal->sizeMallocY = 0;      	signal->size = 0;      	signal->Y = FloatAlloc(size);      	signal->sizeMallocY = size;      }      break;           default: Errorf("SizeSignal() : Bad Signal type");   }  signal->lastp = size-1;  signal->firstp = 0;  signal->size = size;  signal->param = 1;}/* * Function for Deleting a signal */void DeleteSignal(SIGNAL signal){  if (signal)    {    if (signal->nRef==0) {      Warningf("DeleteSignal() : Trying to delete a temporary signal\n");      return;    }    RemoveRefValue(signal);    if (signal->nRef > 0) return;        if (signal->X) Free(signal->X);    if (signal->Y) Free(signal->Y);    if (signal->name != defaultName) Free(signal->name);    if (flagOn) Printf("** Delete Signal %p\n",signal); #ifdef DEBUGALLOCDebugType = "Signal";#endif     Free(signal);    };}/***************************************************************************** * *  Functions to access index, Y or X values of signals            * *****************************************************************************//*  * Dichotomic recursive algorithm to find an x value within a signal * (used only in the case of an XYSIG signal   *//* Only called by the DichX routine */static int DichX_(SIGNAL signal,LWFLOAT x,int iMin,int iMax){  int i;    if (iMin == iMax) return(iMin);    if (iMax-iMin == 1) {    if (signal->X[iMax] == x) return(iMax);    return(iMin);  }  i = (iMax+iMin)/2;  if (signal->X[i] > x)  return(DichX_(signal,x,iMin,i));  return(DichX_(signal,x,i,iMax));  } /*  * Get the index associated to a x-value within a signal  * (Only for XYSIG signal) * returns -1 if x is too low */		static int DichX(SIGNAL signal,LWFLOAT x){  if (signal->size == 0) Errorf("DichX() : signal is empty");  if (signal->X[0] > x) return(-1);  if (signal->size == 1) return(0);  if (signal->X[1] > x) return(0);  if (signal->size == 2) return(1);    if (signal->X[signal->size-1] <= x) return(signal->size-1);    return(DichX_(signal,x,0,signal->size-1));}/* * The main routine that can be called from outside to get an index * associated to an x value ('xValue') whatever the type of the signal is. * This routines behaves differently depending on the type of signal : *   - YSIG  : the index is a LWFLOAT number that can be out of range and that *             is computed only using the dx and x0 fields of the signal *   - XYSIG : the index is an integer that can be out of range (-1) *             it is the  index i such that x[i] <= xvalue <  x[i+1] */ LWFLOAT X2FIndexSig(SIGNAL signal, LWFLOAT xValue){  if (signal->type == XYSIG) return(DichX(signal,xValue));  return((xValue-signal->x0)/signal->dx);}/* * The main routine that returns a Y value given an x value  * given an interpolation mode and a border type. * If flagindex is YES then x corresponds to a LWFLOAT index * otherwise, it is an x-value */LWFLOAT X2YSig(SIGNAL signal,LWFLOAT x, InterMode im, BorderType bt, char flagIndex){  int i;  LWFLOAT index;    if (flagIndex) index = x;  else index = X2FIndexSig(signal,x);    /*   * We first deal with the border type   */  switch (signal->type) {        /* case of a YSignal */    case YSIG :            /* Manage border effects */      switch (bt) {        case BorderNone :          break;        case BorderPer :           index = fmod(index,signal->size);          if (index < 0) index+=signal->size;          break;        case BorderMir1 :           index = fmod(index,2*signal->size);          if (index < 0) index+=2*signal->size;          if (index>=signal->size) index = 2*signal->size-1-index;          break;        case BorderMir :           index = fmod(index,2*signal->size-2);          if (index < 0) index+=2*signal->size-2;          if (index>=signal->size) index = 2*signal->size-2-index;          break;        case BorderCon :          if (index < 0) return(signal->Y[0]);          if (index>=signal->size) return(signal->Y[signal->size-1]);          break;        case Border0 :          if (index < 0 || index>=signal->size) return(0);          break;                  default : Errorf("X2YSig() : Weird");      }        break;          /* case of a XYSignal */    case XYSIG :      /* Manage border effects */      switch (bt) {        case BorderNone :          break;        case BorderCon :          if (index < 0) return(signal->Y[0]);          if (index>=signal->size) return(signal->Y[signal->size-1]);          break;        case Border0 :          if (index < 0 || index>=signal->size) return(0);          break;                  default : Errorf("X2YSig() : Only 'BorderNone', 'Border0' or 'BorderCon' are available for XY signals");      }      break;        }  /*   * Then the Y value    */  i = (int) floor(index);  if (i <0 || i > signal->size-1) Errorf("X2YSig() : Weird 1");    switch(im) {    case InterNone : return(signal->Y[i]);    case InterLinear :       if (i == signal->size-1) return(signal->Y[i]);      if (i+1> signal->size-1) Errorf("X2YSig() : Weird 2");      switch (signal->type) {        case YSIG : return((signal->Y[i+1]-signal->Y[i])*(index-i)+signal->Y[i]);        case XYSIG :          if (signal->X[i+1]==signal->X[i]) return(signal->Y[i]);          return((signal->Y[i+1]-signal->Y[i])*(x-signal->X[i])/(signal->X[i+1]-signal->X[i])+signal->Y[i]);      }    default : Errorf("YSig1() : Weird 2");  }}/* Returns the index corresponding to an xValue (always in range [0,signal->size-1]) */int ISig(SIGNAL signal, LWFLOAT xValue){  int i;    if (signal->type == XYSIG) return(DichX(signal,xValue));  i = (int) ((xValue-signal->x0)/signal->dx);  if (i < 0) i = 0;  else if (i >= signal->size) i = signal->size-1;  return(i);}/* Return the xValue to an index */LWFLOAT XSig(SIGNAL signal,int index){  if (signal->type == XYSIG)  	return(signal->X[index]);  else    return(signal->x0+signal->dx*index);}/* Return either the x or the y value corresponding to an index */LWFLOAT XYSig(SIGNAL signal,int index,char which){  switch(which) {    case 'Y':       return(signal->Y[index]);      break;    case 'X':      return(XSig(signal,index));      break;    default:      Errorf("Bad value of 'which' in 'XYSig' function");  }} /******************************** * *  Copy procedures             * ********************************/ /* Copy the signal in in the signal out */void CopyFieldsSig(SIGNAL in,SIGNAL out){	out->firstp = in->firstp;	out->lastp = in->lastp;	out->type = in->type;	out->size = in->size;	out->dx = in->dx;	out->x0 = in->x0;	out->param = in->param;}SIGNAL CopySig(SIGNAL in, SIGNAL out){  if (in == out) return(out);      if (out == NULL) out = NewSignal();      SizeSignal(out,in->size,in->type);    CopyFieldsSig(in,out);    memcpy(out->Y,in->Y,in->size*sizeof(LWFLOAT));  if (in->type == XYSIG) memcpy(out->X,in->X,in->size*sizeof(LWFLOAT));    return(out);}void CopySigXX(SIGNAL in,SIGNAL out,char *type){  int i;    if (out == in) Errorf("CopySigXX() : The two signals must be different");    if (!strcmp(type,"YY")) {      SizeSignal(out,in->size,YSIG);    memcpy(out->Y,in->Y,sizeof(LWFLOAT)*in->size);  }    else if (!strcmp(type,"XY")) {      SizeSignal(out,in->size,YSIG);    if (in->type == XYSIG) memcpy(out->Y,in->X,sizeof(LWFLOAT)*in->size);    else for(i=0;i<in->size;i++) out->Y[i] = XSig(in,i);  }    else if (!strcmp(type,"YX")) {      SizeSignal(out,in->size,XYSIG);    memcpy(out->X,in->Y,sizeof(LWFLOAT)*in->size);  }  else if (!strcmp(type,"XX")) {      SizeSignal(out,in->size,XYSIG);    if (in->type == XYSIG) memcpy(out->X,in->X,sizeof(LWFLOAT)*in->size);    else for(i=0;i<in->size;i++) out->X[i] = XSig(in,i);  }    else Errorf("CopySigXX() : Bad type '%s'",type);}/*********************************************************************************** * *  Parsing a signal * ***********************************************************************************//* * Parse an output Signal */char ParseSignalLevel_(LEVEL level, char *arg, SIGNAL defVal, SIGNAL *sig){  char *type;  LWFLOAT f;    type = TTEvalExpressionLevel_(level,arg,&f,(VALUE *) sig,SignalType,NO,NO,AnyType,YES);  if (type == NULL) {    *sig = defVal;    if (defVal != NULL) (*sig)->nRef++;    return(NO);  }    return(YES);}char ParseSignal_(char *arg, SIGNAL defVal, SIGNAL *sig){  return(ParseSignalLevel_(levelCur,arg,defVal,sig));}void ParseSignalLevel(LEVEL level,char *arg, SIGNAL *sig){  if (ParseSignalLevel_(level,arg,NULL,sig) == NO) Errorf1("");}void ParseSignal(char *arg, SIGNAL *sig){  ParseSignalLevel(levelCur,arg,sig);}/* * Parse an input Signal */char ParseSignalILevel_(LEVEL level, char *arg, SIGNAL defVal, SIGNAL *sig){    char *type;  LWFLOAT f;    type = TTEvalExpressionLevel_(level,arg,&f,(VALUE *) sig,SignalType,NO,NO,AnyType,NO);  if (type == NULL || (*sig)->size == 0) {    *sig = defVal;    if (defVal != NULL) {      if (defVal->size == 0) Errorf("ParseSignalILevel_() : default signal is empty");      (*sig)->nRef++;    }    return(NO);  }        return(YES);}char ParseSignalI_(char *arg, SIGNAL defVal, SIGNAL *sig){  return(ParseSignalILevel_(levelCur,arg,defVal,sig));}void ParseSignalILevel(LEVEL level, char *arg, SIGNAL *sig){  if (ParseSignalILevel_(level,arg,NULL,sig) == NO) Errorf1("");}void ParseSignalI(char *arg, SIGNAL *sig){  ParseSignalILevel(levelCur,arg,sig);}/* * The field list */struct field fieldsSignal[] = {  "", GetExtractSignalV, SetExtractSignalV, GetExtractOptionsSignalV, GetExtractInfoSignalV,  "X", GetExtractSignalV, SetExtractSignalV, GetExtractOptionsSignalV, GetExtractInfoSignalV,  "Y", GetExtractSignalV, SetExtractSignalV, GetExtractOptionsSignalV, GetExtractInfoSignalV,  "index", GetExtractSignalV, NULL, GetExtractOptionsSignalV, GetExtractInfoSignalV,  "size", GetSizeSignalV, SetSizeSignalV, NULL, NULL,  "dx", GetDxSignalV, SetDxSignalV, NULL, NULL,  "x0", GetX0SignalV, SetX0SignalV, NULL, NULL,  "name", GetNameSignalV, SetNameSignalV, NULL, NULL,  "xy", GetXYSignalV, SetXYSignalV, NULL, NULL,  "sizeAllocX", GetSizeAllocXSignalV, SetSizeAllocXSignalV, NULL, NULL,  "sizeAllocY", GetSizeAllocYSignalV, SetSizeAllocYSignalV, NULL, NULL,  "firstp", GetFirstpSignalV, SetFirstpSignalV, NULL, NULL,  "lastp", GetLastpSignalV, SetLastpSignalV, NULL, NULL,  "tolistv", GetTolistvSignalV, NULL, NULL, NULL,  NULL, NULL, NULL, NULL, NULL};/* * The type structure for SIGNAL */TypeStruct tsSignal = {  "{{{&signal} {This type is the basic type for signals. Uniformly sampled signals (i.e., Y-signals) \can be built using the <value1,...,valueN> syntax. The values can be either a LWFLOAT, a signal, a range or a listv of floats, \signals and ranges. The different operators are \n \- +,-,*,/ (and +=,-=,*=,/=) : regular operators \n \- ==,!=,<=,>=,<,> : regular tests \n \- x^f (and ^=) : each value of |x| is taken to the popwer f \n \- x*^n : each value of x to the power n where n is a positive integer \n\- ~ : transposition operator (returns a single columnimage) \n\- //,% : integer division and remainder \n \- is,isnot : test if 2 signals correspond or not to the same C object \n \- sinh,sin,cosh,cos,tanh,tan,acos,asin,atan : trigonometric operators \n \- min,max : if 1 argument, returns the min or max value of a signal, if 2 arguments returns \the signal made of the min/max of each value. \n\- log2,log,ln,sqrt,abs,exp,ceil,floor,round,frac,int : other math functions \n \- der,prim : derivative and primitive of a signal  \n \- sum : computes the sum of all signal values \n \- mean : same as sum but divides by the total number of points\n \- any : returns 1 if at least one of the values is different from 0\n \- all : returns 1 if all of the values are different from 0\n \- find : returns a signal made of indices which correspond to non 0 values \n\- YSIG Constructors : <...>,Zero,One,I,Grand,Urand \n \- XYSIG Constructors : XY(xsignal,ysignal). In the ysig expression you can use the 'X' notation which refers to xsig.}} \{{&signali} {This type corresponds to non empty signals.}}}",  /* Documentation */  &signalType,       /* The basic (unique) type name */  GetTypeSignal,     /* The GetType function */                           DeleteSignal,     /* The Delete function */  NewSignal,     /* The New function */    CopySig,       /* The copy function */  ClearSignal,       /* The clear function */    ToStrSignal,       /* String conversion */  PrintSignal,   /* The Print function : print the object when 'print' is called */  PrintInfoSignal,   /* The PrintInfo function : called by 'info' */  NULL,              /* The NumExtract function : used to deal with syntax like 10a */     fieldsSignal,      /* The list of fields */};

⌨️ 快捷键说明

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