📄 gtkanal.c
字号:
#ifdef HAVEGTK#include <math.h>#include <gtk/gtk.h>#include "gpkplotting.h"#include "util.h"#include "gtkanal.h"#include "version.h"#include "lame.h"#include "tables.h"#include "quantize-pvt.h"#include <assert.h>plotting_data *pinfo;plotting_data *pplot;plotting_data Pinfo[NUMPINFO];/* global variables for the state of the system */static gint idle_keepgoing; /* processing of frames is ON */static gint idle_count_max; /* number of frames to process before plotting */static gint idle_count; /* pause & plot when idle_count=idel_count_max */static gint idle_end=0; /* process all frames, stop at last frame */static gint idle_back = 0; /* set when we are displaying the old data */static int mp3done = 0; /* last frame has been read */static GtkWidget *frameprogress; /* progress bar */ static GtkWidget *framecounter; /* progress counter */ static int subblock_draw[3] = { 1, 1, 1 };/* main window */GtkWidget *window;/* Backing pixmap for drawing areas */GtkWidget *pcmbox; /* PCM data plotted here */GtkWidget *winbox; /* mpg123 synthesis data plotted here */GtkWidget *enerbox[2]; /* spectrum, gr=0,1 plotted here */GtkWidget *mdctbox[2]; /* mdct coefficients gr=0,1 plotted here */GtkWidget *sfbbox[2]; /* scalefactors gr=0,1 plotted here */GtkWidget *headerbox; /* mpg123 header info shown here */struct gtkinfostruct { int filetype; /* input file type 0=WAV, 1=MP3 */ int msflag; /* toggle between L&R vs M&S PCM data display */ int chflag; /* toggle between L & R channels */ int kbflag; /* toggle between wave # and barks */ int flag123; /* show mpg123 frame info, OR ISO encoder frame info */ double avebits; /* running average bits per frame */ int approxbits; /* (approx) bits per frame */ int maxbits; /* max bits per frame used so far*/ int totemph; /* total of frames with de-emphasis */ int totms; /* total frames with ms_stereo */ int totis; /* total frames with i_stereo */ int totshort; /* total granules with short blocks */ int totmix; /* total granules with mixed blocks */ int pupdate; /* plot while processing, or only when needed */ int sfblines; /* plot scalefactor bands in MDCT plot */ int difference; /* plot original - decoded instead of orig vs. decoded */ int totalframes;} gtkinfo;static lame_global_flags *gfp;lame_internal_flags *gfc;/********************************************************************** * read one frame and encode it **********************************************************************/int gtkmakeframe(void){ int iread = 0; static int init=0; static int mpglag; static short int Buffer[2][1152]; int ch,j; int mp3count = 0; int mp3out = 0; short mpg123pcm[2][1152]; char mp3buffer[LAME_MAXMP3BUFFER]; extern plotting_data *mpg123_pinfo; #ifndef HAVEMPGLIB ERRORF("Error: GTK frame analyzer requires MPGLIB\n"); LAME_ERROR_EXIT();#else /* even if iread=0, get_audio hit EOF and returned Buffer=all 0's. encode * and decode to flush any previous buffers from the decoder */ pinfo->frameNum = gfp->frameNum; pinfo->sampfreq=gfp->out_samplerate; pinfo->framesize=576*gfc->mode_gr; pinfo->stereo = gfc->stereo; gfc->pinfo = pinfo; mpg123_pinfo = pinfo; if (gfp->input_format == sf_mp3) { iread=lame_readframe(gfp,Buffer); gfp->frameNum++; }else { /* feed data to encoder until encoder produces some output */ while (gfp->frameNum == pinfo->frameNum) { if (gfp->frameNum==0 && !init) { mpglag=1; lame_decode_init(); } if (gfp->frameNum==1) init=0; /* reset for next time frameNum==0 */ iread=lame_readframe(gfp,Buffer); if (iread > gfp->framesize) { /* NOTE: frame analyzer requires that we encode one frame * for each pass through this loop. If lame_encode_buffer() * is feed data too quickly, it will sometimes encode multiple frames * breaking this loop. */ MSGF("Warning: lame_readframe is returning too much data.\n"); } mp3count=lame_encode_buffer(gfp,Buffer[0],Buffer[1],iread, mp3buffer,(int)sizeof(mp3buffer)); assert( !(mp3count > 0 && gfp->frameNum == pinfo->frameNum)); /* not possible to produce mp3 data without encoding at least * one frame of data which would increment gfp->frameNum */ } /* decode one frame of output */ mp3out=lame_decode1(mp3buffer,mp3count,mpg123pcm[0],mpg123pcm[1]); /* re-synthesis to pcm */ /* mp3out = 0: need more data to decode */ /* mp3out = -1: error. Lets assume 0 pcm output */ /* mp3out = number of samples output */ if (mp3out>0) assert(mp3out==pinfo->framesize); if (mp3out!=0) { /* decoded output is for frame pinfo->frameNum123 * add a delay of framesize-DECDELAY, which will make the total delay * exactly one frame */ pinfo->frameNum123=pinfo->frameNum-mpglag; for ( ch = 0; ch < pinfo->stereo; ch++ ) { for ( j = 0; j < pinfo->framesize-DECDELAY; j++ ) pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j+pinfo->framesize]; for ( j = 0; j < pinfo->framesize; j++ ) { pinfo->pcmdata2[ch][j+pinfo->framesize-DECDELAY] = (mp3out==-1) ? 0 : mpg123pcm[ch][j]; } } }else{ if (mpglag == MAXMPGLAG) { ERRORF("READ_AHEAD set too low - not enough frame buffering.\n" "MP3x display of input and output PCM data out of sync.\n"); FLUSH_ERROR(); } else mpglag++; pinfo->frameNum123=-1; /* no frame output */ } }#endif return iread;}void plot_frame(void){ int i,j,n,ch,gr; gdouble *xcord,*ycord; gdouble xmx,xmn,ymx,ymn; double *data,*data2,*data3; char title2[80]; char label[80],label2[80]; char *title; plotting_data *pplot1; plotting_data *pplot2 = NULL; double en,samp; int sampindex,version=0; int barthick; static int firstcall=1; static GdkColor *barcolor,*color,*grcolor[2]; static GdkColor yellow,gray,cyan,magenta,orange,pink,red,green,blue,black,oncolor,offcolor; int blocktype[2][2]; int headbits; int mode_gr = 2; /* find the frame where mpg123 produced output coming from input frame * pinfo. i.e.: out_frame + out_frame_lag = input_frame */ for (i=1; i<=MAXMPGLAG; i++ ) { if ((pplot-i)->frameNum123 == pplot->frameNum ) { pplot2 = pplot-i; break; } } if (i > MAXMPGLAG) { ERRORF("input/output pcm syncing problem. should not happen!\n"); pplot2=pplot-1; } /* however, the PCM data is delayed by 528 samples in the encoder filterbanks. * We added another 1152-528 delay to this so the PCM data is *exactly* one * frame behind the header & MDCT information */ pplot1 =pplot2 +1; /* back one frame for header info, MDCT */ /* allocate these GC's only once */ if (firstcall) { firstcall=0; /* grcolor[0] = &magenta; */ grcolor[0] = &blue; grcolor[1] = &green; barcolor = &gray; setcolor(headerbox,&oncolor,255,0,0); setcolor(headerbox,&offcolor,175,175,175); setcolor(pcmbox,&red,255,0,0); setcolor(pcmbox,&pink,255,0,255); setcolor(pcmbox,&magenta,255,0,100); setcolor(pcmbox,&orange,255,127,0); setcolor(pcmbox,&cyan,0,255,255); setcolor(pcmbox,&green,0,255,0); setcolor(pcmbox,&blue,0,0,255); setcolor(pcmbox,&black,0,0,0); setcolor(pcmbox,&gray,100,100,100); setcolor(pcmbox,&yellow,255,255,0); } /******************************************************************* * frame header info *******************************************************************/ if (pplot1->sampfreq) samp=pplot1->sampfreq; else samp=1; sampindex = SmpFrqIndex((long)samp, &version); ch = gtkinfo.chflag; headbits = 32 + ((pplot1->stereo==2) ? 256 : 136); gtkinfo.approxbits = (pplot1->bitrate*1000*1152.0/samp) - headbits; sprintf(title2,"%3.1fkHz %ikbs ",samp/1000,pplot1->bitrate); gtk_text_freeze (GTK_TEXT(headerbox)); gtk_text_backward_delete(GTK_TEXT(headerbox), gtk_text_get_length(GTK_TEXT(headerbox))); gtk_text_set_point(GTK_TEXT(headerbox),0); gtk_text_insert(GTK_TEXT(headerbox),NULL,&oncolor,NULL,title2, -1); title = " mono "; if (2==pplot1->stereo) title = pplot1->js ? " js " : " s "; gtk_text_insert (GTK_TEXT(headerbox), NULL, &oncolor, NULL,title, -1); color = pplot1->ms_stereo ? &oncolor : &offcolor ; gtk_text_insert (GTK_TEXT(headerbox), NULL, color, NULL,"ms ", -1); color = pplot1->i_stereo ? &oncolor : &offcolor ; gtk_text_insert (GTK_TEXT(headerbox), NULL, color, NULL,"is ", -1); color = pplot1->crc ? &oncolor : &offcolor ; gtk_text_insert (GTK_TEXT(headerbox), NULL, color, NULL,"crc ", -1); color = pplot1->padding ? &oncolor : &offcolor ; gtk_text_insert (GTK_TEXT(headerbox), NULL, color, NULL,"pad ", -1); color = pplot1->emph ? &oncolor : &offcolor ; gtk_text_insert (GTK_TEXT(headerbox), NULL, color, NULL,"em ", -1); sprintf(title2,"bv=%i,%i ",pplot1->big_values[0][ch],pplot1->big_values[1][ch]); gtk_text_insert (GTK_TEXT(headerbox), NULL, &black, NULL,title2, -1); color = pplot1->scfsi[ch] ? &oncolor : &offcolor ; sprintf(title2,"scfsi=%i ",pplot1->scfsi[ch]); gtk_text_insert (GTK_TEXT(headerbox), NULL, color, NULL,title2, -1); if (gtkinfo.filetype) sprintf(title2," mdb=%i %i/NA",pplot1->maindata,pplot1->totbits); else sprintf(title2," mdb=%i %i/%i", pplot1->maindata,pplot1->totbits,pplot->resvsize); gtk_text_insert (GTK_TEXT(headerbox), NULL, &oncolor, NULL,title2, -1); gtk_text_thaw (GTK_TEXT(headerbox)); /******************************************************************* * block type *******************************************************************/ for (gr = 0 ; gr < mode_gr ; gr ++) if (gtkinfo.flag123) blocktype[gr][ch]=pplot1->mpg123blocktype[gr][ch]; else blocktype[gr][ch]=pplot->blocktype[gr][ch]; /******************************************************************* * draw the PCM data * *******************************************************************/ n = 1600; /* PCM frame + FFT window: 224 + 1152 + 224 */ xcord = g_malloc(n*sizeof(gdouble)); ycord = g_malloc(n*sizeof(gdouble)); if (gtkinfo.msflag) title=ch ? "Side Channel" : "Mid Channel"; else title=ch ? "Right Channel" : "Left Channel"; sprintf(title2,"%s mask_ratio=%3.2f %3.2f ener_ratio=%3.2f %3.2f", title, pplot->ms_ratio[0],pplot->ms_ratio[1], pplot->ms_ener_ratio[0],pplot->ms_ener_ratio[1]); ymn = -32767 ; ymx = 32767; xmn = 0; xmx = 1600-1; /* 0 ... 224 draw in black, connecting to 224 pixel * 1375 .. 1599 draw in black connecting to 1375 pixel * 224 ... 1375 MP3 frame. draw in blue */ /* draw the title */ gpk_graph_draw(pcmbox,0,xcord,ycord,xmn,ymn,xmx,ymx,1,title2, &black); /* draw some hash marks dividing the frames */ ycord[0] = ymx*.8; ycord[1] = ymn*.8; for (gr=0 ; gr<=2; gr++) { xcord[0] = 223.5 + gr*576; xcord[1] = 223.5 +gr*576; gpk_rectangle_draw(pcmbox,xcord,ycord,xmn,ymn,xmx,ymx,&yellow); } for (gr = 0 ; gr < mode_gr ; gr++) { if (blocktype[gr][ch]==2) for (i=1 ; i<=2; i++) { xcord[0] = 223.5+gr*576 + i*192; xcord[1] = 223.5+gr*576 + i*192; gpk_rectangle_draw(pcmbox,xcord,ycord,xmn,ymn,xmx,ymx,&yellow); } } /* bars representing FFT windows */ xcord[0] = 0; ycord[0] = ymn+3000; xcord[1] = 1024-1; ycord[1] = ymn+1000; gpk_rectangle_draw(pcmbox,xcord,ycord,xmn,ymn,xmx,ymx,grcolor[0]); xcord[0] = 576; ycord[0] = ymn+2000; xcord[1] = 576+1024-1; ycord[1] = ymn; gpk_rectangle_draw(pcmbox,xcord,ycord,xmn,ymn,xmx,ymx,grcolor[1]); /* plot PCM data */ for (i=0; i<n; i++) { xcord[i] = i; if (gtkinfo.msflag) ycord[i] = ch ? .5*(pplot->pcmdata[0][i]-pplot->pcmdata[1][i]) : .5*(pplot->pcmdata[0][i]+pplot->pcmdata[1][i]); else ycord[i]=pplot->pcmdata[ch][i]; } /* skip plot if we are doing an mp3 file */ if (!gtkinfo.filetype) { gpk_graph_draw(pcmbox,n,xcord,ycord,xmn,ymn,xmx,ymx,0,title2,&black); } /*******************************************************************/ /* draw the PCM re-synthesis data */ /*******************************************************************/ n = 1152; /* sprintf(title2,"Re-synthesis mask_ratio=%3.2f %3.2f ener_ratio=%3.2f %3.2f", pplot->ms_ratio[0],pplot->ms_ratio[1], pplot->ms_ener_ratio[0],pplot->ms_ener_ratio[1]); */ title="Re-synthesis"; if (gtkinfo.difference)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -