Équipe Analyse/Synthèse |
typedef struct _SvpOptions /* (modif 30/07/98) */ /* any change must be reported to copySvpOptions */ { int fftSize; /* fft size in the super vp command line */ int windowSize; /* window size */ int step; /* step size */ STRING output; /* s vp output (ampl or ampl_db) */ } SvpOptions;Cette structure est utilisee dans le contexte d'analyse qui se situe dans le buffer (contexte d'analyse courante) et de view (contexte d'analyse par defaut). La structure de contexte d'analys est la suivante:
typedef struct _AnalysisContext { /* any change must be reported to copyAnalysisContext */ ... short type; /* type of analysis: ANALYSIS_TYPE_### */ short spectrumType; /* type of scale: SPECTRUM_TYPE_### */ ... SvpOptions* svpOptions; /* options in the super vp command line */ } AnalysisContext;
typedef struct _ColorRamp /* (modif 03/08/98) */ { int ibramp; /* index of the begining of the color ramp */ int ieramp; /* index of the end of the color ramp */ int bDisplayRampAmpl; /* index of the begining ampl of the displayed color ramp */ int eDisplayRampAmpl; /* index of the end amplitude of the displayed color ramp */ } ColorRamp;Cette strucure pourrait dans un premier temps etre definie pour chaque view, mais le peu de de couleurs disponibles, dans la seule profondeur d'ecran maximale toleree par XSpect (8 bits, c'est a dire 256 couleurs), en tenant compte de l'utilisation de l'overlay qui oblige a reserver quatre fois plus de couleurs que necessaire, il ne reste pas suffisement de couleurs pour allouer plusieurs degrades. On utilise donc une seule ColorRamp, declaree dans une variable globale, tout en concervant une possibilite d'evolution facile. On declare donc :
extern ColorRamp colorRamp;
typedef struct _Options { ... int dBLimitForDisplay; /* (modif 04/09/98)*/ ... } *OptionsPtr, Options;
Nous allons maintenant suivre la construction de l'analyse pas a pas, dans le but de voir precisement la facon dont les fonctions sont utilisees.
#define BUFFER_NATURE_spectrogram 3 /* time x frequency x amplitude */ #define BUFFER_TYPE_regularSampleTrames 6 /* (modif 29/07/98) */Le type du buffer, regularSampleTrames signifie que les donnees sont ordonnees par trames, une trame correpondant a un echantillon temporel, ces trames etant regulierement espacees. La creation du buffer est effectuee dans la fonction askCallUdi. Cette fonction initialise principalement deux parties de la structure du buffer:
La fonction utilisee est :
void askCallUdi(View *viewParam,View *viewFromParam) (du fichier analyse.c)Il faut noter que cette meme fonction est appele lorsque une analyse est refaite (Redo Analysis du menu d'analyse). Dans ce cas, l'etape de creation et d'initialisation du buffer est sautee. Contrairement a ce qui se passait dans le passe, un buffer ne peut pas changer de nature lorsqu'une analyse est refaite: si on change le type d'analyse dans une view, un nouveau buffer est cree puis place dans cette vue par la suite, pour eviter des problemes d'incoherence.
void doUDI(View* uneView,Buffer* unBuffer)Contrairement a ce que suggere son nom, comme c'est le cas de la fonction precedente, doUDI est utilise a la fois pour les analyses udi et SuperVP, son nom etant du a des raisons historiques. Apres avoir teste
Une fois le buffer construit comme nous allons dans le voir, Le buffer est lie a la view (s'il vient d'etre cree), la structure des donnes est mise a jour (minimas et maximas de chacun des axes, dans update.c) puis affiche.
De plus, si des synchronisations sont posees sur cette view, c'est a la fin de cette fonction qu'elles vont etre gerees.
void callSvpSpectrogram(View* viewFrom,Buffer* bufferTo)Le deroulement de cette fonction du fichier svpAnalysis.c (qui, par ailleurs, est abondement commentee dans le programme) est le suivant :
getAnalysisFilename(nom_de_fichier,buffer) et nom = $SFDIR/tmp.xspect.[pid].[ref du buffer]
buildSvpCommandLine(chaine_de_commande,view_from,Buffer_d_analyse,nom_de_fichier)
executeOutputCommand(viewFrom,command);
mmapBufferData(buffer);Cette fonction est une adaptation de la fonction de mapping qui etait utilisee precedement, de maniere a la rendre plus generique. De fait, c'est aussi cette fonction qui est utilisee lors du chargement de fichiers dansl e mode Visit.
void MakeXSpectrogram(View* uneView,DisplayContext* unDispCt)Cette fonction, ainsi que les fonctions qu'elle utilise sont commentees precisement au sein du programme . Nous n'allons donc voire que son principe de base.
L'affichage est effectue en X. On parcoure le pixmap (de type XImage) point par point a travers une boucle verticale (frequence) et une boucle horizontale (temps). Pour chaque pixel, on doit determiner l'amplitude, puis la couleur correpondante. Pour cela, il faut pouvoir determiner la valeur qui correpond a un couple (x,y) du pixmap.
Pour ces conversions, il est necessaire d'extraire de la structure SvpOptions de l'analyse la distance en pixels ou en secondes entre deux trames, la distance en pixels ou en hertz entre deux donnees d'une meme trame, etc. Ces donnees peuvent etre obtenues a partir des fonctions du fichier svpAnalysis.c que sont
/* * returns the size of the Frame for a BUFFER_TYPE_regularSampleTrames * returns 1 otherwise */ int getTrameSize(Buffer* unBuffer) {} /* * returns the time between two steps of an super vp analysis */ float getTrameTimeStep(Buffer* unBuffer) {} /* * returns the frequency interval between two values * of a same trame (modif 16/08/98) */ float getTrameFreqStep(Buffer* unBuffer) {} /* * returns the number of pixels between two trames */ float getNbPixelsBetweenTrames(View* uneView) {} /* * returns the number of pixels between two datas of a trame */ float getNbPixelsBetweenDatas(View* uneView) {}Ensuite, il reste a faire correpondre une amplitude absolue de la donnee correpondant au buffer a la couleur correpondant a une intensite en dB. C'est ce que fait la fonction:
int getColorIndex(amplitude, unData)Cette fonction tien compte de la limite d'affichage, et des maximum et minimum de la donnee.
bDisplayRampAmpl et eDisplayRampAmplCette boite est une boite de contexte standard. Elle est definie dans le fichier dialogColor.c. Une variable globale est egalement definie, par souci de coherence avec les autres boites de contexte, et se nomme colorEditors[]. Lors de l'appuis sur le bouton apply, ou de tout deplacement si le mode auto-apply est activite, la nouvelle palette de couleur est calculee dans une fonction de color.c:
void StoreColorRampInColormap(aColormap,beginIndex,endIndex,beginRampIndex,endRampIndex);Cette fonction repartit lineairement, du blanc au noir, des niveaux de gris correpondants aux amplitudes situees entre bDisplayRampAmpl et eDisplayRampAmpl. En dessus et en deca de ces seuils les couleurs extremes de la palettes sont utilisees. Pour convertir les valeurs en dB obtenues dans la structure ColorRamp en indexes correpondants, on fait appel a la fonction de color.c getColorIndexFromAmplInDb. La fonction effetcuant l'operation inverse existe egalement et se nomme getAmplIndBFromColorIndex.
void storeRVBColor(iCoul,red,green,blue)Celle ci recupere un pointeur sur la cellule du tableau de cellules de couleur exactDefs correpondante a l'indice iCoul chaque intensite RVB par la primitive XQueryColor. Puisque elle fait a son tour appel a la primitive X XStoreColor, qui ne peut etre utilisee que sur des palettes accessibles en lecture/ecriture (ce qui est le cas du fait de l'allocation de ColorCells en mode read/write, lorsque le materiel le permet).