?? mp_graph.c
字號(hào):
/*..........................................................................*//* *//* L a s t W a v e P a c k a g e 'mp' 2.1 *//* *//* Copyright (C) 2000 Remi Gribonval, Emmanuel Bacry and Javier Abadia.*//* email : remi.gribonval@inria.fr *//* email : lastwave@cmap.polytechnique.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 *//* *//*..........................................................................*//****************************************************************************//* *//* mp_graph.c Functions for displaying books *//* *//****************************************************************************/#include "lastwave.h"#include "mp_book.h"/* The GOBJECT structure for displaying a BOOK */typedef struct graphBook { GObjectFields; /* The book to be displayed */ BOOK book; /* The limits on which atoms to display */ unsigned long nMin,nMax; /* minimum and maximum ranks of molecules that are displayed */ unsigned long windowSizeMin, windowSizeMax; /* 'windowSize' range */ LWFLOAT chirpIdMin,chirpIdMax; /* 'chirpId' range */ /* Some flags changing the color-code */ char flagFund; /* * the way an harmonic molecule is displayed : * see help in function _SetGraphBook */ char flagDb; /* switches decibel display */ LWFLOAT exponent; /* dynamic range (dB) / exponent ... */ // char flagLogFreq; // LWFLOAT freqSwitch; /* The colormap used */ unsigned long cm;} GraphBook, *GRAPHBOOK;/* The corresponding class */ GCLASS theGraphBookClass = NULL;enum { FundAll=NO, FundMax, FundSum};/* Some default values */#define DEFAULT_GRAPH_BOOK_FLAGFUND FundAll#define DEFAULT_GRAPH_BOOK_FLAGDB YES#define DEFAULT_GRAPH_BOOK_EXPONENT 30.0//#define DEFAULT_GRAPH_BOOK_FLAGLOGFREQ NO//#define DEFAULT_GRAPH_BOOK_FREQSWITCH 300.0/* Initialization of the GraphBook structure */static void _InitGraphBook(GOBJECT o){ GRAPHBOOK graph; graph = (GRAPHBOOK) o; graph->bgColor = invisibleColor; graph->rectType = SmallRect; graph->book = NULL; graph->nMin = 0; graph->nMax = 0; graph->windowSizeMin = STFT_MIN_WINDOWSIZE; graph->windowSizeMax = STFT_MAX_WINDOWSIZE; graph->chirpIdMin = 0.0; graph->chirpIdMax = 0.0; graph->flagFund = DEFAULT_GRAPH_BOOK_FLAGFUND; graph->flagDb = DEFAULT_GRAPH_BOOK_FLAGDB; graph->exponent = DEFAULT_GRAPH_BOOK_EXPONENT; // graph->flagLogFreq = DEFAULT_GRAPH_BOOK_FLAGLOGFREQ; // graph->freqSwitch = DEFAULT_GRAPH_BOOK_FREQSWITCH; graph->book = NULL; graph->cm = GetColorMapCur(); }/* Deleting the content of a GraphBook */static void _DeleteContentGraphBook(GOBJECT o){ GRAPHBOOK graph; graph = (GRAPHBOOK) o; if (graph->book != NULL) graph->book = DeleteBook(graph->book);}/* A utility that tells whether an atom is to be displayed in a graph */static char IsVisible(GRAPHBOOK graph,ATOM atom){ if (!INRANGE(graph->windowSizeMin,atom->windowSize,graph->windowSizeMax)) return(NO); if (!INRANGE(graph->chirpIdMin,atom->chirpId,graph->chirpIdMax)) return(NO); return(YES);}/* The setg method */static int _SetGraphBook (GOBJECT o, char *field, char**argv){ GRAPHBOOK graph; BOOK book; MOLECULE molecule; ATOM atom=NULL; char *str; int imin,imax; LWFLOAT fmin,fmax; LWFLOAT t,f,timeId,freqId; int flag; unsigned long n,nClosest; unsigned short k,kClosest; int timeIdMin,timeIdMax; LWFLOAT freqIdMin,freqIdMax; LWFLOAT dist,distClosest; LISTV lv; /* The help command */ if (o == NULL) { SetResultStr("{{{graph [<book>]} {Gets/Sets the book to be displayed by the GraphBook. (The '-cgraph' field is equivalent to that field).}} \{{cm [<colormap>]} {Sets/Gets the colormap that will be used to display the book.}} \{{scale [<windowSizeMin> <windowSizeMax>]} {Sets/Gets the windowSize range of the molecules that are displayed.}} \{{chirp [<chirpMin> <chirpMax>]} {Sets/Gets the chirp range of the molecules that are displayed.}} \{{chirpId [<chirpIdMin> <chirpIdMax>]} {Sets/Gets the chirpId range of the molecules that are displayed.}} \{{n [<nMin> <nMax>]} {Sets/Gets the minimum and maximum ranks of the molecules that are displayed.}} ""{{fund <flag>} {Sets/Gets the fundamental flag which can be 'all','max' or 'sum'. This flag allows to display all the atoms within each molecule (<flag>='all') or \only the most energetic atom with its energy (<flag>='max') or with the total energy of the molecule (<flag>='sum').}} "" {{db [<flagOnOff>]} {Sets/Gets the decibel-display flag. If it is on, the energy of the molecules is displayed in decibel.}} \{{expo [<exponent>]} {Sets/Gets the exponent used for display. If '-db' is off, then the energy to the <exponent> of the molecules is displayed. If '-db' is on, then the same quantity is displayed in decibel.}} \{{?closest <time> <freq>} {Gets the rank of the atom that is currently displayed and that is the closest to position <time> <freq>. It returns either 'null' if it fails or a listv {<n> <k>} where 0<=n<book.size is the rank of the molecule and 0<=k<molecule.dim is the atom number in the molecule.}}}"); return(YES); } graph = (GRAPHBOOK) o; book = graph->book; /* the 'graph' and 'cgraph' fields */ if (!strcmp(field,"graph") || !strcmp(field,"cgraph")) { if (*argv == NULL) { SetResultValue(graph->book); return(YES); } argv = ParseArgv(argv,tBOOK,&book,0); CheckBookNotEmpty(book); if (graph->book != NULL) DeleteBook(graph->book); graph->book = book; AddRefValue(book); graph->nMin = 0; graph->nMax = book->size-1; graph->windowSizeMin = STFT_MIN_WINDOWSIZE; graph->windowSizeMax = STFT_MAX_WINDOWSIZE; graph->chirpIdMax = GABOR_MAX_CHIRPID; graph->chirpIdMin = -graph->chirpIdMax; o->rx = TimeId2Time(book,-.5); o->rw = TimeId2Time(book,book->signalSize-.5); o->rw-=o->rx; o->ry = FreqId2Freq(book,-.5); o->rh = FreqId2Freq(book,GABOR_NYQUIST_FREQID+.5); o->rh-=o->ry; UpdateGlobalRectGObject(o); return(YES); } /* The octave field */ if (!strcmp(field,"s")) { if (*argv == NULL) { lv = TNewListv(); SetResultValue(lv); AppendInt2Listv(lv,graph->windowSizeMin); AppendInt2Listv(lv,graph->windowSizeMax); return(YES); } argv = ParseArgv(argv,tINT,&imin,tINT,&imax,0); imin = MAX(imin,STFT_MIN_WINDOWSIZE); imax = MIN(imax,STFT_MAX_WINDOWSIZE); if (imin>imax) Errorf("_SetGraphBook : Option '-scale' : Minimum windowSize value '%d' cannot be greater than maximum windowSize value '%d'",imin,imax); graph->windowSizeMin = imin; graph->windowSizeMax = imax; return(YES); } /* The chirpId field */ if (!strcmp(field,"chirpId")) { if (*argv == NULL) { lv = TNewListv(); SetResultValue(lv); AppendFloat2Listv(lv,graph->chirpIdMin); AppendFloat2Listv(lv,graph->chirpIdMax); return(YES); } argv = ParseArgv(argv,tFLOAT,&fmin,tFLOAT,&fmax,0); fmin = MAX(fmin,-GABOR_MAX_CHIRPID); fmax = MIN(fmax,GABOR_MAX_CHIRPID); if (fmin > fmax) Errorf("_SetGraphBook : Option '-chirpId' : Minimum chirpId value '%g' cannot be greater than maximum chirpId value '%g'",fmin,fmax); graph->chirpIdMin = fmin; graph->chirpIdMax = fmax; return(YES); } /* The chirp field */ if (!strcmp(field,"chirp")) { if (*argv == NULL) { lv = TNewListv(); SetResultValue(lv); AppendFloat2Listv(lv,ChirpId2Chirp(graph->book,graph->chirpIdMin)); AppendFloat2Listv(lv,ChirpId2Chirp(graph->book,graph->chirpIdMax)); return(YES); } argv = ParseArgv(argv,tFLOAT,&fmin,tFLOAT,&fmax,0); fmin = MAX(Chirp2ChirpId(graph->book,fmin),-GABOR_MAX_CHIRPID); fmax = MIN(Chirp2ChirpId(graph->book,fmax),GABOR_MAX_CHIRPID); if (fmin > fmax) Errorf("_SetGraphBook : Option '-chirp' : Minimum chirp value '%g' cannot be greater than maximum chirp value '%g'",fmin,fmax); graph->chirpIdMin = fmin; graph->chirpIdMax = fmax; return(YES); } /* The closest field */ if (!strcmp(field,"?closest")) { argv = ParseArgv(argv,tFLOAT,&t,tFLOAT,&f,0); timeId = Time2TimeId(book,t); freqId = Freq2FreqId(book,f); /* Some inits */ distClosest = -1.0; /* Look for all the molecules of which some atom is displayed in this graph */ for (n = MAX(0,graph->nMin); n <= MIN(book->size-1,graph->nMax); n++) { molecule = GetBookMolecule(book,n); for (k=0;k<molecule->dim;k++) { atom = GetMoleculeAtom(molecule,0,k); if (!IsVisible(graph,atom)) continue; /* * Detect if (timeId,freqId) is indeed INSIDE some atom. */ ComputeWindowSupport(atom->windowSize,atom->windowShape,atom->timeId,&timeIdMin,&timeIdMax); freqIdMin = atom->freqId-(GABOR_MAX_FREQID/atom->windowSize)/(2.0); freqIdMax = atom->freqId+(GABOR_MAX_FREQID/atom->windowSize)/(2.0); if(INRANGE(timeIdMin,timeId,timeIdMax) && INRANGE(freqIdMin,freqId,freqIdMax)) { distClosest = 0.0; nClosest = n; kClosest = k; break; } /* When not 'inside' the atom, compute the distance to (timeId,freqId) */ dist = pow(fabs(timeId-atom->timeId),2.)+pow(fabs(freqId-atom->freqId),2.); /* Update the location of the closest molecule, if necessary */ if (distClosest < 0 || distClosest > dist) { distClosest = dist; nClosest = n; kClosest = k; } } /* Case when (timeId,freqId) is 'inside' some displayed atom */ if (distClosest == 0.0) break; } if (distClosest < 0) { SetResultValue(nullValue); } else { lv = TNewListv(); SetResultValue(lv); AppendInt2Listv(lv,nClosest); AppendInt2Listv(lv,kClosest); } return(YES); } /* The n field */ if (!strcmp(field,"n")) { if (*argv == NULL) { lv = TNewListv(); SetResultValue(lv); AppendInt2Listv(lv,graph->nMin); AppendInt2Listv(lv,graph->nMax); return(YES); } argv = ParseArgv(argv,tINT,&imin,tINT,&imax,0); imin = MAX(imin,0); imax = MIN(imax,book->size-1); if (imin>imax) Errorf("_SetGraphBook : Option '-n' : Minimum n-value '%d' cannot be greater than maximum n-value '%d'",imin,imax); graph->nMin = imin; graph->nMax = imax; return(YES); } /* The fund field */ if (!strcmp(field,"fund")) { if (*argv == NULL) { switch(graph->flagFund) { case FundAll : SetResultStr("all"); break; case FundMax : SetResultStr("max"); break; case FundSum : SetResultStr("sum"); break; default : Errorf("???? bad flagFund"); } return(YES); } argv = ParseArgv(argv,tSTR,&str,0); if(!strcmp(str,"all")) { graph->flagFund = FundAll; return(YES); } if(!strcmp(str,"max")) { graph->flagFund = FundMax; return(YES); } if(!strcmp(str,"sum")) { graph->flagFund = FundSum; return(YES); } Errorf("_SetGraphBook : Option -fund : bad value '%s'",str); return(NO); } /* The db field */ if (!strcmp(field,"db")) { if (*argv == NULL) { SetResultInt((int) graph->flagDb); return(YES); } argv = ParseArgv(argv,tINT,&flag,0); graph->flagDb = (flag!=0); return(YES); } /* The expo field */ if (!strcmp(field,"expo")) { if (*argv == NULL) { SetResultFloat(graph->exponent); return(YES); } argv = ParseArgv(argv,tFLOAT,&(graph->exponent),0); return(YES); }// /* The logFreq field */// if (!strcmp(field,"logfreq")) {// if (*argv == NULL) {// SetResultInt((int) graph->flagLogFreq);// return(YES); // } // argv = ParseArgv(argv,tINT,&flag,0);// graph->flagLogFreq = (flag!=0);// return(YES);// }// /* The expo field */// if (!strcmp(field,"freqswitch")) {// if (*argv == NULL) {// SetResultFloat(graph->freqSwitch);// return(YES); // } // argv = ParseArgv(argv,tFLOAT,&(graph->freqSwitch),0);// return(YES);// } /* The colormap field */ if (!strcmp(field,"cm")) { if (*argv == NULL) { SetResultStr(GetColorMapName(graph->cm)); return(YES); } argv = ParseArgv(argv,tCOLORMAP,&(graph->cm),0); return(YES); } /* The 'rect' field */ if (!strcmp(field,"rect")) { NoMoreArgs(argv); if (book == NULL) { lv = TNewListv(); SetResultValue(lv); AppendFloat2Listv(lv,0); AppendFloat2Listv(lv,0); AppendFloat2Listv(lv,0); AppendFloat2Listv(lv,0); return(YES); } o->rx = TimeId2Time(book,-.5); o->rw = TimeId2Time(book,book->signalSize-.5); o->rw-=o->rx; o->ry = FreqId2Freq(book,-.5); o->rh = FreqId2Freq(book,GABOR_NYQUIST_FREQID+.5); o->rh-=o->ry; UpdateGlobalRectGObject(o); lv = TNewListv(); SetResultValue(lv); AppendFloat2Listv(lv,o->rx); AppendFloat2Listv(lv,o->ry); AppendFloat2Listv(lv,o->rw);
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -