📄 gtkanal.c
字号:
/* * GTK plotting routines source file * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* $Id: gtkanal.c,v 1.35 2005/01/13 18:20:43 bouvigne Exp $ */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <math.h>#include <gtk/gtk.h>#include <assert.h>#include "main.h"#include "lame.h"#include "lame-analysis.h"#include "get_audio.h"#include "gtkanal.h"#include "gpkplotting.h"/* this file should be removed. The few data items accessed in 'gfc' should be made accessable by writing a lame_set_variable() function */#include "util.h"#ifdef WITH_DMALLOC#include <dmalloc.h>#endif#ifdef _WIN32# include <windows.h># define msleep(t) Sleep(t)#else# include <unistd.h># define msleep(t) usleep((t) * 1000)#endif/*! Stringify \a x. */#define STR(x) #x/*! Stringify \a x, perform macro expansion. */#define XSTR(x) STR(x)#define MP3X_MAJOR_VERSION 0 /* Major version number */#define MP3X_MINOR_VERSION 82 /* Minor version number */#define MP3X_ALPHA_VERSION 0 /* Set number if this is an alpha version, otherwise zero */#define MP3X_BETA_VERSION 0 /* Set number if this is a beta version, otherwise zero */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 totpreflag; /* total granules with preflag */ 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]; short int mpg123pcm[2][1152]; int ch,j; int mp3count = 0; int mp3out = 0; int channels_out; char mp3buffer[LAME_MAXMP3BUFFER]; extern plotting_data *mpg123_pinfo; static int frameNum=0; int framesize = lame_get_framesize(gfp); channels_out = (lame_get_mode(gfp)==MONO) ? 1 : 2; pinfo->frameNum = frameNum; pinfo->sampfreq = lame_get_out_samplerate ( gfp ); pinfo->framesize= framesize; pinfo->stereo = channels_out; /* If the analsys code is enabled, lame will writes data into gfc->pinfo, * and mpg123 will write data into mpg123_pinfo. Set these so * the libraries put this data in the right place: */ gfc->pinfo = pinfo; mpg123_pinfo = pinfo; if (input_format == sf_mp1 || input_format == sf_mp2 || input_format == sf_mp3) { iread = get_audio16(gfp,Buffer); /* add a delay of framesize-DECDELAY, which will make the total delay * exactly one frame, so we can sync MP3 output with WAV input */ for ( ch = 0; ch < channels_out; ch++ ) { for ( j = 0; j < framesize-DECDELAY; j++ ) pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j+framesize]; for ( j = 0; j < framesize; j++ ) /*rescale from int to short int */ pinfo->pcmdata2[ch][j+framesize-DECDELAY] = Buffer[ch][j]; } pinfo->frameNum123 = frameNum-1; ++frameNum; }else { /* feed data to encoder until encoder produces some output */ while (lame_get_frameNum(gfp) == pinfo->frameNum) { if (!init) { init=1; mpglag=1; lame_decode_init(); } iread = get_audio16(gfp,Buffer); if (iread > 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. */ fprintf(stderr,"Warning: get_audio is returning too much data.\n"); } if (0==iread) break; /* eof */ mp3count=lame_encode_buffer(gfp,Buffer[0],Buffer[1],iread, mp3buffer,(int)sizeof(mp3buffer)); assert( !(mp3count > 0 && lame_get_frameNum(gfp) == pinfo->frameNum)); /* not possible to produce mp3 data without encoding at least * one frame of data which would increment frameNum */ } frameNum = lame_get_frameNum(gfp); /* use the internal MP3 frame counter */ /* 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) { fprintf(stderr,"READ_AHEAD set too low - not enough frame buffering.\n" "MP3x display of input and output PCM data out of sync.\n"); fflush(stderr); } else mpglag++; pinfo->frameNum123=-1; /* no frame output */ } } 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) { fprintf(stderr,"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,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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -