00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 # include <config.h>
00026 #endif
00027
00028 #include <gtk/gtk.h>
00029
00030 #include "main.h"
00031 #include "lame.h"
00032 #include "machine.h"
00033 #include "encoder.h"
00034 #include "lame-analysis.h"
00035 #include "get_audio.h"
00036 #include "gtkanal.h"
00037 #include "gpkplotting.h"
00038 #include "lame_global_flags.h"
00039
00040
00041
00042 #include "util.h"
00043
00044 #include "console.h"
00045
00046
00047 #ifdef _WIN32
00048 # include <windows.h>
00049 # define msleep(t) Sleep(t)
00050 #else
00051 # include <unistd.h>
00052 # define msleep(t) usleep((t) * 1000)
00053 #endif
00054
00055
00056
00057
00059 #define STR(x) #x
00060
00061 #define XSTR(x) STR(x)
00062
00063 #define MP3X_MAJOR_VERSION 0
00064 #define MP3X_MINOR_VERSION 82
00065 #define MP3X_ALPHA_VERSION 0
00066 #define MP3X_BETA_VERSION 0
00067
00068
00069 plotting_data *pinfo;
00070 plotting_data *pplot;
00071 plotting_data Pinfo[NUMPINFO];
00072
00073
00074
00075 static gint idle_keepgoing;
00076 static gint idle_count_max;
00077 static gint idle_count;
00078 static gint idle_end = 0;
00079 static gint idle_back = 0;
00080 static int mp3done = 0;
00081 static GtkWidget *frameprogress;
00082 static GtkWidget *framecounter;
00083
00084 static int subblock_draw[3] = { 1, 1, 1 };
00085
00086
00087 GtkWidget *window;
00088
00089 GtkWidget *pcmbox;
00090 GtkWidget *winbox;
00091 GtkWidget *enerbox[2];
00092 GtkWidget *mdctbox[2];
00093 GtkWidget *sfbbox[2];
00094 GtkWidget *headerbox;
00095
00096
00097 struct gtkinfostruct {
00098 int filetype;
00099 int msflag;
00100 int chflag;
00101 int kbflag;
00102 int flag123;
00103 double avebits;
00104 int approxbits;
00105 int maxbits;
00106 int totemph;
00107 int totms;
00108 int totis;
00109 int totshort;
00110 int totmix;
00111 int totpreflag;
00112 int pupdate;
00113 int sfblines;
00114 int difference;
00115 int totalframes;
00116 } gtkinfo;
00117
00118
00119 static lame_global_flags *gfp;
00120 lame_internal_flags *gfc;
00121
00122
00123
00124
00125 int
00126 gtkmakeframe(void)
00127 {
00128 int iread = 0;
00129 static int init = 0;
00130 static int mpglag;
00131 static short int Buffer[2][1152];
00132 short int mpg123pcm[2][1152];
00133 int ch, j;
00134 int mp3count = 0;
00135 int mp3out = 0;
00136 int channels_out;
00137 char mp3buffer[LAME_MAXMP3BUFFER];
00138 extern plotting_data *mpg123_pinfo;
00139 static int frameNum = 0;
00140 int framesize = lame_get_framesize(gfp);
00141
00142 channels_out = (lame_get_mode(gfp) == MONO) ? 1 : 2;
00143
00144 pinfo->frameNum = frameNum;
00145 pinfo->sampfreq = lame_get_out_samplerate(gfp);
00146 pinfo->framesize = framesize;
00147 pinfo->stereo = channels_out;
00148
00149
00150
00151
00152 gfc->pinfo = pinfo;
00153 mpg123_pinfo = pinfo;
00154
00155 if (is_mpeg_file_format(input_format)) {
00156 iread = get_audio16(gfp, Buffer);
00157
00158
00159
00160
00161 for (ch = 0; ch < channels_out; ch++) {
00162 for (j = 0; j < framesize - DECDELAY; j++)
00163 pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j + framesize];
00164 for (j = 0; j < framesize; j++)
00165 pinfo->pcmdata2[ch][j + framesize - DECDELAY] = Buffer[ch][j];
00166 }
00167
00168 pinfo->frameNum123 = frameNum - 1;
00169 ++frameNum;
00170
00171 }
00172 else {
00173
00174
00175 while (lame_get_frameNum(gfp) == pinfo->frameNum) {
00176
00177 if (!init) {
00178 init = 1;
00179 mpglag = 1;
00180 lame_decode_init();
00181 }
00182
00183 iread = get_audio16(gfp, Buffer);
00184 if (iread > framesize) {
00185
00186
00187
00188
00189
00190 error_printf("Warning: get_audio is returning too much data.\n");
00191 }
00192 if (iread <= 0)
00193 break;
00194
00195 mp3count = lame_encode_buffer(gfp, Buffer[0], Buffer[1], iread,
00196 mp3buffer, (int) sizeof(mp3buffer));
00197
00198 assert(!(mp3count > 0 && lame_get_frameNum(gfp) == pinfo->frameNum));
00199
00200
00201 }
00202 frameNum = lame_get_frameNum(gfp);
00203
00204
00205
00206 mp3out = lame_decode1(mp3buffer, mp3count, mpg123pcm[0], mpg123pcm[1]);
00207
00208
00209
00210 if (mp3out > 0)
00211 assert(mp3out == pinfo->framesize);
00212 if (mp3out != 0) {
00213
00214
00215
00216 pinfo->frameNum123 = pinfo->frameNum - mpglag;
00217 for (ch = 0; ch < pinfo->stereo; ch++) {
00218 for (j = 0; j < pinfo->framesize - DECDELAY; j++)
00219 pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j + pinfo->framesize];
00220 for (j = 0; j < pinfo->framesize; j++) {
00221 pinfo->pcmdata2[ch][j + pinfo->framesize - DECDELAY] =
00222 (mp3out == -1) ? 0 : mpg123pcm[ch][j];
00223 }
00224 }
00225 }
00226 else {
00227 if (mpglag == MAXMPGLAG) {
00228 error_printf("READ_AHEAD set too low - not enough frame buffering.\n"
00229 "MP3x display of input and output PCM data out of sync.\n");
00230 error_flush();
00231 }
00232 else
00233 mpglag++;
00234 pinfo->frameNum123 = -1;
00235 }
00236 }
00237 return iread;
00238 }
00239
00240
00241 void
00242 plot_frame(void)
00243 {
00244 int i, j, n, ch, gr;
00245 gdouble *xcord, *ycord;
00246 gdouble xmx, xmn, ymx, ymn;
00247 double *data, *data2, *data3;
00248 char title2[80];
00249 char label[80], label2[80];
00250 char *title;
00251 plotting_data *pplot1;
00252 plotting_data *pplot2 = NULL;
00253
00254 double en, samp;
00255 int sampindex, version = 0;
00256 int barthick;
00257 static int firstcall = 1;
00258 static GdkColor *barcolor, *color, *grcolor[2];
00259 static GdkColor yellow, gray, cyan, magenta, orange, pink, red, green, blue, black, oncolor,
00260 offcolor;
00261 int blocktype[2][2];
00262 int headbits;
00263 int mode_gr = 2;
00264
00265
00266
00267 for (i = 1; i <= MAXMPGLAG; i++) {
00268 if ((pplot - i)->frameNum123 == pplot->frameNum) {
00269 pplot2 = pplot - i;
00270 break;
00271 }
00272 }
00273 if (i > MAXMPGLAG) {
00274 error_printf("input/output pcm syncing problem. should not happen!\n");
00275 pplot2 = pplot - 1;
00276 }
00277
00278
00279
00280
00281
00282 pplot1 = pplot2 + 1;
00283
00284
00285 if (firstcall) {
00286 firstcall = 0;
00287
00288 grcolor[0] = &blue;
00289 grcolor[1] = &green;
00290 barcolor = &gray;
00291
00292 setcolor(headerbox, &oncolor, 255, 0, 0);
00293 setcolor(headerbox, &offcolor, 175, 175, 175);
00294 setcolor(pcmbox, &red, 255, 0, 0);
00295 setcolor(pcmbox, &pink, 255, 0, 255);
00296 setcolor(pcmbox, &magenta, 255, 0, 100);
00297 setcolor(pcmbox, &orange, 255, 127, 0);
00298 setcolor(pcmbox, &cyan, 0, 255, 255);
00299 setcolor(pcmbox, &green, 0, 255, 0);
00300 setcolor(pcmbox, &blue, 0, 0, 255);
00301 setcolor(pcmbox, &black, 0, 0, 0);
00302 setcolor(pcmbox, &gray, 100, 100, 100);
00303 setcolor(pcmbox, &yellow, 255, 255, 0);
00304
00305 }
00306
00307
00308
00309
00310 if (pplot1->sampfreq)
00311 samp = pplot1->sampfreq;
00312 else
00313 samp = 1;
00314 sampindex = SmpFrqIndex((long) samp, &version);
00315
00316 ch = gtkinfo.chflag;
00317
00318 headbits = 32 + ((pplot1->stereo == 2) ? 256 : 136);
00319 gtkinfo.approxbits = (pplot1->bitrate * 1000 * 1152.0 / samp) - headbits;
00320 sprintf(title2, "%3.1fkHz %ikbs ", samp / 1000, pplot1->bitrate);
00321 gtk_text_freeze(GTK_TEXT(headerbox));
00322 gtk_text_backward_delete(GTK_TEXT(headerbox), gtk_text_get_length(GTK_TEXT(headerbox)));
00323 gtk_text_set_point(GTK_TEXT(headerbox), 0);
00324 gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title2, -1);
00325 title = " mono ";
00326 if (2 == pplot1->stereo)
00327 title = pplot1->js ? " js " : " s ";
00328 gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title, -1);
00329 color = pplot1->ms_stereo ? &oncolor : &offcolor;
00330 gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "ms ", -1);
00331 color = pplot1->i_stereo ? &oncolor : &offcolor;
00332 gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "is ", -1);
00333
00334 color = pplot1->crc ? &oncolor : &offcolor;
00335 gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "crc ", -1);
00336 color = pplot1->padding ? &oncolor : &offcolor;
00337 gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "pad ", -1);
00338
00339 color = pplot1->emph ? &oncolor : &offcolor;
00340 gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "em ", -1);
00341
00342 sprintf(title2, "bv=%i,%i ", pplot1->big_values[0][ch], pplot1->big_values[1][ch]);
00343 gtk_text_insert(GTK_TEXT(headerbox), NULL, &black, NULL, title2, -1);
00344
00345 color = pplot1->scfsi[ch] ? &oncolor : &offcolor;
00346 sprintf(title2, "scfsi=%i ", pplot1->scfsi[ch]);
00347 gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, title2, -1);
00348 if (gtkinfo.filetype)
00349 sprintf(title2, " mdb=%i %i/NA", pplot1->maindata, pplot1->totbits);
00350 else
00351 sprintf(title2, " mdb=%i %i/%i",
00352 pplot1->maindata, pplot1->totbits, pplot1->totbits + pplot->resvsize);
00353 gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title2, -1);
00354 gtk_text_thaw(GTK_TEXT(headerbox));
00355
00356
00357
00358
00359
00360
00361 for (gr = 0; gr < mode_gr; gr++)
00362 if (gtkinfo.flag123)
00363 blocktype[gr][ch] = pplot1->mpg123blocktype[gr][ch];
00364 else
00365 blocktype[gr][ch] = pplot->blocktype[gr][ch];
00366
00367
00368
00369
00370
00371 n = 1600;
00372 xcord = g_malloc(n * sizeof(gdouble));
00373 ycord = g_malloc(n * sizeof(gdouble));
00374
00375
00376 if (gtkinfo.msflag)
00377 title = ch ? "Side Channel" : "Mid Channel";
00378 else
00379 title = ch ? "Right Channel" : "Left Channel";
00380
00381 sprintf(title2, "%s mask_ratio=%3.2f %3.2f ener_ratio=%3.2f %3.2f",
00382 title,
00383 pplot->ms_ratio[0], pplot->ms_ratio[1],
00384 pplot->ms_ener_ratio[0], pplot->ms_ener_ratio[1]);
00385
00386
00387 ymn = -32767;
00388 ymx = 32767;
00389 xmn = 0;
00390 xmx = 1600 - 1;
00391
00392
00393
00394
00395
00396
00397
00398 gpk_graph_draw(pcmbox, 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title2, &black);
00399
00400
00401
00402 ycord[0] = ymx * .8;
00403 ycord[1] = ymn * .8;
00404 for (gr = 0; gr <= 2; gr++) {
00405 xcord[0] = 223.5 + gr * 576;
00406 xcord[1] = 223.5 + gr * 576;
00407 gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
00408 }
00409 for (gr = 0; gr < mode_gr; gr++) {
00410 if (blocktype[gr][ch] == 2)
00411 for (i = 1; i <= 2; i++) {
00412 xcord[0] = 223.5 + gr * 576 + i * 192;
00413 xcord[1] = 223.5 + gr * 576 + i * 192;
00414 gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
00415 }
00416 }
00417
00418 xcord[0] = 0;
00419 ycord[0] = ymn + 3000;
00420 xcord[1] = 1024 - 1;
00421 ycord[1] = ymn + 1000;
00422 gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, grcolor[0]);
00423 xcord[0] = 576;
00424 ycord[0] = ymn + 2000;
00425 xcord[1] = 576 + 1024 - 1;
00426 ycord[1] = ymn;
00427 gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, grcolor[1]);
00428
00429
00430
00431 for (i = 0; i < n; i++) {
00432 xcord[i] = i;
00433 if (gtkinfo.msflag)
00434 ycord[i] = ch ? .5 * (pplot->pcmdata[0][i] - pplot->pcmdata[1][i]) :
00435 .5 * (pplot->pcmdata[0][i] + pplot->pcmdata[1][i]);
00436 else
00437 ycord[i] = pplot->pcmdata[ch][i];
00438 }
00439
00440
00441 if (!gtkinfo.filetype) {
00442 gpk_graph_draw(pcmbox, n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title2, &black);
00443 }
00444
00445
00446
00447
00448
00449 n = 1152;
00450
00451
00452
00453
00454
00455 title = "Re-synthesis";
00456 if (gtkinfo.difference)
00457 title = "Re-synthesis difference (amplified 20db)";
00458
00459
00460 ymn = -32767;
00461 ymx = 32767;
00462 xmn = 0;
00463 xmx = 1600 - 1;
00464 gpk_graph_draw(winbox, 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title, &black);
00465
00466 ycord[0] = ymx * .8;
00467 ycord[1] = ymn * .8;
00468 for (gr = 0; gr <= 2; gr++) {
00469 xcord[0] = 223.5 + gr * 576;
00470 xcord[1] = 223.5 + gr * 576;
00471 gpk_rectangle_draw(winbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
00472 }
00473 for (gr = 0; gr < 2; gr++) {
00474 if (blocktype[gr][ch] == 2)
00475 for (i = 1; i <= 2; i++) {
00476 xcord[0] = 223.5 + gr * 576 + i * 192;
00477 xcord[1] = 223.5 + gr * 576 + i * 192;
00478 gpk_rectangle_draw(winbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
00479 }
00480 }
00481
00482
00483 n = 224;
00484 for (j = 1152 - n, i = 0; i < n; i++, j++) {
00485 xcord[i] = i;
00486 if (gtkinfo.msflag)
00487 ycord[i] = ch ? .5 * (pplot1->pcmdata2[0][j] -
00488 pplot1->pcmdata2[1][j]) :
00489 .5 * (pplot1->pcmdata2[0][j] + pplot1->pcmdata2[1][j]);
00490 else
00491 ycord[i] = pplot1->pcmdata2[ch][j];
00492 }
00493
00494
00495 n = 1152;
00496 for (i = 0; i < n; i++) {
00497 xcord[i + 224] = i + 224;
00498 if (gtkinfo.msflag)
00499 ycord[i + 224] = ch ? .5 * (pplot2->pcmdata2[0][i] - pplot2->pcmdata2[1][i]) :
00500 .5 * (pplot2->pcmdata2[0][i] + pplot2->pcmdata2[1][i]);
00501 else
00502 ycord[i + 224] = pplot2->pcmdata2[ch][i];
00503 }
00504
00505 n = 1152 + 224;
00506 if (gtkinfo.difference) {
00507 for (i = 0; i < n; i++) {
00508 if (gtkinfo.msflag)
00509 ycord[i] -= ch ? .5 * (pplot->pcmdata[0][i] - pplot->pcmdata[1][i]) :
00510 .5 * (pplot->pcmdata[0][i] + pplot->pcmdata[1][i]);
00511 else
00512 ycord[i] -= pplot->pcmdata[ch][i];
00513 }
00514 ycord[i] *= 100;
00515 }
00516
00517
00518 gpk_graph_draw(winbox, n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title, &black);
00519
00520
00521
00522
00523
00524
00525
00526
00527 for (gr = 0; gr < mode_gr; gr++) {
00528 int bits, bits2;
00529 char *blockname = "";
00530 switch (blocktype[gr][ch]) {
00531 case 0:
00532 blockname = "normal";
00533 break;
00534 case 1:
00535 blockname = "start";
00536 break;
00537 case 2:
00538 blockname = "short";
00539 break;
00540 case 3:
00541 blockname = "end";
00542 break;
00543 }
00544 strcpy(label, blockname);
00545 if (pplot1->mixed[gr][ch])
00546 strcat(label, "(mixed)");
00547
00548
00549
00550
00551 n = 576;
00552 if (gtkinfo.flag123) {
00553 data = pplot1->mpg123xr[gr][0];
00554 data2 = pplot1->mpg123xr[gr][1];
00555 }
00556 else {
00557 data = pplot->xr[gr][0];
00558 data2 = pplot->xr[gr][1];
00559 }
00560
00561
00562 xmn = 0;
00563 xmx = n - 1;
00564 ymn = 0;
00565 ymx = 11;
00566
00567
00568 if (gtkinfo.flag123) {
00569 bits = pplot1->mainbits[gr][ch];
00570 bits2 = pplot1->sfbits[gr][ch];
00571 }
00572 else {
00573 bits = pplot->LAMEmainbits[gr][ch];
00574 bits2 = pplot->LAMEsfbits[gr][ch];
00575 }
00576 sprintf(title2, "MDCT%1i(%s) bits=%i/%i ", gr, label, bits, bits2);
00577 gpk_bargraph_draw(mdctbox[gr], 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title2, 0, barcolor);
00578
00579
00580 if (gtkinfo.sfblines) {
00581 int fac, nsfb, *scalefac;
00582 if (blocktype[gr][ch] == SHORT_TYPE) {
00583 nsfb = SBMAX_s;
00584 i = nsfb - 7;
00585 fac = 3;
00586 scalefac = gfc->scalefac_band.s;
00587 }
00588 else {
00589 nsfb = SBMAX_l;
00590 i = nsfb - 10;
00591 fac = 1;
00592 scalefac = gfc->scalefac_band.l;
00593 }
00594 for (; i < nsfb; i++) {
00595 ycord[0] = .8 * ymx;
00596 ycord[1] = ymn;
00597 xcord[0] = fac * scalefac[i];
00598 xcord[1] = xcord[0];
00599 gpk_rectangle_draw(mdctbox[gr], xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
00600 }
00601 }
00602
00603
00604
00605 ymn = 9e20;
00606 ymx = -9e20;
00607 for (i = 0; i < n; i++) {
00608 double coeff;
00609 xcord[i] = i;
00610 if (gtkinfo.msflag) {
00611 coeff = ch ? .5 * (data[i] - data2[i]) : .5 * (data[i] + data2[i]);
00612 }
00613 else {
00614 coeff = ch ? data2[i] : data[i];
00615 }
00616 if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
00617 coeff = 0;
00618 ycord[i] = coeff * coeff * 1e10;
00619 ycord[i] = log10(MAX(ycord[i], (double) 1));
00620
00621 #if 0
00622 if (ch == 0)
00623 if (i == 26)
00624 if (data[i] != 0)
00625 console_printf("%i %i i=%i mdct: (db) %f %f \n", pplot->frameNum, gr, i,
00626 10 * log10(data[i] * data[i]),
00627 10 * log10(.33 *
00628 (data[i - 1] * data[i - 1] + data[i] * data[i] +
00629 data[i + 1] * data[i + 1]))
00630 );
00631 #endif
00632
00633 ymx = (ycord[i] > ymx) ? ycord[i] : ymx;
00634 ymn = (ycord[i] < ymn) ? ycord[i] : ymn;
00635 }
00636
00637
00638
00639
00640 if (gtkinfo.flag123)
00641 bits = pplot1->mainbits[gr][ch];
00642 else
00643 bits = pplot->LAMEmainbits[gr][ch];
00644
00645
00646 sprintf(title2, "MDCT%1i(%s) bits=%i ", gr, label, bits);
00647
00648 xmn = 0;
00649 xmx = n - 1;
00650 ymn = 0;
00651 ymx = 11;
00652 gpk_bargraph_draw(mdctbox[gr], n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title2, 0, barcolor);
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662 if (gtkinfo.kbflag) {
00663 for (gr = 0; gr < mode_gr; gr++) {
00664 n = HBLKSIZE;
00665
00666 data = &pplot->energy[gr][ch][0];
00667
00668 ymn = 9e20;
00669 ymx = -9e20;
00670 for (i = 0; i < n; i++) {
00671 xcord[i] = i + 1;
00672 if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
00673 ycord[i] = 0;
00674 else
00675 ycord[i] = log10(MAX(data[i], (double) 1));
00676 ymx = (ycord[i] > ymx) ? ycord[i] : ymx;
00677 ymn = (ycord[i] < ymn) ? ycord[i] : ymn;
00678 }
00679 for (en = 0, j = 0; j < BLKSIZE; j++)
00680 en += pplot->energy[gr][ch][j];
00681
00682 sprintf(title2, "FFT%1i pe=%5.2fK en=%5.2e ", gr, pplot->pe[gr][ch] / 1000, en);
00683
00684 ymn = 3;
00685 ymx = 15;
00686 xmn = 1;
00687 xmx = n;
00688 gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
00689 xmn, ymn, xmx, ymx, 1, title2, 0, barcolor);
00690
00691 }
00692 }
00693 else {
00694
00695
00696
00697 for (gr = 0; gr < mode_gr; gr++) {
00698
00699 if (blocktype[gr][ch] == 2) {
00700 n = 3 * SBMAX_s;
00701 data = &pplot->en_s[gr][ch][0];
00702 data2 = &pplot->thr_s[gr][ch][0];
00703 data3 = &pplot->xfsf_s[gr][ch][0];
00704 }
00705 else {
00706 n = SBMAX_l;
00707 data = &pplot->en[gr][ch][0];
00708 data2 = &pplot->thr[gr][ch][0];
00709 data3 = &pplot->xfsf[gr][ch][0];
00710 }
00711 ymn = 9e20;
00712 ymx = -9e20;
00713 for (i = 0; i < n; i++) {
00714 xcord[i] = i + 1;
00715 if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
00716 ycord[i] = 0;
00717 else
00718 ycord[i] = log10(MAX(data[i], (double) 1));
00719
00720
00721
00722
00723 }
00724
00725
00726
00727
00728 en = pplot->ers[gr][ch];
00729 if (en > 999)
00730 en = 999;
00731 sprintf(title2,
00732 "FFT%1i pe=%5.2fK/%3.1f \nnoise ovr_b:%i/max:%3.1f/ovr:%3.1f/tot:%3.1f/ssd:%i",
00733 gr, pplot->pe[gr][ch] / 1000, en, pplot->over[gr][ch], pplot->max_noise[gr][ch],
00734 pplot->over_noise[gr][ch], pplot->tot_noise[gr][ch], pplot->over_SSD[gr][ch]);
00735
00736 barthick = 3;
00737 if (blocktype[gr][ch] == SHORT_TYPE)
00738 barthick = 2;
00739 if (!(subblock_draw[0] && subblock_draw[1] && subblock_draw[2]))
00740 barthick = 3;
00741
00742 ymn = 3;
00743 ymx = 15;
00744 xmn = 1;
00745 xmx = n + 1;
00746 gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
00747 xmn, ymn, xmx, ymx, 1, title2, barthick, barcolor);
00748
00749 for (i = 0; i < n; i++) {
00750 xcord[i] = i + 1 + .20;
00751 if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
00752 ycord[i] = 0;
00753 else
00754 ycord[i] = log10(MAX(data2[i], (double) 1));
00755 }
00756
00757 gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
00758 xmn, ymn, xmx, ymx, 0, title2, barthick, grcolor[gr]);
00759
00760 for (i = 0; i < n; i++) {
00761 xcord[i] = i + 1 + .40;
00762 if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
00763 ycord[i] = 0;
00764 else
00765 ycord[i] = log10(MAX(data3[i], (double) 1));
00766 }
00767 gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
00768 xmn, ymn, xmx, ymx, 0, title2, barthick, &red);
00769
00770 }
00771 }
00772
00773
00774
00775
00776 for (gr = 0; gr < mode_gr; gr++) {
00777 int ggain;
00778 if (blocktype[gr][ch] == 2) {
00779 n = 3 * SBMAX_s;
00780 if (gtkinfo.flag123)
00781 data = pplot1->sfb_s[gr][ch];
00782 else
00783 data = pplot->LAMEsfb_s[gr][ch];
00784 }
00785 else {
00786 n = SBMAX_l;
00787 if (gtkinfo.flag123)
00788 data = pplot1->sfb[gr][ch];
00789 else
00790 data = pplot->LAMEsfb[gr][ch];
00791 }
00792
00793 ymn = -1;
00794 ymx = 10;
00795 for (i = 0; i < n; i++) {
00796 xcord[i] = i + 1;
00797 if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
00798 ycord[i] = 0;
00799 else
00800 ycord[i] = -data[i];
00801
00802 ymx = (ycord[i] > ymx - 2) ? ycord[i] + 2 : ymx;
00803 ymn = (ycord[i] < ymn) ? ycord[i] - 1 : ymn;
00804 }
00805
00806 if (blocktype[gr][ch] == 2) {
00807 sprintf(label2,
00808 "SFB scale=%i preflag=%i %i%i%i",
00809 pplot1->scalefac_scale[gr][ch],
00810 pplot1->preflag[gr][ch],
00811 pplot1->sub_gain[gr][ch][0],
00812 pplot1->sub_gain[gr][ch][1], pplot1->sub_gain[gr][ch][2]);
00813 }
00814 else {
00815 sprintf(label2, "SFB scale=%i preflag=%i", pplot1->scalefac_scale[gr][ch],
00816 pplot1->preflag[gr][ch]);
00817 }
00818
00819 if (gtkinfo.flag123)
00820 ggain = (pplot1->qss[gr][ch]);
00821 else
00822 ggain = (pplot->LAMEqss[gr][ch]);
00823
00824 sprintf(title2, " ggain=%i", ggain);
00825 strcat(label2, title2);
00826
00827 xmn = 1;
00828 xmx = n + 1;
00829 gpk_bargraph_draw(sfbbox[gr], n, xcord, ycord,
00830 xmn, ymn, xmx, ymx, 1, label2, 0, grcolor[gr]);
00831
00832 ycord[0] = ycord[1] = 0;
00833 xcord[0] = 1;
00834 xcord[1] = n + 1;
00835 gpk_rectangle_draw(sfbbox[gr], xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
00836
00837
00838 }
00839
00840
00841 }
00842
00843
00844
00845 static void
00846 update_progress(void)
00847 {
00848 char label[80];
00849
00850 int tf = lame_get_totalframes(gfp);
00851 if (gtkinfo.totalframes > 0)
00852 tf = gtkinfo.totalframes;
00853
00854 sprintf(label, "Frame:%4i/%4i %6.2fs", pplot->frameNum, (int) tf - 1, pplot->frametime);
00855 gtk_progress_set_value(GTK_PROGRESS(frameprogress), (gdouble) pplot->frameNum);
00856 gtk_label_set_text(GTK_LABEL(framecounter), label);
00857 }
00858
00859
00860
00861 static void
00862 analyze(void)
00863 {
00864 if (idle_keepgoing) {
00865 idle_count = 0;
00866 idle_count_max = 0;
00867 idle_keepgoing = 0;
00868 idle_end = 0;
00869 }
00870 plot_frame();
00871 update_progress();
00872 }
00873
00874 static void
00875 plotclick(GtkWidget * widget, gpointer data)
00876 {
00877 analyze();
00878 }
00879
00880
00881
00882
00883 static int
00884 frameadv1(GtkWidget * widget, gpointer data)
00885 {
00886 int i;
00887 if (idle_keepgoing) {
00888 if (idle_back) {
00889
00890 idle_back--;
00891 pplot = &Pinfo[READ_AHEAD + idle_back];
00892 }
00893 else {
00894
00895 pplot = &Pinfo[READ_AHEAD];
00896 if (mp3done) {
00897
00898
00899 idle_count_max = 0;
00900 idle_end = 0;
00901 }
00902 else {
00903
00904 for (i = NUMPINFO - 1; i > 0; i--)
00905 memcpy(&Pinfo[i], &Pinfo[i - 1], sizeof(plotting_data));
00906 pinfo = &Pinfo[0];
00907 pinfo->num_samples = gtkmakeframe();
00908 if (pinfo->num_samples == 0 && gtkinfo.totalframes == 0)
00909
00910 gtkinfo.totalframes = pinfo->frameNum + 2;
00911
00912 if (pinfo->sampfreq)
00913 pinfo->frametime = (pinfo->frameNum) * 1152.0 / pinfo->sampfreq;
00914 else
00915 pinfo->frametime = 0;
00916
00917
00918
00919
00920
00921 pinfo->totbits = 0;
00922 {
00923 int gr, ch;
00924 for (gr = 0; gr < 2; gr++)
00925 for (ch = 0; ch < 2; ch++) {
00926 gtkinfo.totshort += (pinfo->mpg123blocktype[gr][ch] == 2);
00927 gtkinfo.totmix += !(pinfo->mixed[gr][ch] == 0);
00928 gtkinfo.totpreflag += (pinfo->preflag[gr][ch] == 1);
00929 pinfo->totbits += pinfo->mainbits[gr][ch];
00930 }
00931 }
00932 if (pinfo->frameNum > 0)
00933 gtkinfo.avebits = (gtkinfo.avebits * ((pinfo->frameNum) - 1)
00934 + pinfo->totbits) / (pinfo->frameNum);
00935
00936 gtkinfo.maxbits = MAX(gtkinfo.maxbits, pinfo->totbits);
00937 gtkinfo.totemph += !(pinfo->emph == 0);
00938 gtkinfo.totms += !(pinfo->ms_stereo == 0);
00939 gtkinfo.totis += !(pinfo->i_stereo == 0);
00940
00941 if (gtkinfo.totalframes > 0)
00942 if (pplot->frameNum >= gtkinfo.totalframes - 1)
00943 mp3done = 1;
00944 }
00945 }
00946
00947 idle_count++;
00948 if (gtkinfo.pupdate)
00949 plot_frame();
00950 update_progress();
00951 if ((idle_count >= idle_count_max) && (!idle_end))
00952 analyze();
00953 }
00954 else {
00955
00956 msleep(10);
00957 }
00958 return 1;
00959 }
00960
00961
00962 static void
00963 frameadv(GtkWidget * widget, gpointer data)
00964 {
00965 int adv;
00966
00967 if (!strcmp((char *) data, "-1")) {
00968
00969 if (pplot->frameNum == 0 || (idle_back == NUMBACK))
00970 return;
00971 idle_back++;
00972 pplot = &Pinfo[READ_AHEAD + idle_back];
00973 analyze();
00974 return;
00975 }
00976
00977
00978 adv = 1;
00979 if (!strcmp((char *) data, "1"))
00980 adv = 1;
00981 if (!strcmp((char *) data, "10"))
00982 adv = 10;
00983 if (!strcmp((char *) data, "100"))
00984 adv = 100;
00985 if (!strcmp((char *) data, "finish"))
00986 idle_end = 1;
00987
00988
00989 if (idle_keepgoing) {
00990
00991 idle_count_max += adv;
00992 }
00993 else {
00994
00995 idle_count_max = adv;
00996 idle_count = 0;
00997 idle_keepgoing = 1;
00998 }
00999 }
01000
01001
01002
01003
01004
01005 static void
01006 delete_event(GtkWidget * widget, GdkEvent * event, gpointer data)
01007 {
01008
01009 mp3done = 1;
01010
01011 gtk_main_quit();
01012 }
01013
01014
01015
01016
01017
01018
01019
01020 static void
01021 channel_option(GtkWidget * widget, gpointer data)
01022 {
01023 long option;
01024 option = (long) data;
01025 switch (option) {
01026 case 1:
01027 gtkinfo.msflag = 0;
01028 gtkinfo.chflag = 0;
01029 break;
01030 case 2:
01031 gtkinfo.msflag = 0;
01032 gtkinfo.chflag = 1;
01033 break;
01034 case 3:
01035 gtkinfo.msflag = 1;
01036 gtkinfo.chflag = 0;
01037 break;
01038 case 4:
01039 gtkinfo.msflag = 1;
01040 gtkinfo.chflag = 1;
01041 }
01042 analyze();
01043 }
01044 static void
01045 spec_option(GtkWidget * widget, gpointer data)
01046 {
01047 long option;
01048 option = (long) data;
01049 switch (option) {
01050 case 1:
01051 gtkinfo.kbflag = 0;
01052 break;
01053 case 2:
01054 gtkinfo.kbflag = 1;
01055 break;
01056 case 3:
01057 gtkinfo.flag123 = 0;
01058 break;
01059 case 4:
01060 gtkinfo.flag123 = 1;
01061 break;
01062 case 5:
01063 gtkinfo.pupdate = 1;
01064 break;
01065 case 6:
01066 gtkinfo.pupdate = 0;
01067 break;
01068 case 7:
01069 gtkinfo.sfblines = !gtkinfo.sfblines;
01070 break;
01071 case 8:
01072 gtkinfo.difference = !gtkinfo.difference;
01073 break;
01074 }
01075 analyze();
01076 }
01077
01078 static gint
01079 key_press_event(GtkWidget * widget, GdkEventKey * event)
01080 {
01081
01082 if (event->keyval == '1') {
01083 subblock_draw[0] = 1;
01084 subblock_draw[1] = 0;
01085 subblock_draw[2] = 0;
01086 analyze();
01087 }
01088 else if (event->keyval == '2') {
01089 subblock_draw[0] = 0;
01090 subblock_draw[1] = 1;
01091 subblock_draw[2] = 0;
01092 analyze();
01093 }
01094 else if (event->keyval == '3') {
01095 subblock_draw[0] = 0;
01096 subblock_draw[1] = 0;
01097 subblock_draw[2] = 1;
01098 analyze();
01099 }
01100 else if (event->keyval == '0') {
01101 subblock_draw[0] = 1;
01102 subblock_draw[1] = 1;
01103 subblock_draw[2] = 1;
01104 analyze();
01105 }
01106
01107 return 0;
01108 }
01109
01110
01116 const char *
01117 get_mp3x_version(void)
01118 {
01119 #if MP3X_ALPHA_VERSION > 0
01120 static const char *const str =
01121 XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION)
01122 " (alpha " XSTR(MP3X_ALPHA_VERSION) ", " __DATE__ " " __TIME__ ")";
01123 #elif MP3X_BETA_VERSION > 0
01124 static const char *const str =
01125 XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION)
01126 " (beta " XSTR(MP3X_BETA_VERSION) ", " __DATE__ ")";
01127 #else
01128 static const char *const str =
01129 XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION);
01130 #endif
01131
01132 return str;
01133 }
01134
01135
01136 static void
01137 text_window(GtkWidget * widget, gpointer data)
01138 {
01139 long option;
01140 GtkWidget *hbox, *vbox, *button, *box;
01141 GtkWidget *textwindow, *vscrollbar;
01142 char text[256];
01143
01144 option = (long) data;
01145
01146 textwindow = gtk_window_new(GTK_WINDOW_DIALOG);
01147 gtk_signal_connect_object(GTK_OBJECT(window), "delete_event",
01148 GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(textwindow));
01149
01150 gtk_container_set_border_width(GTK_CONTAINER(textwindow), 0);
01151 vbox = gtk_vbox_new(FALSE, 0);
01152 hbox = gtk_hbox_new(FALSE, 0);
01153
01154 button = gtk_button_new_with_label("close");
01155 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
01156 GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(textwindow));
01157
01158 box = gtk_text_new(NULL, NULL);
01159 gtk_text_set_editable(GTK_TEXT(box), FALSE);
01160 vscrollbar = gtk_vscrollbar_new(GTK_TEXT(box)->vadj);
01161
01162
01163 switch (option) {
01164 case 0:
01165 gtk_window_set_title(GTK_WINDOW(textwindow), "Documentation");
01166 gtk_widget_set_usize(box, 450, 500);
01167 gtk_text_set_word_wrap(GTK_TEXT(box), TRUE);
01168
01169 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
01170 "Frame header information: "
01171 "First the bitrate, sampling frequency and mono, stereo or jstereo "
01172 "indicators are displayed . If the bitstream is jstereo, then mid/side "
01173 "stereo or intensity stereo may be on (indicated in red). If "
01174 "de-emphasis is used, this is also indicated in red. The mdb value is "
01175 "main_data_begin. The encoded data starts this many bytes *before* the "
01176 "frame header. A large value of mdb means the bitstream has saved some "
01177 "bits into the reservoir, which it may allocate for some future frame. "
01178 "The two numbers after mdb are the size (in bits) used to encode the "
01179 "MDCT coefficients for this frame, followed byt the size of the bit "
01180 "resevoir before encoding this frame. The maximum frame size and a "
01181 "running average are given in the Stats pull down menu. A large "
01182 "maximum frame size indicates the bitstream has made use of the bit "
01183 "reservoir. \n\n", -1);
01184
01185 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
01186 "PCM data (top graph): "
01187 "The PCM data is plotted in black. The layer3 frame is divided into 2 "
01188 "granules of 576 samples (marked with yellow vertical lines). In the "
01189 "case of normal, start and stop blocks, the MDCT coefficients for each "
01190 "granule are computed using a 1152 sample window centered over the "
01191 "granule. In the case of short blocks, the granule is further divided "
01192 "into 3 blocks of 192 samples (also marked with yellow vertical lines)."
01193 "The MDCT coefficients for these blocks are computed using 384 sample "
01194 "windows centered over the 192 sample window. (This info not available "
01195 "when analyzing .mp3 files.) For the psycho-acoustic model, a windowed "
01196 "FFT is computed for each granule. The range of these windows "
01197 "is denoted by the blue and green bars.\n\n", -1);
01198
01199 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
01200 "PCM re-synthesis data (second graph): "
01201 "Same as the PCM window described above. The data displayed is the "
01202 "result of encoding and then decoding the original sample. \n\n", -1);
01203
01204 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
01205 "MDCT windows: "
01206 "Shows the energy in the MDCT spectrum for granule 0 (left window) "
01207 "and granule 1 (right window). The text also shows the blocktype "
01208 "used, the number of bits used to encode the coefficients and the "
01209 "number of extra bits allocated from the reservoir. The MDCT pull down "
01210 "window will toggle between the original unquantized MDCT coefficients "
01211 "and the compressed (quantized) coefficients.\n\n", -1);
01212
01213 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
01214 "FFT window: "
01215 "The gray bars show the energy in the FFT spectrum used by the "
01216 "psycho-acoustic model. Granule 0 is in the left window, granule 1 in "
01217 "the right window. The green and blue bars show how much distortion is "
01218 "allowable, as computed by the psycho-acoustic model. The red bars show "
01219 "the actual distortion after encoding. There is one FFT for each "
01220 "granule, computed with a 1024 Hann window centered over the "
01221 "appropriate granule. (the range of this 1024 sample window is shown "
01222 "by the blue and green bars in the PCM data window). The Spectrum pull "
01223 "down window will toggle between showing the energy in equally spaced "
01224 "frequency domain and the scale factor bands used by layer3. Finally, "
01225 "the perceptual entropy, total energy and number of scalefactor bands "
01226 "with audible distortion is shown. (This info not available when "
01227 "analyzing .mp3 files.)", -1);
01228
01229 break;
01230 case 1:
01231
01232 gtk_window_set_title(GTK_WINDOW(textwindow), "About");
01233 gtk_widget_set_usize(box, 350, 260);
01234
01235 sprintf(text, "LAME version %s \n%s\n\n", get_lame_version(), get_lame_url());
01236 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01237
01238 sprintf(text, "psycho-acoustic model: GPSYCHO version %s\n", get_psy_version());
01239 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01240
01241 sprintf(text, "frame analyzer: MP3x version %s\n\n", get_mp3x_version());
01242 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01243
01244 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
01245 "decoder: mpg123/mpglib .59q \nMichael Hipp (www.mpg123.de)\n\n", -1);
01246
01247 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
01248 "Encoder, decoder & psy-models based on ISO\ndemonstration source. ", -1);
01249 break;
01250
01251 case 2:
01252 gtk_window_set_title(GTK_WINDOW(textwindow), "Statistics");
01253 gtk_widget_set_usize(box, 350, 260);
01254 sprintf(text, "frames processed so far: %i \n", Pinfo[0].frameNum + 1);
01255 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01256 sprintf(text, "granules processed so far: %i \n\n", 4 * (Pinfo[0].frameNum + 1));
01257 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01258 sprintf(text, "mean bits/frame (approximate): %i\n", gtkinfo.approxbits);
01259 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01260 sprintf(text, "mean bits/frame (from LAME): %i\n", 4 * Pinfo[0].mean_bits);
01261 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01262 sprintf(text, "bitsize of largest frame: %i \n", gtkinfo.maxbits);
01263 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01264 sprintf(text, "average bits/frame: %3.1f \n\n", gtkinfo.avebits);
01265 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01266 sprintf(text, "ms_stereo frames: %i \n", gtkinfo.totms);
01267 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01268 sprintf(text, "i_stereo frames: %i \n", gtkinfo.totis);
01269 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01270 sprintf(text, "de-emphasis frames: %i \n", gtkinfo.totemph);
01271 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01272 sprintf(text, "short block granules: %i \n", gtkinfo.totshort);
01273 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01274 sprintf(text, "mixed block granules: %i \n", gtkinfo.totmix);
01275 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01276 sprintf(text, "preflag granules: %i \n", gtkinfo.totpreflag);
01277 gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
01278 break;
01279 }
01280
01281
01282
01283 gtk_widget_show(vscrollbar);
01284 gtk_widget_show(box);
01285 gtk_widget_show(vbox);
01286 gtk_widget_show(hbox);
01287 gtk_widget_show(button);
01288
01289 gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, TRUE, 0);
01290 gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
01291 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
01292 gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, TRUE, 0);
01293 gtk_container_add(GTK_CONTAINER(textwindow), vbox);
01294 gtk_widget_show(textwindow);
01295
01296 }
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328 #define C(chr) "<control>" #chr
01329 #define func(name) (GtkItemFactoryCallback) (name)
01330
01331 static const GtkItemFactoryEntry menu_items[] = {
01332 {"/_File", NULL, NULL, 0, "<Branch>"},
01333 #if 0
01334 {"/File/_New", C(N), func(print_hello), 0, NULL},
01335 {"/File/_Open", C(O), func(print_hello), 0, NULL},
01336 {"/File/_Save", C(S), func(print_hello), 0, NULL},
01337 {"/File/Save _As", NULL, NULL, 0, NULL},
01338 {"/File/sep1", NULL, NULL, 0, "<Separator>"},
01339 {"/File/Quit", C(Q), func(gtk_main_quit), 0, NULL},
01340 #endif
01341 {"/File/_Quit", C(Q), func(delete_event), 0, NULL},
01342
01343 {"/_Plotting", NULL, NULL, 0, "<Branch>"},
01344 {"/Plotting/_While advancing", NULL, func(spec_option), 5, NULL},
01345 {"/Plotting/_After advancing", NULL, func(spec_option), 6, NULL},
01346 {"/Plotting/Toggle SFB lines", NULL, func(spec_option), 7, NULL},
01347 {"/Plotting/Toggle orig-diff", NULL, func(spec_option), 8, NULL},
01348
01349 {"/_Channel", NULL, NULL, 0, "<Branch>"},
01350 {"/Channel/show _Left", NULL, func(channel_option), 1, NULL},
01351 {"/Channel/show _Right", NULL, func(channel_option), 2, NULL},
01352 {"/Channel/show _Mid", NULL, func(channel_option), 3, NULL},
01353 {"/Channel/show _Side", NULL, func(channel_option), 4, NULL},
01354
01355 {"/_Spectrum", NULL, NULL, 0, "<Branch>"},
01356 {"/Spectrum/_Scalefactor bands", NULL, func(spec_option), 1, NULL},
01357 {"/Spectrum/_Wave number", NULL, func(spec_option), 2, NULL},
01358
01359 {"/_MDCT", NULL, NULL, 0, "<Branch>"},
01360 {"/MDCT/_Original", NULL, func(spec_option), 3, NULL},
01361 {"/MDCT/_Compressed", NULL, func(spec_option), 4, NULL},
01362 {"/MDCT/_Toggle SFB lines", NULL, func(spec_option), 7, NULL},
01363
01364 {"/_Stats", NULL, NULL, 0, "<Branch>"},
01365 {"/Stats/_Show", NULL, func(text_window), 2, NULL},
01366
01367 {"/_Help", NULL, NULL, 0, "<LastBranch>"},
01368 {"/_Help/_Documentation", NULL, func(text_window), 0, NULL},
01369 {"/_Help/_About", NULL, func(text_window), 1, NULL},
01370 };
01371
01372 #undef C
01373 #undef func
01374
01375
01376 static void
01377 get_main_menu(GtkWidget * windows, GtkWidget ** menubar)
01378 {
01379 unsigned int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
01380 GtkItemFactory *item_factory;
01381 GtkAccelGroup *accel_group;
01382
01383 accel_group = gtk_accel_group_new();
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393 item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
01394
01395
01396
01397
01398 gtk_item_factory_create_items(item_factory, nmenu_items, (GtkItemFactoryEntry *) menu_items,
01399 NULL);
01400
01401
01402 gtk_accel_group_attach(accel_group, GTK_OBJECT(windows));
01403
01404 if (menubar)
01405
01406 *menubar = gtk_item_factory_get_widget(item_factory, "<main>");
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424 int
01425 gtkcontrol(lame_global_flags * gfp2, char *inPath)
01426 {
01427
01428 GtkWidget *button;
01429 GtkAdjustment *adj;
01430 GtkWidget *mbox;
01431 GtkWidget *box1;
01432 GtkWidget *box2;
01433 GtkWidget *box3;
01434 GtkWidget *table;
01435 GtkWidget *menubar;
01436
01437 gint tableops, graphx, graphy;
01438 char frameinfo[80];
01439
01440 graphx = 600;
01441 graphy = 95;
01442
01443 gfp = gfp2;
01444 gfc = gfp->internal_flags;
01445
01446
01447 gtkinfo.filetype = is_mpeg_file_format(input_format) ? 1 : 0;
01448 gtkinfo.msflag = 0;
01449 gtkinfo.chflag = 0;
01450 gtkinfo.kbflag = 0;
01451 gtkinfo.flag123 = is_mpeg_file_format(input_format) ? 1 : 0;
01452 gtkinfo.pupdate = 0;
01453 gtkinfo.avebits = 0;
01454 gtkinfo.maxbits = 0;
01455 gtkinfo.approxbits = 0;
01456 gtkinfo.totemph = 0;
01457 gtkinfo.totms = 0;
01458 gtkinfo.totis = 0;
01459 gtkinfo.totshort = 0;
01460 gtkinfo.totmix = 0;
01461 gtkinfo.sfblines = 1;
01462 gtkinfo.difference = 0;
01463 gtkinfo.totalframes = 0;
01464
01465 memset((char *) Pinfo, 0, sizeof(Pinfo));
01466 pplot = &Pinfo[READ_AHEAD];
01467
01468 strcpy(frameinfo, "MP3x: ");
01469 strncat(frameinfo, inPath, 70);
01470
01471 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
01472 gtk_window_set_title(GTK_WINDOW(window), frameinfo);
01473 gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL);
01474
01475 gtk_signal_connect_object(GTK_OBJECT(window), "key_press_event",
01476 GTK_SIGNAL_FUNC(key_press_event), GTK_OBJECT(window));
01477
01478 gtk_container_set_border_width(GTK_CONTAINER(window), 0);
01479
01480
01481 mbox = gtk_vbox_new(FALSE, 0);
01482
01483
01484
01485 box1 = gtk_hbox_new(FALSE, 0);
01486 box2 = gtk_hbox_new(FALSE, 0);
01487 box3 = gtk_hbox_new(FALSE, 0);
01488 table = gtk_table_new(5, 2, FALSE);
01489 tableops = GTK_FILL | GTK_EXPAND | GTK_SHRINK;
01490 get_main_menu(window, &menubar);
01491
01492 gtk_box_pack_start(GTK_BOX(mbox), menubar, FALSE, TRUE, 0);
01493 gtk_box_pack_end(GTK_BOX(mbox), box1, FALSE, TRUE, 0);
01494 gtk_box_pack_end(GTK_BOX(mbox), box2, FALSE, TRUE, 0);
01495 gtk_box_pack_start(GTK_BOX(mbox), box3, FALSE, TRUE, 0);
01496 gtk_box_pack_start(GTK_BOX(mbox), table, TRUE, TRUE, 0);
01497 gtk_container_add(GTK_CONTAINER(window), mbox);
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507 headerbox = gtk_text_new(NULL, NULL);
01508 gtk_text_set_editable(GTK_TEXT(headerbox), FALSE);
01509 gtk_widget_set_usize(headerbox, 200, 20);
01510 gtk_widget_show(headerbox);
01511 gtk_box_pack_start(GTK_BOX(box3), headerbox, TRUE, TRUE, 0);
01512
01513
01514
01515
01516
01517
01518 framecounter = gtk_label_new("");
01519 gtk_widget_show(framecounter);
01520 gtk_box_pack_start(GTK_BOX(box2), framecounter, FALSE, TRUE, 0);
01521
01522 adj = (GtkAdjustment *) gtk_adjustment_new(0, 0, (gint) lame_get_totalframes(gfp) - 1, 0, 0, 0);
01523 frameprogress = gtk_progress_bar_new_with_adjustment(adj);
01524
01525
01526
01527
01528
01529
01530 gtk_progress_set_format_string(GTK_PROGRESS(frameprogress), "%p%%");
01531 gtk_progress_set_value(GTK_PROGRESS(frameprogress), (gdouble) 0);
01532 gtk_progress_set_show_text(GTK_PROGRESS(frameprogress), TRUE);
01533 gtk_widget_show(frameprogress);
01534 gtk_box_pack_end(GTK_BOX(box2), frameprogress, FALSE, TRUE, 0);
01535
01536
01537
01538
01539
01540
01541 button = gtk_button_new_with_label("-1");
01542 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "-1");
01543 gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
01544 gtk_widget_show(button);
01545
01546 button = gtk_button_new_with_label("+1");
01547 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "1");
01548 gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
01549 gtk_widget_show(button);
01550
01551 button = gtk_button_new_with_label("+10");
01552 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "10");
01553 gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
01554 gtk_widget_show(button);
01555
01556 button = gtk_button_new_with_label("+100");
01557 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "100");
01558 gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
01559 gtk_widget_show(button);
01560
01561 button = gtk_button_new_with_label("last frame");
01562 gtk_signal_connect(GTK_OBJECT(button), "clicked",
01563 GTK_SIGNAL_FUNC(frameadv), (gpointer) "finish");
01564 gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
01565 gtk_widget_show(button);
01566
01567 button = gtk_button_new_with_label("stop/plot");
01568 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(plotclick), NULL);
01569 gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
01570 gtk_widget_show(button);
01571
01572
01573
01574
01575
01576 pcmbox = gpk_plot_new(graphx, graphy);
01577 gtk_table_attach(GTK_TABLE(table), pcmbox, 0, 2, 0, 1, tableops, tableops, 2, 2);
01578 gtk_widget_show(pcmbox);
01579
01580 winbox = gpk_plot_new(graphy, graphy);
01581 gtk_table_attach(GTK_TABLE(table), winbox, 0, 2, 1, 2, tableops, tableops, 2, 2);
01582 gtk_widget_show(winbox);
01583
01584
01585 mdctbox[0] = gpk_plot_new(graphy, graphy);
01586 gtk_table_attach(GTK_TABLE(table), mdctbox[0], 0, 1, 2, 3, tableops, tableops, 2, 2);
01587 gtk_widget_show(mdctbox[0]);
01588
01589 mdctbox[1] = gpk_plot_new(graphy, graphy);
01590 gtk_table_attach(GTK_TABLE(table), mdctbox[1], 1, 2, 2, 3, tableops, tableops, 2, 2);
01591 gtk_widget_show(mdctbox[1]);
01592
01593 enerbox[0] = gpk_plot_new(graphy, graphy);
01594 gtk_table_attach(GTK_TABLE(table), enerbox[0], 0, 1, 3, 4, tableops, tableops, 2, 2);
01595 gtk_widget_show(enerbox[0]);
01596
01597 enerbox[1] = gpk_plot_new(graphy, graphy);
01598 gtk_table_attach(GTK_TABLE(table), enerbox[1], 1, 2, 3, 4, tableops, tableops, 2, 2);
01599 gtk_widget_show(enerbox[1]);
01600
01601 sfbbox[0] = gpk_plot_new(graphy, graphy);
01602 gtk_table_attach(GTK_TABLE(table), sfbbox[0], 0, 1, 4, 5, tableops, tableops, 2, 2);
01603 gtk_widget_show(sfbbox[0]);
01604
01605 sfbbox[1] = gpk_plot_new(graphy, graphy);
01606 gtk_table_attach(GTK_TABLE(table), sfbbox[1], 1, 2, 4, 5, tableops, tableops, 2, 2);
01607 gtk_widget_show(sfbbox[1]);
01608
01609
01610
01611
01612 gtk_idle_add((GtkFunction) frameadv1, NULL);
01613 gtk_widget_show(menubar);
01614 gtk_widget_show(box2);
01615 gtk_widget_show(box3);
01616 gtk_widget_show(table);
01617 gtk_widget_show(box1);
01618 gtk_widget_show(mbox);
01619 gtk_widget_show(window);
01620
01621
01622
01623
01624
01625
01626
01627
01628 idle_keepgoing = 1;
01629 idle_count_max = READ_AHEAD + 1;
01630 idle_count = 0;
01631
01632 gtk_main();
01633 assert(mp3done);
01634 return (0);
01635 }