📄 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>
int gtkflag;
extern int makeframe(void);
/* 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 */
plotting_data *pinfo,*pplot;
plotting_data Pinfo[NUMPINFO];
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 totalframes;
} gtkinfo;
static lame_global_flags *gfp;
/**********************************************************************
* 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];
#ifndef HAVEMPGLIB
fprintf(stderr,"Error: GTK frame analyzer requires MPGLIB\n");
exit(1);
#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*gfp->mode_gr;
pinfo->stereo = gfp->stereo;
if (gfp->input_format == sf_mp3) {
iread=lame_readframe(gfp,Buffer);
gfp->frameNum++;
}else {
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);
mp3count=lame_encode(gfp,Buffer,mp3buffer,sizeof(mp3buffer)); /* encode frame */
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 */
}
mp3out=lame_decode(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");
fprintf(stderr,"MP3x display of input and output PCM data out of sync.\n");
}
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;
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;
/*font = gdk_font_load ("-misc-fixed-medium-r-*-*-*-100-*-*-*-*-*-*");*/
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,"c1=%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) {
n = 224; /* number of points on end of blue part */
/* data left of frame */
gpk_graph_draw(pcmbox,n+1,xcord,ycord,xmn,ymn,xmx,ymx,0,title2,&black);
/* data right of frame */
gpk_graph_draw(pcmbox,n+1,&xcord[1152+n-1],&ycord[1152+n-1],
xmn,ymn,xmx,ymx,0,title2,&black);
/* the actual frame */
gpk_graph_draw(pcmbox,1152,&xcord[n],&ycord[n],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]);
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -