Blame frontend/gtkanal.c

Packit 47f805
/*
Packit 47f805
 *      GTK plotting routines source file
Packit 47f805
 *
Packit 47f805
 *      Copyright (c) 1999 Mark Taylor
Packit 47f805
 *
Packit 47f805
 * This library is free software; you can redistribute it and/or
Packit 47f805
 * modify it under the terms of the GNU Library General Public
Packit 47f805
 * License as published by the Free Software Foundation; either
Packit 47f805
 * version 2 of the License, or (at your option) any later version.
Packit 47f805
 *
Packit 47f805
 * This library is distributed in the hope that it will be useful,
Packit 47f805
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 47f805
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 47f805
 * Library General Public License for more details.
Packit 47f805
 *
Packit 47f805
 * You should have received a copy of the GNU Library General Public
Packit 47f805
 * License along with this library; if not, write to the
Packit 47f805
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 47f805
 * Boston, MA 02111-1307, USA.
Packit 47f805
 */
Packit 47f805
Packit 47f805
/* $Id: gtkanal.c,v 1.50 2017/08/28 12:48:39 robert Exp $ */
Packit 47f805
Packit 47f805
#ifdef HAVE_CONFIG_H
Packit 47f805
# include <config.h>
Packit 47f805
#endif
Packit 47f805
Packit 47f805
#include <gtk/gtk.h>
Packit 47f805
Packit 47f805
#include "main.h"
Packit 47f805
#include "lame.h"
Packit 47f805
#include "machine.h"
Packit 47f805
#include "encoder.h"
Packit 47f805
#include "lame-analysis.h"
Packit 47f805
#include "get_audio.h"
Packit 47f805
#include "gtkanal.h"
Packit 47f805
#include "gpkplotting.h"
Packit 47f805
#include "lame_global_flags.h"
Packit 47f805
Packit 47f805
/* this file should be removed. The few data items accessed in 'gfc'
Packit 47f805
   should be made accessable by writing a lame_set_variable() function */
Packit 47f805
#include "util.h"
Packit 47f805
Packit 47f805
#include "console.h"
Packit 47f805
Packit 47f805
Packit 47f805
#ifdef _WIN32
Packit 47f805
#  include <windows.h>
Packit 47f805
#  define msleep(t) Sleep(t)
Packit 47f805
#else
Packit 47f805
#  include <unistd.h>
Packit 47f805
#  define msleep(t) usleep((t) * 1000)
Packit 47f805
#endif
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/*! Stringify \a x. */
Packit 47f805
#define STR(x)   #x
Packit 47f805
/*! Stringify \a x, perform macro expansion. */
Packit 47f805
#define XSTR(x)  STR(x)
Packit 47f805
Packit 47f805
#define MP3X_MAJOR_VERSION      0 /* Major version number */
Packit 47f805
#define MP3X_MINOR_VERSION     82 /* Minor version number */
Packit 47f805
#define MP3X_ALPHA_VERSION      0 /* Set number if this is an alpha version, otherwise zero */
Packit 47f805
#define MP3X_BETA_VERSION       0 /* Set number if this is a beta version, otherwise zero */
Packit 47f805
Packit 47f805
Packit 47f805
plotting_data *pinfo;
Packit 47f805
plotting_data *pplot;
Packit 47f805
plotting_data Pinfo[NUMPINFO];
Packit 47f805
Packit 47f805
Packit 47f805
/* global variables for the state of the system */
Packit 47f805
static gint idle_keepgoing;  /* processing of frames is ON */
Packit 47f805
static gint idle_count_max;  /* number of frames to process before plotting */
Packit 47f805
static gint idle_count;      /* pause & plot when idle_count=idel_count_max */
Packit 47f805
static gint idle_end = 0;    /* process all frames, stop at last frame  */
Packit 47f805
static gint idle_back = 0;   /* set when we are displaying the old data */
Packit 47f805
static int mp3done = 0;      /* last frame has been read */
Packit 47f805
static GtkWidget *frameprogress; /* progress bar */
Packit 47f805
static GtkWidget *framecounter; /* progress counter */
Packit 47f805
Packit 47f805
static int subblock_draw[3] = { 1, 1, 1 };
Packit 47f805
Packit 47f805
/* main window */
Packit 47f805
GtkWidget *window;
Packit 47f805
/* Backing pixmap for drawing areas */
Packit 47f805
GtkWidget *pcmbox;           /* PCM data plotted here */
Packit 47f805
GtkWidget *winbox;           /* mpg123 synthesis data plotted here */
Packit 47f805
GtkWidget *enerbox[2];       /* spectrum, gr=0,1 plotted here */
Packit 47f805
GtkWidget *mdctbox[2];       /* mdct coefficients gr=0,1 plotted here */
Packit 47f805
GtkWidget *sfbbox[2];        /* scalefactors gr=0,1 plotted here */
Packit 47f805
GtkWidget *headerbox;        /* mpg123 header info shown here */
Packit 47f805
Packit 47f805
Packit 47f805
struct gtkinfostruct {
Packit 47f805
    int     filetype;        /* input file type 0=WAV, 1=MP3 */
Packit 47f805
    int     msflag;          /* toggle between L&R vs M&S PCM data display */
Packit 47f805
    int     chflag;          /* toggle between L & R channels */
Packit 47f805
    int     kbflag;          /* toggle between wave # and barks */
Packit 47f805
    int     flag123;         /* show mpg123 frame info, OR ISO encoder frame info */
Packit 47f805
    double  avebits;         /* running average bits per frame */
Packit 47f805
    int     approxbits;      /* (approx) bits per frame */
Packit 47f805
    int     maxbits;         /* max bits per frame used so far */
Packit 47f805
    int     totemph;         /* total of frames with de-emphasis */
Packit 47f805
    int     totms;           /* total frames with ms_stereo */
Packit 47f805
    int     totis;           /* total frames with i_stereo */
Packit 47f805
    int     totshort;        /* total granules with short blocks */
Packit 47f805
    int     totmix;          /* total granules with mixed blocks */
Packit 47f805
    int     totpreflag;      /* total granules with preflag */
Packit 47f805
    int     pupdate;         /* plot while processing, or only when needed */
Packit 47f805
    int     sfblines;        /* plot scalefactor bands in MDCT plot */
Packit 47f805
    int     difference;      /* plot original - decoded instead of orig vs. decoded */
Packit 47f805
    int     totalframes;
Packit 47f805
} gtkinfo;
Packit 47f805
Packit 47f805
Packit 47f805
static lame_global_flags *gfp;
Packit 47f805
lame_internal_flags *gfc;
Packit 47f805
hip_t hip; /* decoder handle of just encoded data */
Packit 47f805
Packit 47f805
/**********************************************************************
Packit 47f805
 * read one frame and encode it
Packit 47f805
 **********************************************************************/
Packit 47f805
int
Packit 47f805
gtkmakeframe(void)
Packit 47f805
{
Packit 47f805
    int     iread = 0;
Packit 47f805
    static int init = 0;
Packit 47f805
    static int mpglag;
Packit 47f805
    static short int Buffer[2][1152];
Packit 47f805
    short int mpg123pcm[2][1152];
Packit 47f805
    int     ch, j;
Packit 47f805
    int     mp3count = 0;
Packit 47f805
    int     mp3out = 0;
Packit 47f805
    int     channels_out;
Packit 47f805
    unsigned char mp3buffer[LAME_MAXMP3BUFFER];
Packit 47f805
    static int frameNum = 0;
Packit 47f805
    int     framesize = lame_get_framesize(gfp);
Packit 47f805
Packit 47f805
    channels_out = (lame_get_mode(gfp) == MONO) ? 1 : 2;
Packit 47f805
Packit 47f805
    pinfo->frameNum = frameNum;
Packit 47f805
    pinfo->sampfreq = lame_get_out_samplerate(gfp);
Packit 47f805
    pinfo->framesize = framesize;
Packit 47f805
    pinfo->stereo = channels_out;
Packit 47f805
Packit 47f805
    /* If the analsys code is enabled, lame will writes data into gfc->pinfo,
Packit 47f805
     * and mpg123 will write data into pinfo.  Set these so
Packit 47f805
     * the libraries put this data in the right place: */
Packit 47f805
    gfc->pinfo = pinfo;
Packit 47f805
    hip_set_pinfo(hip, pinfo);
Packit 47f805
Packit 47f805
    if (is_mpeg_file_format(global_reader.input_format)) {
Packit 47f805
        hip_set_pinfo(get_hip(), pplot);
Packit 47f805
        iread = get_audio16(gfp, Buffer);
Packit 47f805
Packit 47f805
Packit 47f805
        /* add a delay of framesize-DECDELAY, which will make the total delay
Packit 47f805
         * exactly one frame, so we can sync MP3 output with WAV input */
Packit 47f805
        for (ch = 0; ch < channels_out; ch++) {
Packit 47f805
            for (j = 0; j < framesize - DECDELAY; j++)
Packit 47f805
                pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j + framesize];
Packit 47f805
            for (j = 0; j < framesize; j++) /*rescale from int to short int */
Packit 47f805
                pinfo->pcmdata2[ch][j + framesize - DECDELAY] = Buffer[ch][j];
Packit 47f805
        }
Packit 47f805
Packit 47f805
        pinfo->frameNum123 = frameNum - 1;
Packit 47f805
        ++frameNum;
Packit 47f805
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
Packit 47f805
        /* feed data to encoder until encoder produces some output */
Packit 47f805
        while (lame_get_frameNum(gfp) == pinfo->frameNum) {
Packit 47f805
Packit 47f805
            if (!init) {
Packit 47f805
                init = 1;
Packit 47f805
                mpglag = 1;
Packit 47f805
                if (hip) {
Packit 47f805
                    hip_decode_exit(hip);
Packit 47f805
                }
Packit 47f805
                hip = hip_decode_init();
Packit 47f805
                hip_set_pinfo(hip, pinfo);
Packit 47f805
            }
Packit 47f805
Packit 47f805
            iread = get_audio16(gfp, Buffer);
Packit 47f805
            if (iread > framesize) {
Packit 47f805
                /* NOTE: frame analyzer requires that we encode one frame
Packit 47f805
                 * for each pass through this loop.  If lame_encode_buffer()
Packit 47f805
                 * is feed data too quickly, it will sometimes encode multiple frames
Packit 47f805
                 * breaking this loop.
Packit 47f805
                 */
Packit 47f805
                error_printf("Warning: get_audio is returning too much data.\n");
Packit 47f805
            }
Packit 47f805
            if (iread <= 0)
Packit 47f805
                break;  /* eof */
Packit 47f805
Packit 47f805
            mp3count = lame_encode_buffer(gfp, Buffer[0], Buffer[1], iread,
Packit 47f805
                                          mp3buffer, sizeof(mp3buffer));
Packit 47f805
Packit 47f805
            assert(!(mp3count > 0 && lame_get_frameNum(gfp) == pinfo->frameNum));
Packit 47f805
            /* not possible to produce mp3 data without encoding at least
Packit 47f805
             * one frame of data which would increment frameNum */
Packit 47f805
        }
Packit 47f805
        frameNum = lame_get_frameNum(gfp); /* use the internal MP3 frame counter */
Packit 47f805
Packit 47f805
Packit 47f805
        /* decode one frame of output */
Packit 47f805
        mp3out = hip_decode1(hip, mp3buffer, mp3count, mpg123pcm[0], mpg123pcm[1]); /* re-synthesis to pcm */
Packit 47f805
        /* mp3out = 0:  need more data to decode */
Packit 47f805
        /* mp3out = -1:  error.  Lets assume 0 pcm output */
Packit 47f805
        /* mp3out = number of samples output */
Packit 47f805
        if (mp3out > 0)
Packit 47f805
            assert(mp3out == pinfo->framesize);
Packit 47f805
        if (mp3out != 0) {
Packit 47f805
            /* decoded output is for frame pinfo->frameNum123
Packit 47f805
             * add a delay of framesize-DECDELAY, which will make the total delay
Packit 47f805
             * exactly one frame */
Packit 47f805
            pinfo->frameNum123 = pinfo->frameNum - mpglag;
Packit 47f805
            for (ch = 0; ch < pinfo->stereo; ch++) {
Packit 47f805
                for (j = 0; j < pinfo->framesize - DECDELAY; j++)
Packit 47f805
                    pinfo->pcmdata2[ch][j] = pinfo->pcmdata2[ch][j + pinfo->framesize];
Packit 47f805
                for (j = 0; j < pinfo->framesize; j++) {
Packit 47f805
                    pinfo->pcmdata2[ch][j + pinfo->framesize - DECDELAY] =
Packit 47f805
                        (mp3out == -1) ? 0 : mpg123pcm[ch][j];
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            if (mpglag == MAXMPGLAG) {
Packit 47f805
                error_printf("READ_AHEAD set too low - not enough frame buffering.\n"
Packit 47f805
                             "MP3x display of input and output PCM data out of sync.\n");
Packit 47f805
                error_flush();
Packit 47f805
            }
Packit 47f805
            else
Packit 47f805
                mpglag++;
Packit 47f805
            pinfo->frameNum123 = -1; /* no frame output */
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    return iread;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
void
Packit 47f805
plot_frame(void)
Packit 47f805
{
Packit 47f805
    int     i, j, n, ch, gr;
Packit 47f805
    gdouble *xcord, *ycord;
Packit 47f805
    gdouble xmx, xmn, ymx, ymn;
Packit 47f805
    double *data, *data2, *data3;
Packit 47f805
    char    title2[80];
Packit 47f805
    char    label[80], label2[80];
Packit 47f805
    char   *title;
Packit 47f805
    plotting_data *pplot1;
Packit 47f805
    plotting_data *pplot2 = NULL;
Packit 47f805
Packit 47f805
    double  en, samp;
Packit 47f805
    /*int     sampindex, version = 0;*/
Packit 47f805
    int     barthick;
Packit 47f805
    static int firstcall = 1;
Packit 47f805
    static GdkColor *barcolor, *color, *grcolor[2];
Packit 47f805
    static GdkColor yellow, gray, cyan, magenta, orange, pink, red, green, blue, black, oncolor,
Packit 47f805
        offcolor;
Packit 47f805
    int     blocktype[2][2];
Packit 47f805
    int     headbits;
Packit 47f805
    int     mode_gr = 2;
Packit 47f805
Packit 47f805
    /* find the frame where mpg123 produced output coming from input frame
Packit 47f805
     * pinfo.  i.e.:   out_frame + out_frame_lag = input_frame  */
Packit 47f805
    for (i = 1; i <= MAXMPGLAG; i++) {
Packit 47f805
        if ((pplot - i)->frameNum123 == pplot->frameNum) {
Packit 47f805
            pplot2 = pplot - i;
Packit 47f805
            break;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    if (i > MAXMPGLAG) {
Packit 47f805
        error_printf("input/output pcm syncing problem.  should not happen!\n");
Packit 47f805
        pplot2 = pplot - 1;
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
    /* however, the PCM data is delayed by 528 samples in the encoder filterbanks.
Packit 47f805
     * We added another 1152-528 delay to this so the PCM data is *exactly* one
Packit 47f805
     * frame behind the header & MDCT information */
Packit 47f805
    pplot1 = pplot2 + 1; /* back one frame for header info, MDCT */
Packit 47f805
Packit 47f805
    /* allocate these GC's only once */
Packit 47f805
    if (firstcall) {
Packit 47f805
        firstcall = 0;
Packit 47f805
        /*    grcolor[0] = &magenta; */
Packit 47f805
        grcolor[0] = &blu;;
Packit 47f805
        grcolor[1] = &green;
Packit 47f805
        barcolor = &gray;
Packit 47f805
Packit 47f805
        setcolor(headerbox, &oncolor, 255, 0, 0);
Packit 47f805
        setcolor(headerbox, &offcolor, 175, 175, 175);
Packit 47f805
        setcolor(pcmbox, &red, 255, 0, 0);
Packit 47f805
        setcolor(pcmbox, &pink, 255, 0, 255);
Packit 47f805
        setcolor(pcmbox, &magenta, 255, 0, 100);
Packit 47f805
        setcolor(pcmbox, &orange, 255, 127, 0);
Packit 47f805
        setcolor(pcmbox, &cyan, 0, 255, 255);
Packit 47f805
        setcolor(pcmbox, &green, 0, 255, 0);
Packit 47f805
        setcolor(pcmbox, &blue, 0, 0, 255);
Packit 47f805
        setcolor(pcmbox, &black, 0, 0, 0);
Packit 47f805
        setcolor(pcmbox, &gray, 100, 100, 100);
Packit 47f805
        setcolor(pcmbox, &yellow, 255, 255, 0);
Packit 47f805
Packit 47f805
    }
Packit 47f805
Packit 47f805
  /*******************************************************************
Packit 47f805
   * frame header info
Packit 47f805
   *******************************************************************/
Packit 47f805
    if (pplot1->sampfreq)
Packit 47f805
        samp = pplot1->sampfreq;
Packit 47f805
    else
Packit 47f805
        samp = 1;
Packit 47f805
    /*sampindex = SmpFrqIndex((long) samp, &version);*/
Packit 47f805
Packit 47f805
    ch = gtkinfo.chflag;
Packit 47f805
Packit 47f805
    headbits = 32 + ((pplot1->stereo == 2) ? 256 : 136);
Packit 47f805
    gtkinfo.approxbits = (pplot1->bitrate * 1000 * 1152.0 / samp) - headbits;
Packit 47f805
    sprintf(title2, "%3.1fkHz %ikbs ", samp / 1000, pplot1->bitrate);
Packit 47f805
    gtk_text_freeze(GTK_TEXT(headerbox));
Packit 47f805
    gtk_text_backward_delete(GTK_TEXT(headerbox), gtk_text_get_length(GTK_TEXT(headerbox)));
Packit 47f805
    gtk_text_set_point(GTK_TEXT(headerbox), 0);
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title2, -1);
Packit 47f805
    title = " mono ";
Packit 47f805
    if (2 == pplot1->stereo)
Packit 47f805
        title = pplot1->js ? " js " : " s ";
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title, -1);
Packit 47f805
    color = pplot1->ms_stereo ? &oncolor : &offcolor;
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "ms ", -1);
Packit 47f805
    color = pplot1->i_stereo ? &oncolor : &offcolor;
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "is ", -1);
Packit 47f805
Packit 47f805
    color = pplot1->crc ? &oncolor : &offcolor;
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "crc ", -1);
Packit 47f805
    color = pplot1->padding ? &oncolor : &offcolor;
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "pad ", -1);
Packit 47f805
Packit 47f805
    color = pplot1->emph ? &oncolor : &offcolor;
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, "em ", -1);
Packit 47f805
Packit 47f805
    sprintf(title2, "bv=%i,%i ", pplot1->big_values[0][ch], pplot1->big_values[1][ch]);
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, &black, NULL, title2, -1);
Packit 47f805
Packit 47f805
    color = pplot1->scfsi[ch] ? &oncolor : &offcolor;
Packit 47f805
    sprintf(title2, "scfsi=%i            ", pplot1->scfsi[ch]);
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, color, NULL, title2, -1);
Packit 47f805
    if (gtkinfo.filetype)
Packit 47f805
        sprintf(title2, " mdb=%i %i/NA", pplot1->maindata, pplot1->totbits);
Packit 47f805
    else
Packit 47f805
        sprintf(title2, " mdb=%i   %i/%i",
Packit 47f805
                pplot1->maindata, pplot1->totbits, pplot1->totbits + pplot->resvsize);
Packit 47f805
    gtk_text_insert(GTK_TEXT(headerbox), NULL, &oncolor, NULL, title2, -1);
Packit 47f805
    gtk_text_thaw(GTK_TEXT(headerbox));
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
  /*******************************************************************
Packit 47f805
   * block type
Packit 47f805
   *******************************************************************/
Packit 47f805
    for (gr = 0; gr < mode_gr; gr++)
Packit 47f805
        if (gtkinfo.flag123)
Packit 47f805
            blocktype[gr][ch] = pplot1->mpg123blocktype[gr][ch];
Packit 47f805
        else
Packit 47f805
            blocktype[gr][ch] = pplot->blocktype[gr][ch];
Packit 47f805
Packit 47f805
Packit 47f805
  /*******************************************************************
Packit 47f805
   * draw the PCM data *
Packit 47f805
   *******************************************************************/
Packit 47f805
    n = 1600;           /* PCM frame + FFT window:   224 + 1152 + 224  */
Packit 47f805
    xcord = g_malloc(n * sizeof(gdouble));
Packit 47f805
    ycord = g_malloc(n * sizeof(gdouble));
Packit 47f805
Packit 47f805
Packit 47f805
    if (gtkinfo.msflag)
Packit 47f805
        title = ch ? "Side Channel" : "Mid Channel";
Packit 47f805
    else
Packit 47f805
        title = ch ? "Right Channel" : "Left Channel";
Packit 47f805
Packit 47f805
    sprintf(title2, "%s  mask_ratio=%3.2f  %3.2f  ener_ratio=%3.2f  %3.2f",
Packit 47f805
            title,
Packit 47f805
            pplot->ms_ratio[0], pplot->ms_ratio[1],
Packit 47f805
            pplot->ms_ener_ratio[0], pplot->ms_ener_ratio[1]);
Packit 47f805
Packit 47f805
Packit 47f805
    ymn = -32767;
Packit 47f805
    ymx = 32767;
Packit 47f805
    xmn = 0;
Packit 47f805
    xmx = 1600 - 1;
Packit 47f805
Packit 47f805
    /*  0  ... 224      draw in black, connecting to 224 pixel
Packit 47f805
     * 1375 .. 1599     draw in black  connecting to 1375 pixel
Packit 47f805
     * 224 ... 1375     MP3 frame.  draw in blue
Packit 47f805
     */
Packit 47f805
Packit 47f805
    /* draw the title */
Packit 47f805
    gpk_graph_draw(pcmbox, 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title2, &black);
Packit 47f805
Packit 47f805
Packit 47f805
    /* draw some hash marks dividing the frames */
Packit 47f805
    ycord[0] = ymx * .8;
Packit 47f805
    ycord[1] = ymn * .8;
Packit 47f805
    for (gr = 0; gr <= 2; gr++) {
Packit 47f805
        xcord[0] = 223.5 + gr * 576;
Packit 47f805
        xcord[1] = 223.5 + gr * 576;
Packit 47f805
        gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
Packit 47f805
    }
Packit 47f805
    for (gr = 0; gr < mode_gr; gr++) {
Packit 47f805
        if (blocktype[gr][ch] == 2)
Packit 47f805
            for (i = 1; i <= 2; i++) {
Packit 47f805
                xcord[0] = 223.5 + gr * 576 + i * 192;
Packit 47f805
                xcord[1] = 223.5 + gr * 576 + i * 192;
Packit 47f805
                gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
Packit 47f805
            }
Packit 47f805
    }
Packit 47f805
    /* bars representing FFT windows */
Packit 47f805
    xcord[0] = 0;
Packit 47f805
    ycord[0] = ymn + 3000;
Packit 47f805
    xcord[1] = 1024 - 1;
Packit 47f805
    ycord[1] = ymn + 1000;
Packit 47f805
    gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, grcolor[0]);
Packit 47f805
    xcord[0] = 576;
Packit 47f805
    ycord[0] = ymn + 2000;
Packit 47f805
    xcord[1] = 576 + 1024 - 1;
Packit 47f805
    ycord[1] = ymn;
Packit 47f805
    gpk_rectangle_draw(pcmbox, xcord, ycord, xmn, ymn, xmx, ymx, grcolor[1]);
Packit 47f805
Packit 47f805
Packit 47f805
    /* plot PCM data */
Packit 47f805
    for (i = 0; i < n; i++) {
Packit 47f805
        xcord[i] = i;
Packit 47f805
        if (gtkinfo.msflag)
Packit 47f805
            ycord[i] = ch ? .5 * (pplot->pcmdata[0][i] - pplot->pcmdata[1][i]) :
Packit 47f805
                .5 * (pplot->pcmdata[0][i] + pplot->pcmdata[1][i]);
Packit 47f805
        else
Packit 47f805
            ycord[i] = pplot->pcmdata[ch][i];
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* skip plot if we are doing an mp3 file */
Packit 47f805
    if (!gtkinfo.filetype) {
Packit 47f805
        gpk_graph_draw(pcmbox, n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title2, &black);
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
  /*******************************************************************/
Packit 47f805
    /* draw the PCM re-synthesis data */
Packit 47f805
  /*******************************************************************/
Packit 47f805
    n = 1152;
Packit 47f805
    /*
Packit 47f805
       sprintf(title2,"Re-synthesis  mask_ratio=%3.2f  %3.2f  ener_ratio=%3.2f  %3.2f",
Packit 47f805
       pplot->ms_ratio[0],pplot->ms_ratio[1],
Packit 47f805
       pplot->ms_ener_ratio[0],pplot->ms_ener_ratio[1]);
Packit 47f805
     */
Packit 47f805
    title = "Re-synthesis";
Packit 47f805
    if (gtkinfo.difference)
Packit 47f805
        title = "Re-synthesis difference (amplified 20db)";
Packit 47f805
Packit 47f805
Packit 47f805
    ymn = -32767;
Packit 47f805
    ymx = 32767;
Packit 47f805
    xmn = 0;
Packit 47f805
    xmx = 1600 - 1;
Packit 47f805
    gpk_graph_draw(winbox, 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title, &black);
Packit 47f805
    /* draw some hash marks dividing the frames */
Packit 47f805
    ycord[0] = ymx * .8;
Packit 47f805
    ycord[1] = ymn * .8;
Packit 47f805
    for (gr = 0; gr <= 2; gr++) {
Packit 47f805
        xcord[0] = 223.5 + gr * 576;
Packit 47f805
        xcord[1] = 223.5 + gr * 576;
Packit 47f805
        gpk_rectangle_draw(winbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
Packit 47f805
    }
Packit 47f805
    for (gr = 0; gr < 2; gr++) {
Packit 47f805
        if (blocktype[gr][ch] == 2)
Packit 47f805
            for (i = 1; i <= 2; i++) {
Packit 47f805
                xcord[0] = 223.5 + gr * 576 + i * 192;
Packit 47f805
                xcord[1] = 223.5 + gr * 576 + i * 192;
Packit 47f805
                gpk_rectangle_draw(winbox, xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
Packit 47f805
            }
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* this piece of PCM data from previous frame */
Packit 47f805
    n = 224;
Packit 47f805
    for (j = 1152 - n, i = 0; i < n; i++, j++) {
Packit 47f805
        xcord[i] = i;
Packit 47f805
        if (gtkinfo.msflag)
Packit 47f805
            ycord[i] = ch ? .5 * (pplot1->pcmdata2[0][j] -
Packit 47f805
                                  pplot1->pcmdata2[1][j]) :
Packit 47f805
                .5 * (pplot1->pcmdata2[0][j] + pplot1->pcmdata2[1][j]);
Packit 47f805
        else
Packit 47f805
            ycord[i] = pplot1->pcmdata2[ch][j];
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* this piece of PCM data from current frame */
Packit 47f805
    n = 1152;
Packit 47f805
    for (i = 0; i < n; i++) {
Packit 47f805
        xcord[i + 224] = i + 224;
Packit 47f805
        if (gtkinfo.msflag)
Packit 47f805
            ycord[i + 224] = ch ? .5 * (pplot2->pcmdata2[0][i] - pplot2->pcmdata2[1][i]) :
Packit 47f805
                .5 * (pplot2->pcmdata2[0][i] + pplot2->pcmdata2[1][i]);
Packit 47f805
        else
Packit 47f805
            ycord[i + 224] = pplot2->pcmdata2[ch][i];
Packit 47f805
    }
Packit 47f805
Packit 47f805
    n = 1152 + 224;
Packit 47f805
    if (gtkinfo.difference) {
Packit 47f805
        for (i = 0; i < n; i++) {
Packit 47f805
            if (gtkinfo.msflag)
Packit 47f805
                ycord[i] -= ch ? .5 * (pplot->pcmdata[0][i] - pplot->pcmdata[1][i]) :
Packit 47f805
                    .5 * (pplot->pcmdata[0][i] + pplot->pcmdata[1][i]);
Packit 47f805
            else
Packit 47f805
                ycord[i] -= pplot->pcmdata[ch][i];
Packit 47f805
        }
Packit 47f805
        ycord[i] *= 100;
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
    gpk_graph_draw(winbox, n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title, &black);
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
  /*******************************************************************/
Packit 47f805
    /* draw the MDCT energy spectrum */
Packit 47f805
  /*******************************************************************/
Packit 47f805
    for (gr = 0; gr < mode_gr; gr++) {
Packit 47f805
        int     bits, bits2;
Packit 47f805
        char   *blockname = "";
Packit 47f805
        switch (blocktype[gr][ch]) {
Packit 47f805
        case 0:
Packit 47f805
            blockname = "normal";
Packit 47f805
            break;
Packit 47f805
        case 1:
Packit 47f805
            blockname = "start";
Packit 47f805
            break;
Packit 47f805
        case 2:
Packit 47f805
            blockname = "short";
Packit 47f805
            break;
Packit 47f805
        case 3:
Packit 47f805
            blockname = "end";
Packit 47f805
            break;
Packit 47f805
        }
Packit 47f805
        strcpy(label, blockname);
Packit 47f805
        if (pplot1->mixed[gr][ch])
Packit 47f805
            strcat(label, "(mixed)");
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
        n = 576;
Packit 47f805
        if (gtkinfo.flag123) {
Packit 47f805
            data = pplot1->mpg123xr[gr][0];
Packit 47f805
            data2 = pplot1->mpg123xr[gr][1];
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            data = pplot->xr[gr][0];
Packit 47f805
            data2 = pplot->xr[gr][1];
Packit 47f805
        }
Packit 47f805
Packit 47f805
Packit 47f805
        xmn = 0;
Packit 47f805
        xmx = n - 1;
Packit 47f805
        ymn = 0;
Packit 47f805
        ymx = 11;
Packit 47f805
Packit 47f805
        /* draw title, erase old plot */
Packit 47f805
        if (gtkinfo.flag123) {
Packit 47f805
            bits = pplot1->mainbits[gr][ch];
Packit 47f805
            bits2 = pplot1->sfbits[gr][ch];
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            bits = pplot->LAMEmainbits[gr][ch];
Packit 47f805
            bits2 = pplot->LAMEsfbits[gr][ch];
Packit 47f805
        }
Packit 47f805
        sprintf(title2, "MDCT%1i(%s) bits=%i/%i ", gr, label, bits, bits2);
Packit 47f805
        gpk_bargraph_draw(mdctbox[gr], 0, xcord, ycord, xmn, ymn, xmx, ymx, 1, title2, 0, barcolor);
Packit 47f805
Packit 47f805
        /* draw some hash marks showing scalefactor bands */
Packit 47f805
        if (gtkinfo.sfblines) {
Packit 47f805
            int     fac, nsfb, *scalefac;
Packit 47f805
            if (blocktype[gr][ch] == SHORT_TYPE) {
Packit 47f805
                nsfb = SBMAX_s;
Packit 47f805
                i = nsfb - 7;
Packit 47f805
                fac = 3;
Packit 47f805
                scalefac = gfc->scalefac_band.s;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                nsfb = SBMAX_l;
Packit 47f805
                i = nsfb - 10;
Packit 47f805
                fac = 1;
Packit 47f805
                scalefac = gfc->scalefac_band.l;
Packit 47f805
            }
Packit 47f805
            for (; i < nsfb; i++) {
Packit 47f805
                ycord[0] = .8 * ymx;
Packit 47f805
                ycord[1] = ymn;
Packit 47f805
                xcord[0] = fac * scalefac[i];
Packit 47f805
                xcord[1] = xcord[0];
Packit 47f805
                gpk_rectangle_draw(mdctbox[gr], xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
        ymn = 9e20;
Packit 47f805
        ymx = -9e20;
Packit 47f805
        for (i = 0; i < n; i++) {
Packit 47f805
            double  coeff;
Packit 47f805
            xcord[i] = i;
Packit 47f805
            if (gtkinfo.msflag) {
Packit 47f805
                coeff = ch ? .5 * (data[i] - data2[i]) : .5 * (data[i] + data2[i]);
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                coeff = ch ? data2[i] : data[i];
Packit 47f805
            }
Packit 47f805
            if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
Packit 47f805
                coeff = 0;
Packit 47f805
            ycord[i] = coeff * coeff * 1e10;
Packit 47f805
            ycord[i] = log10(MAX(ycord[i], (double) 1));
Packit 47f805
Packit 47f805
#if 0
Packit 47f805
            if (ch == 0)
Packit 47f805
                if (i == 26)
Packit 47f805
                    if (data[i] != 0)
Packit 47f805
                        console_printf("%i %i i=%i  mdct: (db) %f  %f \n", pplot->frameNum, gr, i,
Packit 47f805
                                       10 * log10(data[i] * data[i]),
Packit 47f805
                                       10 * log10(.33 *
Packit 47f805
                                                  (data[i - 1] * data[i - 1] + data[i] * data[i] +
Packit 47f805
                                                   data[i + 1] * data[i + 1]))
Packit 47f805
                            );
Packit 47f805
#endif
Packit 47f805
Packit 47f805
            ymx = (ycord[i] > ymx) ? ycord[i] : ymx;
Packit 47f805
            ymn = (ycord[i] < ymn) ? ycord[i] : ymn;
Packit 47f805
        }
Packit 47f805
        /*  print the min/max
Packit 47f805
           sprintf(title2,"MDCT%1i %5.2f %5.2f  bits=%i",gr,ymn,ymx,
Packit 47f805
           pplot1->mainbits[gr][ch]);
Packit 47f805
         */
Packit 47f805
        if (gtkinfo.flag123)
Packit 47f805
            bits = pplot1->mainbits[gr][ch];
Packit 47f805
        else
Packit 47f805
            bits = pplot->LAMEmainbits[gr][ch];
Packit 47f805
Packit 47f805
Packit 47f805
        sprintf(title2, "MDCT%1i(%s) bits=%i ", gr, label, bits);
Packit 47f805
Packit 47f805
        xmn = 0;
Packit 47f805
        xmx = n - 1;
Packit 47f805
        ymn = 0;
Packit 47f805
        ymx = 11;
Packit 47f805
        gpk_bargraph_draw(mdctbox[gr], n, xcord, ycord, xmn, ymn, xmx, ymx, 0, title2, 0, barcolor);
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
  /*******************************************************************
Packit 47f805
   * draw the psy model energy spectrum (k space)
Packit 47f805
   * l3psy.c computes pe, en, thm for THIS granule.
Packit 47f805
   *******************************************************************/
Packit 47f805
    if (gtkinfo.kbflag) {
Packit 47f805
        for (gr = 0; gr < mode_gr; gr++) {
Packit 47f805
            n = HBLKSIZE; /* only show half the spectrum */
Packit 47f805
Packit 47f805
            data = &pplot->energy[gr][ch][0];
Packit 47f805
Packit 47f805
            ymn = 9e20;
Packit 47f805
            ymx = -9e20;
Packit 47f805
            for (i = 0; i < n; i++) {
Packit 47f805
                xcord[i] = i + 1;
Packit 47f805
                if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
Packit 47f805
                    ycord[i] = 0;
Packit 47f805
                else
Packit 47f805
                    ycord[i] = log10(MAX(data[i], (double) 1));
Packit 47f805
                ymx = (ycord[i] > ymx) ? ycord[i] : ymx;
Packit 47f805
                ymn = (ycord[i] < ymn) ? ycord[i] : ymn;
Packit 47f805
            }
Packit 47f805
            for (en = 0, j = 0; j < BLKSIZE; j++)
Packit 47f805
                en += pplot->energy[gr][ch][j];
Packit 47f805
Packit 47f805
            sprintf(title2, "FFT%1i  pe=%5.2fK  en=%5.2e ", gr, pplot->pe[gr][ch] / 1000, en);
Packit 47f805
Packit 47f805
            ymn = 3;
Packit 47f805
            ymx = 15;
Packit 47f805
            xmn = 1;
Packit 47f805
            xmx = n;
Packit 47f805
            gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
Packit 47f805
                              xmn, ymn, xmx, ymx, 1, title2, 0, barcolor);
Packit 47f805
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
    /*******************************************************************
Packit 47f805
     * draw the psy model energy spectrum (scalefactor bands)
Packit 47f805
     *******************************************************************/
Packit 47f805
        for (gr = 0; gr < mode_gr; gr++) {
Packit 47f805
Packit 47f805
            if (blocktype[gr][ch] == 2) {
Packit 47f805
                n = 3 * SBMAX_s;
Packit 47f805
                data = &pplot->en_s[gr][ch][0];
Packit 47f805
                data2 = &pplot->thr_s[gr][ch][0];
Packit 47f805
                data3 = &pplot->xfsf_s[gr][ch][0];
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                n = SBMAX_l;
Packit 47f805
                data = &pplot->en[gr][ch][0];
Packit 47f805
                data2 = &pplot->thr[gr][ch][0];
Packit 47f805
                data3 = &pplot->xfsf[gr][ch][0];
Packit 47f805
            }
Packit 47f805
            ymn = 9e20;
Packit 47f805
            ymx = -9e20;
Packit 47f805
            for (i = 0; i < n; i++) {
Packit 47f805
                xcord[i] = i + 1;
Packit 47f805
                if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
Packit 47f805
                    ycord[i] = 0;
Packit 47f805
                else
Packit 47f805
                    ycord[i] = log10(MAX(data[i], (double) 1));
Packit 47f805
                /*
Packit 47f805
                   ymx=(ycord[i] > ymx) ? ycord[i] : ymx;
Packit 47f805
                   ymn=(ycord[i] < ymn) ? ycord[i] : ymn;
Packit 47f805
                 */
Packit 47f805
            }
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
            /* en = max energy difference amoung the 3 short FFTs for this granule */
Packit 47f805
            en = pplot->ers[gr][ch];
Packit 47f805
            if (en > 999)
Packit 47f805
                en = 999;
Packit 47f805
            sprintf(title2,
Packit 47f805
                    "FFT%1i pe=%5.2fK/%3.1f \nnoise ovr_b:%i/max:%3.1f/ovr:%3.1f/tot:%3.1f/ssd:%i",
Packit 47f805
                    gr, pplot->pe[gr][ch] / 1000, en, pplot->over[gr][ch], pplot->max_noise[gr][ch],
Packit 47f805
                    pplot->over_noise[gr][ch], pplot->tot_noise[gr][ch], pplot->over_SSD[gr][ch]);
Packit 47f805
Packit 47f805
            barthick = 3;
Packit 47f805
            if (blocktype[gr][ch] == SHORT_TYPE)
Packit 47f805
                barthick = 2;
Packit 47f805
            if (!(subblock_draw[0] && subblock_draw[1] && subblock_draw[2]))
Packit 47f805
                barthick = 3;
Packit 47f805
Packit 47f805
            ymn = 3;
Packit 47f805
            ymx = 15;
Packit 47f805
            xmn = 1;
Packit 47f805
            xmx = n + 1; /* a little extra because of the bar thickness */
Packit 47f805
            gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
Packit 47f805
                              xmn, ymn, xmx, ymx, 1, title2, barthick, barcolor);
Packit 47f805
Packit 47f805
            for (i = 0; i < n; i++) {
Packit 47f805
                xcord[i] = i + 1 + .20;
Packit 47f805
                if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
Packit 47f805
                    ycord[i] = 0;
Packit 47f805
                else
Packit 47f805
                    ycord[i] = log10(MAX(data2[i], (double) 1));
Packit 47f805
            }
Packit 47f805
Packit 47f805
            gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
Packit 47f805
                              xmn, ymn, xmx, ymx, 0, title2, barthick, grcolor[gr]);
Packit 47f805
Packit 47f805
            for (i = 0; i < n; i++) {
Packit 47f805
                xcord[i] = i + 1 + .40;
Packit 47f805
                if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
Packit 47f805
                    ycord[i] = 0;
Packit 47f805
                else
Packit 47f805
                    ycord[i] = log10(MAX(data3[i], (double) 1));
Packit 47f805
            }
Packit 47f805
            gpk_bargraph_draw(enerbox[gr], n, xcord, ycord,
Packit 47f805
                              xmn, ymn, xmx, ymx, 0, title2, barthick, &red;;
Packit 47f805
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
  /*******************************************************************
Packit 47f805
   * draw scalefactors
Packit 47f805
   *******************************************************************/
Packit 47f805
    for (gr = 0; gr < mode_gr; gr++) {
Packit 47f805
        int     ggain;
Packit 47f805
        if (blocktype[gr][ch] == 2) {
Packit 47f805
            n = 3 * SBMAX_s;
Packit 47f805
            if (gtkinfo.flag123)
Packit 47f805
                data = pplot1->sfb_s[gr][ch];
Packit 47f805
            else
Packit 47f805
                data = pplot->LAMEsfb_s[gr][ch];
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            n = SBMAX_l;
Packit 47f805
            if (gtkinfo.flag123)
Packit 47f805
                data = pplot1->sfb[gr][ch];
Packit 47f805
            else
Packit 47f805
                data = pplot->LAMEsfb[gr][ch];
Packit 47f805
        }
Packit 47f805
Packit 47f805
        ymn = -1;
Packit 47f805
        ymx = 10;
Packit 47f805
        for (i = 0; i < n; i++) {
Packit 47f805
            xcord[i] = i + 1;
Packit 47f805
            if (blocktype[gr][ch] == SHORT_TYPE && !subblock_draw[i % 3])
Packit 47f805
                ycord[i] = 0;
Packit 47f805
            else
Packit 47f805
                ycord[i] = -data[i];
Packit 47f805
Packit 47f805
            ymx = (ycord[i] > ymx - 2) ? ycord[i] + 2 : ymx;
Packit 47f805
            ymn = (ycord[i] < ymn) ? ycord[i] - 1 : ymn;
Packit 47f805
        }
Packit 47f805
Packit 47f805
        if (blocktype[gr][ch] == 2) {
Packit 47f805
            sprintf(label2,
Packit 47f805
                    "SFB scale=%i preflag=%i  %i%i%i",
Packit 47f805
                    pplot1->scalefac_scale[gr][ch],
Packit 47f805
                    pplot1->preflag[gr][ch],
Packit 47f805
                    pplot1->sub_gain[gr][ch][0],
Packit 47f805
                    pplot1->sub_gain[gr][ch][1], pplot1->sub_gain[gr][ch][2]);
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            sprintf(label2, "SFB scale=%i preflag=%i", pplot1->scalefac_scale[gr][ch],
Packit 47f805
                    pplot1->preflag[gr][ch]);
Packit 47f805
        }
Packit 47f805
Packit 47f805
        if (gtkinfo.flag123)
Packit 47f805
            ggain = (pplot1->qss[gr][ch]);
Packit 47f805
        else
Packit 47f805
            ggain = (pplot->LAMEqss[gr][ch]);
Packit 47f805
Packit 47f805
        sprintf(title2, " ggain=%i", ggain);
Packit 47f805
        strcat(label2, title2);
Packit 47f805
Packit 47f805
        xmn = 1;
Packit 47f805
        xmx = n + 1;
Packit 47f805
        gpk_bargraph_draw(sfbbox[gr], n, xcord, ycord,
Packit 47f805
                          xmn, ymn, xmx, ymx, 1, label2, 0, grcolor[gr]);
Packit 47f805
Packit 47f805
        ycord[0] = ycord[1] = 0;
Packit 47f805
        xcord[0] = 1;
Packit 47f805
        xcord[1] = n + 1;
Packit 47f805
        gpk_rectangle_draw(sfbbox[gr], xcord, ycord, xmn, ymn, xmx, ymx, &yellow);
Packit 47f805
Packit 47f805
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
update_progress(void)
Packit 47f805
{
Packit 47f805
    char    label[80];
Packit 47f805
Packit 47f805
    int     tf = lame_get_totalframes(gfp);
Packit 47f805
    if (gtkinfo.totalframes > 0)
Packit 47f805
        tf = gtkinfo.totalframes;
Packit 47f805
Packit 47f805
    sprintf(label, "Frame:%4i/%4i  %6.2fs", pplot->frameNum, (int) tf - 1, pplot->frametime);
Packit 47f805
    gtk_progress_set_value(GTK_PROGRESS(frameprogress), (gdouble) pplot->frameNum);
Packit 47f805
    gtk_label_set_text(GTK_LABEL(framecounter), label);
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
analyze(void)
Packit 47f805
{
Packit 47f805
    if (idle_keepgoing) {
Packit 47f805
        idle_count = 0;
Packit 47f805
        idle_count_max = 0;
Packit 47f805
        idle_keepgoing = 0;
Packit 47f805
        idle_end = 0;
Packit 47f805
    }
Packit 47f805
    plot_frame();
Packit 47f805
    update_progress();
Packit 47f805
}
Packit 47f805
Packit 47f805
static void
Packit 47f805
plotclick(GtkWidget * widget, gpointer data)
Packit 47f805
{
Packit 47f805
    analyze();
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static int
Packit 47f805
frameadv1(GtkWidget * widget, gpointer data)
Packit 47f805
{
Packit 47f805
    int     i;
Packit 47f805
    if (idle_keepgoing) {
Packit 47f805
        if (idle_back) {
Packit 47f805
            /* frame displayed is the old frame.  to advance, just swap in new frame */
Packit 47f805
            idle_back--;
Packit 47f805
            pplot = &Pinfo[READ_AHEAD + idle_back];
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            /* advance the frame by reading in a new frame */
Packit 47f805
            pplot = &Pinfo[READ_AHEAD];
Packit 47f805
            if (mp3done) {
Packit 47f805
                /* dont try to read any more frames, and quit if "finish MP3" was selected */
Packit 47f805
                /* if (idle_finish) gtk_main_quit(); */
Packit 47f805
                idle_count_max = 0;
Packit 47f805
                idle_end = 0;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                /* read in the next frame */
Packit 47f805
                for (i = NUMPINFO - 1; i > 0; i--)
Packit 47f805
                    memcpy(&Pinfo[i], &Pinfo[i - 1], sizeof(plotting_data));
Packit 47f805
                pinfo = &Pinfo[0];
Packit 47f805
                pinfo->num_samples = gtkmakeframe();
Packit 47f805
                if (pinfo->num_samples == 0 && gtkinfo.totalframes == 0)
Packit 47f805
                    /* allow an extra frame to flush decoder buffers */
Packit 47f805
                    gtkinfo.totalframes = pinfo->frameNum + 2;
Packit 47f805
Packit 47f805
                if (pinfo->sampfreq)
Packit 47f805
                    pinfo->frametime = (pinfo->frameNum) * 1152.0 / pinfo->sampfreq;
Packit 47f805
                else
Packit 47f805
                    pinfo->frametime = 0;
Packit 47f805
Packit 47f805
                /* eof?
Packit 47f805
                   if (!pinfo->num_samples) if (idle_finish) gtk_main_quit();
Packit 47f805
                 */
Packit 47f805
Packit 47f805
                pinfo->totbits = 0;
Packit 47f805
                {
Packit 47f805
                    int     gr, ch;
Packit 47f805
                    for (gr = 0; gr < 2; gr++)
Packit 47f805
                        for (ch = 0; ch < 2; ch++) {
Packit 47f805
                            gtkinfo.totshort += (pinfo->mpg123blocktype[gr][ch] == 2);
Packit 47f805
                            gtkinfo.totmix += !(pinfo->mixed[gr][ch] == 0);
Packit 47f805
                            gtkinfo.totpreflag += (pinfo->preflag[gr][ch] == 1);
Packit 47f805
                            pinfo->totbits += pinfo->mainbits[gr][ch];
Packit 47f805
                        }
Packit 47f805
                }
Packit 47f805
                if (pinfo->frameNum > 0) /* start averaging at second frame */
Packit 47f805
                    gtkinfo.avebits = (gtkinfo.avebits * ((pinfo->frameNum) - 1)
Packit 47f805
                                       + pinfo->totbits) / (pinfo->frameNum);
Packit 47f805
Packit 47f805
                gtkinfo.maxbits = MAX(gtkinfo.maxbits, pinfo->totbits);
Packit 47f805
                gtkinfo.totemph += !(pinfo->emph == 0);
Packit 47f805
                gtkinfo.totms += !(pinfo->ms_stereo == 0);
Packit 47f805
                gtkinfo.totis += !(pinfo->i_stereo == 0);
Packit 47f805
Packit 47f805
                if (gtkinfo.totalframes > 0)
Packit 47f805
                    if (pplot->frameNum >= gtkinfo.totalframes - 1)
Packit 47f805
                        mp3done = 1;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
Packit 47f805
        idle_count++;
Packit 47f805
        if (gtkinfo.pupdate)
Packit 47f805
            plot_frame();
Packit 47f805
        update_progress();
Packit 47f805
        if ((idle_count >= idle_count_max) && (!idle_end))
Packit 47f805
            analyze();
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        /*no processing to do, sleep in order to not monopolize CPU */
Packit 47f805
        msleep(10);
Packit 47f805
    }
Packit 47f805
    return 1;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
frameadv(GtkWidget * widget, gpointer data)
Packit 47f805
{
Packit 47f805
    int     adv;
Packit 47f805
Packit 47f805
    if (!strcmp((char *) data, "-1")) {
Packit 47f805
        /* ignore if we've already gone back as far as possible */
Packit 47f805
        if (pplot->frameNum == 0 || (idle_back == NUMBACK))
Packit 47f805
            return;
Packit 47f805
        idle_back++;
Packit 47f805
        pplot = &Pinfo[READ_AHEAD + idle_back];
Packit 47f805
        analyze();
Packit 47f805
        return;
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
    adv = 1;
Packit 47f805
    if (!strcmp((char *) data, "1"))
Packit 47f805
        adv = 1;
Packit 47f805
    if (!strcmp((char *) data, "10"))
Packit 47f805
        adv = 10;
Packit 47f805
    if (!strcmp((char *) data, "100"))
Packit 47f805
        adv = 100;
Packit 47f805
    if (!strcmp((char *) data, "finish"))
Packit 47f805
        idle_end = 1;
Packit 47f805
Packit 47f805
Packit 47f805
    if (idle_keepgoing) {
Packit 47f805
        /* already running - que up additional frame advance requests */
Packit 47f805
        idle_count_max += adv;
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        /* turn on idleing */
Packit 47f805
        idle_count_max = adv;
Packit 47f805
        idle_count = 0;
Packit 47f805
        idle_keepgoing = 1;
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/* another callback */
Packit 47f805
static void
Packit 47f805
delete_event(GtkWidget * widget, GdkEvent * event, gpointer data)
Packit 47f805
{
Packit 47f805
    /* set MP3 done flag in case the File/Quit menu item has been selected */
Packit 47f805
    mp3done = 1;
Packit 47f805
Packit 47f805
    if (hip) {
Packit 47f805
        hip_decode_exit(hip);
Packit 47f805
        hip = 0;
Packit 47f805
    }
Packit 47f805
    gtk_main_quit();
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
channel_option(GtkWidget * widget, gpointer data)
Packit 47f805
{
Packit 47f805
    long    option;
Packit 47f805
    option = (long) data;
Packit 47f805
    switch (option) {
Packit 47f805
    case 1:
Packit 47f805
        gtkinfo.msflag = 0;
Packit 47f805
        gtkinfo.chflag = 0;
Packit 47f805
        break;
Packit 47f805
    case 2:
Packit 47f805
        gtkinfo.msflag = 0;
Packit 47f805
        gtkinfo.chflag = 1;
Packit 47f805
        break;
Packit 47f805
    case 3:
Packit 47f805
        gtkinfo.msflag = 1;
Packit 47f805
        gtkinfo.chflag = 0;
Packit 47f805
        break;
Packit 47f805
    case 4:
Packit 47f805
        gtkinfo.msflag = 1;
Packit 47f805
        gtkinfo.chflag = 1;
Packit 47f805
    }
Packit 47f805
    analyze();
Packit 47f805
}
Packit 47f805
static void
Packit 47f805
spec_option(GtkWidget * widget, gpointer data)
Packit 47f805
{
Packit 47f805
    long    option;
Packit 47f805
    option = (long) data;
Packit 47f805
    switch (option) {
Packit 47f805
    case 1:
Packit 47f805
        gtkinfo.kbflag = 0;
Packit 47f805
        break;
Packit 47f805
    case 2:
Packit 47f805
        gtkinfo.kbflag = 1;
Packit 47f805
        break;
Packit 47f805
    case 3:
Packit 47f805
        gtkinfo.flag123 = 0;
Packit 47f805
        break;
Packit 47f805
    case 4:
Packit 47f805
        gtkinfo.flag123 = 1;
Packit 47f805
        break;
Packit 47f805
    case 5:
Packit 47f805
        gtkinfo.pupdate = 1;
Packit 47f805
        break;
Packit 47f805
    case 6:
Packit 47f805
        gtkinfo.pupdate = 0;
Packit 47f805
        break;
Packit 47f805
    case 7:
Packit 47f805
        gtkinfo.sfblines = !gtkinfo.sfblines;
Packit 47f805
        break;
Packit 47f805
    case 8:
Packit 47f805
        gtkinfo.difference = !gtkinfo.difference;
Packit 47f805
        break;
Packit 47f805
    }
Packit 47f805
    analyze();
Packit 47f805
}
Packit 47f805
Packit 47f805
static  gint
Packit 47f805
key_press_event(GtkWidget * widget, GdkEventKey * event)
Packit 47f805
{
Packit 47f805
    /* is a switch() statement in lame forbidden? */
Packit 47f805
    if (event->keyval == '1') {
Packit 47f805
        subblock_draw[0] = 1;
Packit 47f805
        subblock_draw[1] = 0;
Packit 47f805
        subblock_draw[2] = 0;
Packit 47f805
        analyze();
Packit 47f805
    }
Packit 47f805
    else if (event->keyval == '2') {
Packit 47f805
        subblock_draw[0] = 0;
Packit 47f805
        subblock_draw[1] = 1;
Packit 47f805
        subblock_draw[2] = 0;
Packit 47f805
        analyze();
Packit 47f805
    }
Packit 47f805
    else if (event->keyval == '3') {
Packit 47f805
        subblock_draw[0] = 0;
Packit 47f805
        subblock_draw[1] = 0;
Packit 47f805
        subblock_draw[2] = 1;
Packit 47f805
        analyze();
Packit 47f805
    }
Packit 47f805
    else if (event->keyval == '0') {
Packit 47f805
        subblock_draw[0] = 1;
Packit 47f805
        subblock_draw[1] = 1;
Packit 47f805
        subblock_draw[2] = 1;
Packit 47f805
        analyze();
Packit 47f805
    }
Packit 47f805
    /* analyze(); */ /* dont redraw entire window for every key! */
Packit 47f805
    return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
/*! Get the mp3x version string. */
Packit 47f805
/*!
Packit 47f805
  \param void
Packit 47f805
  \return a pointer to a string which describes the version of mp3x.
Packit 47f805
*/
Packit 47f805
const char *
Packit 47f805
get_mp3x_version(void)
Packit 47f805
{
Packit 47f805
#if   MP3X_ALPHA_VERSION > 0
Packit 47f805
    static /*@observer@ */ const char *const str =
Packit 47f805
        XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION)
Packit 47f805
        " (alpha " XSTR(MP3X_ALPHA_VERSION) ", " __DATE__ " " __TIME__ ")";
Packit 47f805
#elif MP3X_BETA_VERSION > 0
Packit 47f805
    static /*@observer@ */ const char *const str =
Packit 47f805
        XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION)
Packit 47f805
        " (beta " XSTR(MP3X_BETA_VERSION) ", " __DATE__ ")";
Packit 47f805
#else
Packit 47f805
    static /*@observer@ */ const char *const str =
Packit 47f805
        XSTR(MP3X_MAJOR_VERSION) "." XSTR(MP3X_MINOR_VERSION);
Packit 47f805
#endif
Packit 47f805
Packit 47f805
    return str;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
text_window(GtkWidget * widget, gpointer data)
Packit 47f805
{
Packit 47f805
    long    option;
Packit 47f805
    GtkWidget *hbox, *vbox, *button, *box;
Packit 47f805
    GtkWidget *textwindow, *vscrollbar;
Packit 47f805
    char    text[256];
Packit 47f805
Packit 47f805
    option = (long) data;
Packit 47f805
Packit 47f805
    textwindow = gtk_window_new(GTK_WINDOW_DIALOG);
Packit 47f805
    gtk_signal_connect_object(GTK_OBJECT(window), "delete_event",
Packit 47f805
                              GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(textwindow));
Packit 47f805
Packit 47f805
    gtk_container_set_border_width(GTK_CONTAINER(textwindow), 0);
Packit 47f805
    vbox = gtk_vbox_new(FALSE, 0);
Packit 47f805
    hbox = gtk_hbox_new(FALSE, 0);
Packit 47f805
Packit 47f805
    button = gtk_button_new_with_label("close");
Packit 47f805
    gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
Packit 47f805
                              GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(textwindow));
Packit 47f805
Packit 47f805
    box = gtk_text_new(NULL, NULL);
Packit 47f805
    gtk_text_set_editable(GTK_TEXT(box), FALSE);
Packit 47f805
    vscrollbar = gtk_vscrollbar_new(GTK_TEXT(box)->vadj);
Packit 47f805
Packit 47f805
Packit 47f805
    switch (option) {
Packit 47f805
    case 0:
Packit 47f805
        gtk_window_set_title(GTK_WINDOW(textwindow), "Documentation");
Packit 47f805
        gtk_widget_set_usize(box, 450, 500);
Packit 47f805
        gtk_text_set_word_wrap(GTK_TEXT(box), TRUE);
Packit 47f805
        /* text should be moved outside this function, may be in a separate file */
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
Packit 47f805
                        "Frame header information: "
Packit 47f805
                        "First the bitrate, sampling frequency and mono, stereo or jstereo "
Packit 47f805
                        "indicators are displayed .  If the bitstream is jstereo, then mid/side "
Packit 47f805
                        "stereo or intensity stereo may be on (indicated in red).  If "
Packit 47f805
                        "de-emphasis is used, this is also indicated in red.  The mdb value is "
Packit 47f805
                        "main_data_begin.  The encoded data starts this many bytes *before* the "
Packit 47f805
                        "frame header.  A large value of mdb means the bitstream has saved some "
Packit 47f805
                        "bits into the reservoir, which it may allocate for some future frame. "
Packit 47f805
                        "The two numbers after mdb are the size (in bits) used to encode the "
Packit 47f805
                        "MDCT coefficients for this frame, followed byt the size of the bit "
Packit 47f805
                        "resevoir before encoding this frame.  The maximum frame size and a "
Packit 47f805
                        "running average are given in the Stats pull down menu.  A large "
Packit 47f805
                        "maximum frame size indicates the bitstream has made use of the bit "
Packit 47f805
                        "reservoir. \n\n", -1);
Packit 47f805
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
Packit 47f805
                        "PCM data (top graph): "
Packit 47f805
                        "The PCM data is plotted in black.  The layer3 frame is divided into 2 "
Packit 47f805
                        "granules of 576 samples (marked with yellow vertical lines).  In the "
Packit 47f805
                        "case of normal, start and stop blocks, the MDCT coefficients for each "
Packit 47f805
                        "granule are computed using a 1152 sample window centered over the "
Packit 47f805
                        "granule.  In the case of short blocks, the granule is further divided "
Packit 47f805
                        "into 3 blocks of 192 samples (also marked with yellow vertical lines)."
Packit 47f805
                        "The MDCT coefficients for these blocks are computed using 384 sample "
Packit 47f805
                        "windows centered over the 192 sample window.  (This info not available "
Packit 47f805
                        "when analyzing .mp3 files.)  For the psycho-acoustic model, a windowed "
Packit 47f805
                        "FFT is computed for each granule.  The range of these windows "
Packit 47f805
                        "is denoted by the blue and green bars.\n\n", -1);
Packit 47f805
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
Packit 47f805
                        "PCM re-synthesis data (second graph): "
Packit 47f805
                        "Same as the PCM window described above.  The data displayed is the "
Packit 47f805
                        "result of encoding and then decoding the original sample. \n\n", -1);
Packit 47f805
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
Packit 47f805
                        "MDCT windows: "
Packit 47f805
                        "Shows the energy in the MDCT spectrum for granule 0 (left window) "
Packit 47f805
                        "and granule 1 (right window).  The text also shows the blocktype "
Packit 47f805
                        "used, the number of bits used to encode the coefficients and the "
Packit 47f805
                        "number of extra bits allocated from the reservoir.  The MDCT pull down "
Packit 47f805
                        "window will toggle between the original unquantized MDCT coefficients "
Packit 47f805
                        "and the compressed (quantized) coefficients.\n\n", -1);
Packit 47f805
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
Packit 47f805
                        "FFT window: "
Packit 47f805
                        "The gray bars show the energy in the FFT spectrum used by the "
Packit 47f805
                        "psycho-acoustic model.  Granule 0 is in the left window, granule 1 in "
Packit 47f805
                        "the right window.  The green and blue bars show how much distortion is "
Packit 47f805
                        "allowable, as computed by the psycho-acoustic model. The red bars show "
Packit 47f805
                        "the actual distortion after encoding.  There is one FFT for each "
Packit 47f805
                        "granule, computed with a 1024 Hann window centered over the "
Packit 47f805
                        "appropriate granule.  (the range of this 1024 sample window is shown "
Packit 47f805
                        "by the blue and green bars in the PCM data window).  The Spectrum pull "
Packit 47f805
                        "down window will toggle between showing the energy in equally spaced "
Packit 47f805
                        "frequency domain and the scale factor bands used by layer3.  Finally, "
Packit 47f805
                        "the perceptual entropy, total energy and number of scalefactor bands "
Packit 47f805
                        "with audible distortion is shown.  (This info not available when "
Packit 47f805
                        "analyzing .mp3 files.)", -1);
Packit 47f805
Packit 47f805
        break;
Packit 47f805
    case 1:
Packit 47f805
        /* Set the about box information */
Packit 47f805
        gtk_window_set_title(GTK_WINDOW(textwindow), "About");
Packit 47f805
        gtk_widget_set_usize(box, 350, 260);
Packit 47f805
Packit 47f805
        sprintf(text, "LAME version %s \n%s\n\n", get_lame_version(), get_lame_url());
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
Packit 47f805
        sprintf(text, "psycho-acoustic model:  GPSYCHO version %s\n", get_psy_version());
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
Packit 47f805
        sprintf(text, "frame analyzer: MP3x version %s\n\n", get_mp3x_version());
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
Packit 47f805
                        "decoder:  mpg123/mpglib  .59q  \nMichael Hipp (www.mpg123.de)\n\n", -1);
Packit 47f805
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL,
Packit 47f805
                        "Encoder, decoder & psy-models based on ISO\ndemonstration source. ", -1);
Packit 47f805
        break;
Packit 47f805
Packit 47f805
    case 2:
Packit 47f805
        gtk_window_set_title(GTK_WINDOW(textwindow), "Statistics");
Packit 47f805
        gtk_widget_set_usize(box, 350, 260);
Packit 47f805
        sprintf(text, "frames processed so far: %i \n", Pinfo[0].frameNum + 1);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "granules processed so far: %i \n\n", 4 * (Pinfo[0].frameNum + 1));
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "mean bits/frame (approximate): %i\n", gtkinfo.approxbits);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "mean bits/frame (from LAME): %i\n", 4 * Pinfo[0].mean_bits);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "bitsize of largest frame: %i \n", gtkinfo.maxbits);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "average bits/frame: %3.1f \n\n", gtkinfo.avebits);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "ms_stereo frames: %i \n", gtkinfo.totms);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "i_stereo frames: %i \n", gtkinfo.totis);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "de-emphasis frames: %i \n", gtkinfo.totemph);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "short block granules: %i \n", gtkinfo.totshort);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "mixed block granules: %i \n", gtkinfo.totmix);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        sprintf(text, "preflag granules: %i \n", gtkinfo.totpreflag);
Packit 47f805
        gtk_text_insert(GTK_TEXT(box), NULL, NULL, NULL, text, -1);
Packit 47f805
        break;
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
    gtk_widget_show(vscrollbar);
Packit 47f805
    gtk_widget_show(box);
Packit 47f805
    gtk_widget_show(vbox);
Packit 47f805
    gtk_widget_show(hbox);
Packit 47f805
    gtk_widget_show(button);
Packit 47f805
Packit 47f805
    gtk_box_pack_start(GTK_BOX(hbox), box, FALSE, TRUE, 0);
Packit 47f805
    gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
Packit 47f805
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
Packit 47f805
    gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, TRUE, 0);
Packit 47f805
    gtk_container_add(GTK_CONTAINER(textwindow), vbox);
Packit 47f805
    gtk_widget_show(textwindow);
Packit 47f805
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/* #include <strings.h>*/
Packit 47f805
Packit 47f805
Packit 47f805
/* This is the GtkItemFactoryEntry structure used to generate new menus.
Packit 47f805
   Item 1: The menu path. The letter after the underscore indicates an
Packit 47f805
           accelerator key once the menu is open.
Packit 47f805
   Item 2: The accelerator key for the entry
Packit 47f805
   Item 3: The callback function.
Packit 47f805
   Item 4: The callback action.  This changes the parameters with
Packit 47f805
           which the function is called.  The default is 0.
Packit 47f805
   Item 5: The item type, used to define what kind of an item it is.
Packit 47f805
           Here are the possible values:
Packit 47f805
Packit 47f805
           NULL               -> "<Item>"
Packit 47f805
           ""                 -> "<Item>"
Packit 47f805
           "<Title>"          -> create a title item
Packit 47f805
           "<Item>"           -> create a simple item
Packit 47f805
           "<CheckItem>"      -> create a check item
Packit 47f805
           "<ToggleItem>"     -> create a toggle item
Packit 47f805
           "<RadioItem>"      -> create a radio item
Packit 47f805
           <path>             -> path of a radio item to link against
Packit 47f805
           "<Separator>"      -> create a separator
Packit 47f805
           "<Branch>"         -> create an item to hold sub items
Packit 47f805
           "<LastBranch>"     -> create a right justified branch
Packit 47f805
*/
Packit 47f805
Packit 47f805
Packit 47f805
#define C(chr)       "<control>" #chr
Packit 47f805
#define func(name)   (GtkItemFactoryCallback) (name)
Packit 47f805
Packit 47f805
static const GtkItemFactoryEntry menu_items[] = {
Packit 47f805
    {"/_File", NULL, NULL, 0, "<Branch>"},
Packit 47f805
#if 0
Packit 47f805
    {"/File/_New", C(N), func(print_hello), 0, NULL},
Packit 47f805
    {"/File/_Open", C(O), func(print_hello), 0, NULL},
Packit 47f805
    {"/File/_Save", C(S), func(print_hello), 0, NULL},
Packit 47f805
    {"/File/Save _As", NULL, NULL, 0, NULL},
Packit 47f805
    {"/File/sep1", NULL, NULL, 0, "<Separator>"},
Packit 47f805
    {"/File/Quit", C(Q), func(gtk_main_quit), 0, NULL},
Packit 47f805
#endif
Packit 47f805
    {"/File/_Quit", C(Q), func(delete_event), 0, NULL},
Packit 47f805
Packit 47f805
    {"/_Plotting", NULL, NULL, 0, "<Branch>"},
Packit 47f805
    {"/Plotting/_While advancing", NULL, func(spec_option), 5, NULL},
Packit 47f805
    {"/Plotting/_After advancing", NULL, func(spec_option), 6, NULL},
Packit 47f805
    {"/Plotting/Toggle SFB lines", NULL, func(spec_option), 7, NULL},
Packit 47f805
    {"/Plotting/Toggle orig-diff", NULL, func(spec_option), 8, NULL},
Packit 47f805
Packit 47f805
    {"/_Channel", NULL, NULL, 0, "<Branch>"},
Packit 47f805
    {"/Channel/show _Left", NULL, func(channel_option), 1, NULL},
Packit 47f805
    {"/Channel/show _Right", NULL, func(channel_option), 2, NULL},
Packit 47f805
    {"/Channel/show _Mid", NULL, func(channel_option), 3, NULL},
Packit 47f805
    {"/Channel/show _Side", NULL, func(channel_option), 4, NULL},
Packit 47f805
Packit 47f805
    {"/_Spectrum", NULL, NULL, 0, "<Branch>"},
Packit 47f805
    {"/Spectrum/_Scalefactor bands", NULL, func(spec_option), 1, NULL},
Packit 47f805
    {"/Spectrum/_Wave number", NULL, func(spec_option), 2, NULL},
Packit 47f805
Packit 47f805
    {"/_MDCT", NULL, NULL, 0, "<Branch>"},
Packit 47f805
    {"/MDCT/_Original", NULL, func(spec_option), 3, NULL},
Packit 47f805
    {"/MDCT/_Compressed", NULL, func(spec_option), 4, NULL},
Packit 47f805
    {"/MDCT/_Toggle SFB lines", NULL, func(spec_option), 7, NULL},
Packit 47f805
Packit 47f805
    {"/_Stats", NULL, NULL, 0, "<Branch>"},
Packit 47f805
    {"/Stats/_Show", NULL, func(text_window), 2, NULL},
Packit 47f805
Packit 47f805
    {"/_Help", NULL, NULL, 0, "<LastBranch>"},
Packit 47f805
    {"/_Help/_Documentation", NULL, func(text_window), 0, NULL},
Packit 47f805
    {"/_Help/_About", NULL, func(text_window), 1, NULL},
Packit 47f805
};
Packit 47f805
Packit 47f805
#undef C
Packit 47f805
#undef func
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
get_main_menu(GtkWidget * windows, GtkWidget ** menubar)
Packit 47f805
{
Packit 47f805
    unsigned int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
Packit 47f805
    GtkItemFactory *item_factory;
Packit 47f805
    GtkAccelGroup *accel_group;
Packit 47f805
Packit 47f805
    accel_group = gtk_accel_group_new();
Packit 47f805
Packit 47f805
    /* This function initializes the item factory.
Packit 47f805
       Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU,
Packit 47f805
       or GTK_TYPE_OPTION_MENU.
Packit 47f805
       Param 2: The path of the menu.
Packit 47f805
       Param 3: A pointer to a gtk_accel_group.  The item factory sets up
Packit 47f805
       the accelerator table while generating menus.
Packit 47f805
     */
Packit 47f805
Packit 47f805
    item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
Packit 47f805
Packit 47f805
    /* This function generates the menu items. Pass the item factory,
Packit 47f805
       the number of items in the array, the array itself, and any
Packit 47f805
       callback data for the the menu items. */
Packit 47f805
    gtk_item_factory_create_items(item_factory, nmenu_items, (GtkItemFactoryEntry *) menu_items,
Packit 47f805
                                  NULL);
Packit 47f805
Packit 47f805
    /* Attach the new accelerator group to the window. */
Packit 47f805
    gtk_accel_group_attach(accel_group, GTK_OBJECT(windows));
Packit 47f805
Packit 47f805
    if (menubar)
Packit 47f805
        /* Finally, return the actual menu bar created by the item factory. */
Packit 47f805
        *menubar = gtk_item_factory_get_widget(item_factory, "<main>");
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
int
Packit 47f805
gtkcontrol(lame_global_flags * gfp2, char *inPath)
Packit 47f805
{
Packit 47f805
    /* GtkWidget is the storage type for widgets */
Packit 47f805
    GtkWidget *button;
Packit 47f805
    GtkAdjustment *adj;
Packit 47f805
    GtkWidget *mbox;         /* main box */
Packit 47f805
    GtkWidget *box1;         /* frame control buttons go */
Packit 47f805
    GtkWidget *box2;         /* frame counters */
Packit 47f805
    GtkWidget *box3;         /* frame header info */
Packit 47f805
    GtkWidget *table;        /* table for all the plotting areas */
Packit 47f805
    GtkWidget *menubar;
Packit 47f805
Packit 47f805
    gint    tableops, graphx, graphy;
Packit 47f805
    char    frameinfo[80];
Packit 47f805
Packit 47f805
    graphx = 600;       /* minimum allowed size of pixmap */
Packit 47f805
    graphy = 95;
Packit 47f805
Packit 47f805
    gfp = gfp2;
Packit 47f805
    gfc = gfp->internal_flags;
Packit 47f805
Packit 47f805
    /* set some global defaults/variables */
Packit 47f805
    gtkinfo.filetype = is_mpeg_file_format(global_reader.input_format) ? 1 : 0;
Packit 47f805
    gtkinfo.msflag = 0;
Packit 47f805
    gtkinfo.chflag = 0;
Packit 47f805
    gtkinfo.kbflag = 0;
Packit 47f805
    gtkinfo.flag123 = is_mpeg_file_format(global_reader.input_format) ? 1 : 0; /* MP3 file=use mpg123 output */
Packit 47f805
    gtkinfo.pupdate = 0;
Packit 47f805
    gtkinfo.avebits = 0;
Packit 47f805
    gtkinfo.maxbits = 0;
Packit 47f805
    gtkinfo.approxbits = 0;
Packit 47f805
    gtkinfo.totemph = 0;
Packit 47f805
    gtkinfo.totms = 0;
Packit 47f805
    gtkinfo.totis = 0;
Packit 47f805
    gtkinfo.totshort = 0;
Packit 47f805
    gtkinfo.totmix = 0;
Packit 47f805
    gtkinfo.sfblines = 1;
Packit 47f805
    gtkinfo.difference = 0;
Packit 47f805
    gtkinfo.totalframes = 0;
Packit 47f805
Packit 47f805
    memset((char *) Pinfo, 0, sizeof(Pinfo));
Packit 47f805
    pplot = &Pinfo[READ_AHEAD];
Packit 47f805
Packit 47f805
    strcpy(frameinfo, "MP3x: ");
Packit 47f805
    strncat(frameinfo, inPath, 70);
Packit 47f805
Packit 47f805
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
Packit 47f805
    gtk_window_set_title(GTK_WINDOW(window), frameinfo);
Packit 47f805
    gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL);
Packit 47f805
Packit 47f805
    gtk_signal_connect_object(GTK_OBJECT(window), "key_press_event",
Packit 47f805
                              GTK_SIGNAL_FUNC(key_press_event), GTK_OBJECT(window));
Packit 47f805
Packit 47f805
    gtk_container_set_border_width(GTK_CONTAINER(window), 0);
Packit 47f805
Packit 47f805
Packit 47f805
    mbox = gtk_vbox_new(FALSE, 0);
Packit 47f805
Packit 47f805
Packit 47f805
    /* layout of mbox */
Packit 47f805
    box1 = gtk_hbox_new(FALSE, 0);
Packit 47f805
    box2 = gtk_hbox_new(FALSE, 0);
Packit 47f805
    box3 = gtk_hbox_new(FALSE, 0);
Packit 47f805
    table = gtk_table_new(5, 2, FALSE);
Packit 47f805
    tableops = GTK_FILL | GTK_EXPAND | GTK_SHRINK;
Packit 47f805
    get_main_menu(window, &menubar);
Packit 47f805
Packit 47f805
    gtk_box_pack_start(GTK_BOX(mbox), menubar, FALSE, TRUE, 0);
Packit 47f805
    gtk_box_pack_end(GTK_BOX(mbox), box1, FALSE, TRUE, 0);
Packit 47f805
    gtk_box_pack_end(GTK_BOX(mbox), box2, FALSE, TRUE, 0);
Packit 47f805
    gtk_box_pack_start(GTK_BOX(mbox), box3, FALSE, TRUE, 0);
Packit 47f805
    gtk_box_pack_start(GTK_BOX(mbox), table, TRUE, TRUE, 0);
Packit 47f805
    gtk_container_add(GTK_CONTAINER(window), mbox);
Packit 47f805
Packit 47f805
Packit 47f805
    /*********************************************************************/
Packit 47f805
    /* stuff in box3  frame header info */
Packit 47f805
    /*********************************************************************/
Packit 47f805
    /*
Packit 47f805
       headerbox = gtk_label_new(" ");
Packit 47f805
       gtk_label_set_justify(GTK_LABEL(headerbox),GTK_JUSTIFY_LEFT);
Packit 47f805
     */
Packit 47f805
    headerbox = gtk_text_new(NULL, NULL);
Packit 47f805
    gtk_text_set_editable(GTK_TEXT(headerbox), FALSE);
Packit 47f805
    gtk_widget_set_usize(headerbox, 200, 20);
Packit 47f805
    gtk_widget_show(headerbox);
Packit 47f805
    gtk_box_pack_start(GTK_BOX(box3), headerbox, TRUE, TRUE, 0);
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
    /*********************************************************************/
Packit 47f805
    /* stuff in box2   frame counters  */
Packit 47f805
    /*********************************************************************/
Packit 47f805
    framecounter = gtk_label_new("");
Packit 47f805
    gtk_widget_show(framecounter);
Packit 47f805
    gtk_box_pack_start(GTK_BOX(box2), framecounter, FALSE, TRUE, 0);
Packit 47f805
Packit 47f805
    adj = (GtkAdjustment *) gtk_adjustment_new(0, 0, (gint) lame_get_totalframes(gfp) - 1, 0, 0, 0);
Packit 47f805
    frameprogress = gtk_progress_bar_new_with_adjustment(adj);
Packit 47f805
    /* Set the format of the string that can be displayed in the
Packit 47f805
     * trough of the progress bar:
Packit 47f805
     * %p - percentage
Packit 47f805
     * %v - value
Packit 47f805
     * %l - lower range value
Packit 47f805
     * %u - upper range value */
Packit 47f805
    gtk_progress_set_format_string(GTK_PROGRESS(frameprogress), "%p%%");
Packit 47f805
    gtk_progress_set_value(GTK_PROGRESS(frameprogress), (gdouble) 0);
Packit 47f805
    gtk_progress_set_show_text(GTK_PROGRESS(frameprogress), TRUE);
Packit 47f805
    gtk_widget_show(frameprogress);
Packit 47f805
    gtk_box_pack_end(GTK_BOX(box2), frameprogress, FALSE, TRUE, 0);
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
    /*********************************************************************/
Packit 47f805
    /* stuff in box1  buttons along bottom */
Packit 47f805
    /*********************************************************************/
Packit 47f805
    button = gtk_button_new_with_label("-1");
Packit 47f805
    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "-1");
Packit 47f805
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
Packit 47f805
    gtk_widget_show(button);
Packit 47f805
Packit 47f805
    button = gtk_button_new_with_label("+1");
Packit 47f805
    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "1");
Packit 47f805
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
Packit 47f805
    gtk_widget_show(button);
Packit 47f805
Packit 47f805
    button = gtk_button_new_with_label("+10");
Packit 47f805
    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "10");
Packit 47f805
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
Packit 47f805
    gtk_widget_show(button);
Packit 47f805
Packit 47f805
    button = gtk_button_new_with_label("+100");
Packit 47f805
    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(frameadv), (gpointer) "100");
Packit 47f805
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
Packit 47f805
    gtk_widget_show(button);
Packit 47f805
Packit 47f805
    button = gtk_button_new_with_label("last frame");
Packit 47f805
    gtk_signal_connect(GTK_OBJECT(button), "clicked",
Packit 47f805
                       GTK_SIGNAL_FUNC(frameadv), (gpointer) "finish");
Packit 47f805
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
Packit 47f805
    gtk_widget_show(button);
Packit 47f805
Packit 47f805
    button = gtk_button_new_with_label("stop/plot");
Packit 47f805
    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(plotclick), NULL);
Packit 47f805
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
Packit 47f805
    gtk_widget_show(button);
Packit 47f805
Packit 47f805
Packit 47f805
    /*********************************************************************/
Packit 47f805
    /* stuff in table.  all the plotting windows */
Packit 47f805
    /*********************************************************************/
Packit 47f805
    pcmbox = gpk_plot_new(graphx, graphy);
Packit 47f805
    gtk_table_attach(GTK_TABLE(table), pcmbox, 0, 2, 0, 1, tableops, tableops, 2, 2);
Packit 47f805
    gtk_widget_show(pcmbox);
Packit 47f805
Packit 47f805
    winbox = gpk_plot_new(graphy, graphy);
Packit 47f805
    gtk_table_attach(GTK_TABLE(table), winbox, 0, 2, 1, 2, tableops, tableops, 2, 2);
Packit 47f805
    gtk_widget_show(winbox);
Packit 47f805
Packit 47f805
Packit 47f805
    mdctbox[0] = gpk_plot_new(graphy, graphy);
Packit 47f805
    gtk_table_attach(GTK_TABLE(table), mdctbox[0], 0, 1, 2, 3, tableops, tableops, 2, 2);
Packit 47f805
    gtk_widget_show(mdctbox[0]);
Packit 47f805
Packit 47f805
    mdctbox[1] = gpk_plot_new(graphy, graphy);
Packit 47f805
    gtk_table_attach(GTK_TABLE(table), mdctbox[1], 1, 2, 2, 3, tableops, tableops, 2, 2);
Packit 47f805
    gtk_widget_show(mdctbox[1]);
Packit 47f805
Packit 47f805
    enerbox[0] = gpk_plot_new(graphy, graphy);
Packit 47f805
    gtk_table_attach(GTK_TABLE(table), enerbox[0], 0, 1, 3, 4, tableops, tableops, 2, 2);
Packit 47f805
    gtk_widget_show(enerbox[0]);
Packit 47f805
Packit 47f805
    enerbox[1] = gpk_plot_new(graphy, graphy);
Packit 47f805
    gtk_table_attach(GTK_TABLE(table), enerbox[1], 1, 2, 3, 4, tableops, tableops, 2, 2);
Packit 47f805
    gtk_widget_show(enerbox[1]);
Packit 47f805
Packit 47f805
    sfbbox[0] = gpk_plot_new(graphy, graphy);
Packit 47f805
    gtk_table_attach(GTK_TABLE(table), sfbbox[0], 0, 1, 4, 5, tableops, tableops, 2, 2);
Packit 47f805
    gtk_widget_show(sfbbox[0]);
Packit 47f805
Packit 47f805
    sfbbox[1] = gpk_plot_new(graphy, graphy);
Packit 47f805
    gtk_table_attach(GTK_TABLE(table), sfbbox[1], 1, 2, 4, 5, tableops, tableops, 2, 2);
Packit 47f805
    gtk_widget_show(sfbbox[1]);
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
    gtk_idle_add((GtkFunction) frameadv1, NULL);
Packit 47f805
    gtk_widget_show(menubar);
Packit 47f805
    gtk_widget_show(box2);
Packit 47f805
    gtk_widget_show(box3);
Packit 47f805
    gtk_widget_show(table);
Packit 47f805
    gtk_widget_show(box1);
Packit 47f805
    gtk_widget_show(mbox);
Packit 47f805
    gtk_widget_show(window); /* show smallest allowed window */
Packit 47f805
Packit 47f805
    /* make window bigger.   */
Packit 47f805
    /* now the user will be able to shrink it, if desired */
Packit 47f805
    /* gtk_widget_set_usize(mbox,500,500);  */
Packit 47f805
    /* gtk_widget_show (window); */ /* show smallest allowed window */
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
    idle_keepgoing = 1; /* processing of frames is ON */
Packit 47f805
    idle_count_max = READ_AHEAD + 1; /* number of frames to process before plotting */
Packit 47f805
    idle_count = 0;     /* pause & plot when idle_count=idle_count_max */
Packit 47f805
Packit 47f805
    gtk_main();
Packit 47f805
Packit 47f805
    assert(mp3done);
Packit 47f805
    return (0);
Packit 47f805
}