#include <fstream.h>
#include <iomanip.h>
#include <stdlib.h>

#define DEBUG 1             /* turns debugging on */
#define BFADEBUG 0          /* turns BufferedFileAccess debugging on */
#define BUFFER 128          /* maximal size of buffer in kilobytes, is reduced automatically if not enough ram available */

char *vers = "$VER: MpegAnalys-r 0.4 [05. November 2000]";

int errors=0;

/// buffered file access
class bufferedfileaccess   // speeds up file access  VERSION 1.10 (05. November 2000)
{
  private:
    long buffersize;       // size of the data buffer
    long datasize;         // size of the read data in buffer
    long firstposition;    // the file position of the first byte in buffer
    long lastposition;     // the file position of the last byte in buffer
    char *dataptr;         // the pointer to the actual databuffer
   short error;            // everything ok?
 fstream in;               // file pointer
    long getreads;         // number of reads from get(), just for internal checking
    long seekreads;        // number of reads form seek(), just for internal checking
  public:
    long filesize;         // size of the file
    long actualposition;   // pointer to the next byte in buffer
    bufferedfileaccess(char *filename) // counstructor requires name of file to buffer
    {
        buffersize=2*BUFFER*1024;   // calculate buffersize
        datasize=0;
        firstposition=0;
        lastposition=0;
        dataptr=0;
        error=0;

        getreads=0;
        seekreads=0;

        filesize=0;
        actualposition=0;
        in.open(filename,ios::in);  // open file
        if (in.is_open())
        {
            in.seekg(0, ios::end);  // move to last byte
            filesize=in.tellg();    // get size of file
            if (BFADEBUG) cout<<" filesize: "<<filesize<<", buffersize: "<<buffersize<<endl;
            in.seekg(0, ios::beg);  // move back to start
            if (filesize > 1)       // check if file is large enough
            {
                if (filesize < buffersize/2)
                {
                    buffersize=filesize*2;  // file is smaller than the buffer could hold
                }
                do                        // allocate memory for buffer with automatic adaption for low memory
                {
                    if (buffersize==1)
                    {
                        cout <<"Error while allocating file buffer"<<endl;
                        errors++;
                        return;
                    }
                    buffersize=buffersize/2;
                    dataptr=new char[buffersize];
                } while (!dataptr);
                in.read(dataptr, buffersize);  // fill the buffer with the first data from file
                datasize=buffersize;
                lastposition=(in.tellg())-1;   // save fileposition of last byte
                if (BFADEBUG) cout<<" buffersize: "<<buffersize<<",lastposition: "<<lastposition<<endl;
            }
            else // filesize < 2
            {
                cout <<"Error, inputfile \""<<filename<<"\" is too small."<<endl;
                errors++;
            }
        }
        else // in.is_open
        {
            cout <<"Error while opening inputfile: "<<filename<<endl;
            errors++;
        }
        if (BFADEBUG) cout <<this<<" created"<<endl;
        if (BFADEBUG) cout <<" actualposition: "<<actualposition<<", firstposition: "<<firstposition<<", lastposition: "<<lastposition<<endl;
        return;
    }
    ~bufferedfileaccess() // destructor
    {
        delete[] dataptr;
        dataptr=0;
        in.seekg(0, ios::beg);
        in.close();
        if (BFADEBUG) cout <<this<<" removed"<<endl;
        if (BFADEBUG) cout <<"getreads: "<<getreads<<", seekreads: "<<seekreads<<endl;
        return;
    }
    char get()
    {
        char retchar;                                  // the char to be returned
        if ((actualposition >= 0) && (actualposition <= datasize))  // inside buffer
        {
            retchar=dataptr[actualposition];               // extract it from buffer
            actualposition++;                              // increase bufferpointer
        }
        else  // outside buffer
        {
            cout <<"Error, getting outside buffer/file"<<endl;
            retchar=0;
            error=1;
        }
        if (BFADEBUG) cout <<"get(): "<<retchar<<", actualposition: "<<actualposition<<", firstposition: "<<firstposition<<", lastposition: "<<lastposition<<", datasize: "<<datasize<<endl;
        if (actualposition >= datasize)                  // check, if outside of buffer now
        {
            if (BFADEBUG) cout <<"actualposition >= datasize"<<endl;
            if (!eof())
            {
                if (BFADEBUG) cout <<"!eof(), firstposition+actualposition: "<<firstposition+actualposition<<endl;
                in.seekg(firstposition+actualposition, ios::beg);
                firstposition=in.tellg();                  // actualise firstposition
                if (BFADEBUG) cout <<"firstposition: "<<firstposition<<endl;
                actualposition=0;                          // actualise bufferpointer
                if (filesize < firstposition+buffersize)   // check, if remaining file is smaller than the buffer
                {
                    datasize=filesize-firstposition;       // adapt buffersize (doesn't adapt the real size of buffer)
                }
                in.read(dataptr, datasize);                // read in next data from file to buffer
                getreads++;
                lastposition=(in.tellg())-1;               // actualise lastposition
            }
        }
        return retchar;                                // this is what the function should do ;-)
    }
    void seek(long seekposition, short option=0)
    {
        if (option > 0)
        {
            seekposition=(actualposition+firstposition)+seekposition;
        }
        if (option < 0)
        {
            seekposition=(actualposition+firstposition)-seekposition;
        }
        if (BFADEBUG) cout <<"seek()in actualposition: "<<actualposition<<", firstposition: "<<firstposition<<", lastposition: "<<lastposition<<endl;
        if (seekposition >= filesize)
        {
            seekposition=filesize-1;
        }
        if ((seekposition >= firstposition) && (seekposition <= lastposition))
        {
            actualposition=seekposition-firstposition;
            if (BFADEBUG) cout <<"actualposition: "<<actualposition<<endl;
        }
        else
        {
            if (filesize < seekposition+buffersize)
            {
                in.seekg(filesize-buffersize, ios::beg);
            }
            else
            {
                in.seekg(seekposition, ios::beg);
            }
            firstposition=in.tellg();
            actualposition=seekposition-firstposition;
            datasize=buffersize;
            in.read(dataptr, datasize);
            seekreads++;
            lastposition=(in.tellg())-1;
            if (BFADEBUG) cout <<"seek()out actualposition: "<<actualposition<<", firstposition: "<<firstposition<<", lastposition: "<<lastposition<<endl;
        }
        return;
    }
    short eof()
    {
        short end=0;
        if(firstposition+actualposition >= filesize)
        {
            end=1;
        }
        return end;
    }
    short bad()
    {
        return error;
    }
};
///
/// class frame
class frame
{
  public:
     long position;      // the absolute position of the first headerbyte in file
    short invalidheader; // BOOL, indicates whether this frame is ok
    short framelength;   // contains expected length of frame in bytes, calculated from header
    short headercounter;
    // Mpeg Information
    short id;
    short layer;
    short bitrate;
     long frequency;
    short protection;    // BOOL
    short priv;          // BOOL
    short padding;       // BOOL, indicates whether an additional bit is present
    frame()
    {
        invalidheader=0;
        framelength=0;
        id=0;
        layer=0;
        bitrate=0;
        frequency=0;
        protection=0;
        priv=0;
        padding=0;
        // cout <<this<<" created"<<endl;
    }
    ~frame()
    {
        // cout <<this<<" removed"<<endl;
    }
};
///
/// chartoulong()
long chartoulong(char zeichen)
{
    long zeichen2=long(zeichen);
    if (zeichen2 < 0)
    {
        zeichen2=256+zeichen2;
    }
    return zeichen2;
}
///
/// istag()
short istag(bufferedfileaccess *file)
{
    long check=0;
    short tag=1;
    for (short idx=1;idx<124;idx++)
    {
        check=chartoulong(file->get());
        if (!((check >= 32 && check <= 126) || (check >= 160 && check <=255)))
        {
            tag=0;
        }
    }
    file->seek(123,-1);
    return tag;
}
///
/// showtag()
void showtag(bufferedfileaccess *file)
{
    cout <<"  Title: \"";
    for (short idx=1;idx<=30;idx++)
    {
        cout <<file->get();
    }
    cout <<"\"\n Artist: \"";
    for (short idx=1;idx<=30;idx++)
    {
        cout <<file->get();
    }
    cout <<"\"\n  Album: \"";
    for (short idx=1;idx<=30;idx++)
    {
        cout <<file->get();
    }
    cout <<"\"\n   Year: \"";
    for (short idx=1;idx<=4;idx++)
    {
        cout <<file->get();
    }
    cout <<"\"\nComment: \"";
    for (short idx=1;idx<=30;idx++)
    {
        cout <<file->get();
    }
    cout <<"\""<<endl;
    file->seek(124,-1);
    return;
}
///
/// main
int main(int argc, char **argv)
{
    bufferedfileaccess *file=0;
    class frame *thisframeptr=0, *lastframeptr=0, *errorframeptr=0, *lastvalidframeptr=0, *nextvalidframeptr=0;
    short infolevel=0, headercounter=0;
    char header[3]={0,0,0};
    long checkbits=0;
    long firstvalidframe=-1, currentposition=0, framingerrors=0, invalidtagcounter=0;
    cout <<"|      MpegAnalys-r  0.4      |"<<endl;
    cout <<"| by radiat-r@Sascha-Ploss.de |"<<endl;
    if (argc > 3) cout <<"Wrong parameters\nUsage: "<<argv[0]<<" filename [infolevel]"<<endl;
    if (argc > 2) infolevel=atoi(argv[2]);
    file=new bufferedfileaccess(argv[1]);
    if (file)
    {
        header[0]=file->get(); // get first header
        header[1]=file->get(); // get first header
        header[2]=file->get(); // get first header
        while (!file->eof() && !file->bad())   // loop till eof
        {
/* ---------------- Main Program Loop ------------------------------- */
            checkbits=(chartoulong(header[1]))/32; // remove the last 5 bits from char
            //if (DEBUG) cout <<"  char: "<<header[1]<<", long: "<<long(header[1])<<" uchar: "<<chartoulong(header[1])<<", checkbits: "<<checkbits<<endl;
            if ((checkbits == 7) && (header[0] == 'ÿ')) // sync found (11 set bits)
            {
                thisframeptr=new frame;
                if (thisframeptr)
                {
                    thisframeptr->position=currentposition;
                    thisframeptr->headercounter=headercounter;
// -------------- checking frame information ------------------
                    checkbits=((chartoulong(header[1]))/8)-28;   // get the id bytes                                                                                                                                                                                                                                                                                                                                                                                                                 ----
                    thisframeptr->id=4-checkbits;   // id == 4 is Mpeg 2.5
                    if (thisframeptr->id == 3)
                    {
                        thisframeptr->invalidheader=1;
                    }
                    checkbits=((chartoulong(header[1]))-(((chartoulong(header[1]))/8)*8))/2; // get the layer bytes
                    thisframeptr->layer=4-checkbits;
                    if (thisframeptr->layer == 4)
                    {                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ----
                        thisframeptr->invalidheader=1;
                    }
                    checkbits=(chartoulong(header[1]))-((header[1]/2)*2); // get protection bit
                    if (!checkbits)
                    {
                        thisframeptr->protection=1;
                    }
                    checkbits=(chartoulong(header[2]))/16;
                    if ((checkbits < 1) || (checkbits > 14))
                    {
                        thisframeptr->invalidheader=1;
                    }
                    else
                    {
                        if (thisframeptr->id == 1)
                        {
                            if (thisframeptr->layer == 1)
                            {
                                if (checkbits == 1) thisframeptr->bitrate=32;
                                else if (checkbits == 2) thisframeptr->bitrate=64;
                                else if (checkbits == 3) thisframeptr->bitrate=96;
                                else if (checkbits == 4) thisframeptr->bitrate=128;
                                else if (checkbits == 5) thisframeptr->bitrate=160;
                                else if (checkbits == 6) thisframeptr->bitrate=192;
                                else if (checkbits == 7) thisframeptr->bitrate=224;
                                else if (checkbits == 8) thisframeptr->bitrate=256;
                                else if (checkbits == 9) thisframeptr->bitrate=288;
                                else if (checkbits == 10) thisframeptr->bitrate=320;
                                else if (checkbits == 11) thisframeptr->bitrate=352;
                                else if (checkbits == 12) thisframeptr->bitrate=384;
                                else if (checkbits == 13) thisframeptr->bitrate=416;
                                else if (checkbits == 14) thisframeptr->bitrate=448;
                            }
                            else if (thisframeptr->layer == 2)
                            {
                                if (checkbits == 1) thisframeptr->bitrate=32;
                                else if (checkbits == 2) thisframeptr->bitrate=48;
                                else if (checkbits == 3) thisframeptr->bitrate=56;
                                else if (checkbits == 4) thisframeptr->bitrate=64;
                                else if (checkbits == 5) thisframeptr->bitrate=80;
                                else if (checkbits == 6) thisframeptr->bitrate=96;
                                else if (checkbits == 7) thisframeptr->bitrate=112;
                                else if (checkbits == 8) thisframeptr->bitrate=128;
                                else if (checkbits == 9) thisframeptr->bitrate=160;
                                else if (checkbits == 10) thisframeptr->bitrate=192;
                                else if (checkbits == 11) thisframeptr->bitrate=224;
                                else if (checkbits == 12) thisframeptr->bitrate=256;
                                else if (checkbits == 13) thisframeptr->bitrate=320;
                                else if (checkbits == 14) thisframeptr->bitrate=384;
                            }
                            else if (thisframeptr->layer == 3)
                            {
                                if (checkbits == 1) thisframeptr->bitrate=32;
                                else if (checkbits == 2) thisframeptr->bitrate=40;
                                else if (checkbits == 3) thisframeptr->bitrate=48;
                                else if (checkbits == 4) thisframeptr->bitrate=56;
                                else if (checkbits == 5) thisframeptr->bitrate=64;
                                else if (checkbits == 6) thisframeptr->bitrate=80;
                                else if (checkbits == 7) thisframeptr->bitrate=96;
                                else if (checkbits == 8) thisframeptr->bitrate=112;
                                else if (checkbits == 9) thisframeptr->bitrate=128;
                                else if (checkbits == 10) thisframeptr->bitrate=160;
                                else if (checkbits == 11) thisframeptr->bitrate=192;
                                else if (checkbits == 12) thisframeptr->bitrate=224;
                                else if (checkbits == 13) thisframeptr->bitrate=256;
                                else if (checkbits == 14) thisframeptr->bitrate=320;
                            }
                        }
                        else // id == 2 or 2.5
                        {
                            if (thisframeptr->layer == 1)
                            {
                                if (checkbits == 1) thisframeptr->bitrate=32;
                                else if (checkbits == 2) thisframeptr->bitrate=48;
                                else if (checkbits == 3) thisframeptr->bitrate=56;
                                else if (checkbits == 4) thisframeptr->bitrate=64;
                                else if (checkbits == 5) thisframeptr->bitrate=80;
                                else if (checkbits == 6) thisframeptr->bitrate=96;
                                else if (checkbits == 7) thisframeptr->bitrate=112;
                                else if (checkbits == 8) thisframeptr->bitrate=128;
                                else if (checkbits == 9) thisframeptr->bitrate=144;
                                else if (checkbits == 10) thisframeptr->bitrate=160;
                                else if (checkbits == 11) thisframeptr->bitrate=176;
                                else if (checkbits == 12) thisframeptr->bitrate=192;
                                else if (checkbits == 13) thisframeptr->bitrate=224;
                                else if (checkbits == 14) thisframeptr->bitrate=256;
                            }
                            else if ((thisframeptr->layer == 2) || (thisframeptr->layer == 3)) // layer 2 or 3
                            {
                                if (checkbits == 1) thisframeptr->bitrate=8;
                                else if (checkbits == 2) thisframeptr->bitrate=16;
                                else if (checkbits == 3) thisframeptr->bitrate=24;
                                else if (checkbits == 4) thisframeptr->bitrate=32;
                                else if (checkbits == 5) thisframeptr->bitrate=40;
                                else if (checkbits == 6) thisframeptr->bitrate=48;
                                else if (checkbits == 7) thisframeptr->bitrate=56;
                                else if (checkbits == 8) thisframeptr->bitrate=64;
                                else if (checkbits == 9) thisframeptr->bitrate=80;
                                else if (checkbits == 10) thisframeptr->bitrate=96;
                                else if (checkbits == 11) thisframeptr->bitrate=112;
                                else if (checkbits == 12) thisframeptr->bitrate=128;
                                else if (checkbits == 13) thisframeptr->bitrate=144;
                                else if (checkbits == 14) thisframeptr->bitrate=160;
                            }
                        }
                    }
                    checkbits=((chartoulong(header[2]))-(((chartoulong(header[2]))/16)*16))/4; // get the sampling frequency bits
                    if (checkbits == 3)
                    {
                        thisframeptr->invalidheader=1;
                    }
                    else
                    {
                        if (thisframeptr->id == 1)
                        {
                            if (checkbits == 0)
                            {
                                thisframeptr->frequency=44100;
                            }
                            else if (checkbits == 1)
                            {
                                thisframeptr->frequency=48000;
                            }
                            else
                            {
                                thisframeptr->frequency=32000;
                            }
                        }
                        else if (thisframeptr->id == 2)
                        {
                            if (checkbits == 0)
                            {
                                thisframeptr->frequency=22050;
                            }
                            else if (checkbits == 1)
                            {
                                thisframeptr->frequency=24000;
                            }
                            else
                            {
                                thisframeptr->frequency=16000;
                            }
                        }
                        else if (thisframeptr->id == 4)
                        {
                            if (checkbits == 0)
                            {
                                thisframeptr->frequency=11025;
                            }
                            else if (checkbits == 1)
                            {
                                thisframeptr->frequency=12000;
                            }
                            else
                            {
                                thisframeptr->frequency=8000;
                            }
                        }
                    }
                    checkbits=((chartoulong(header[2]))-((chartoulong(header[2]))/4)*4)/2; // get padding bit
                    if (checkbits)
                    {
                        thisframeptr->padding=1;
                    }
                    checkbits=(chartoulong(header[2]))-(((chartoulong(header[2]))/2)*2); // get private bit
                    if (checkbits)
                    {
                        thisframeptr->priv=1;
                    }

                    // add here some code to check the last 8 bit

                    if ((thisframeptr->frequency) && (thisframeptr->bitrate))
                    {
                        if (thisframeptr->layer == 1)  // calculate framelength from header
                        {
                            thisframeptr->framelength = (((12*thisframeptr->bitrate*1000)/thisframeptr->frequency)+thisframeptr->padding)*4;
                        }
                        else
                        {
                            thisframeptr->framelength = ((144*thisframeptr->bitrate*1000)/thisframeptr->frequency)+thisframeptr->padding;
                        }
                    }
                    else
                    {
                        thisframeptr->framelength=0;
                    }
// ------------- checking complete --------------------------
                    if (!(thisframeptr->invalidheader))  // header is valid
                    {
                        // if (DEBUG) cout <<" + "; // validheader
                        if (lastframeptr)
                        {  // this is not the first frame
                            if ((thisframeptr->position) == ((lastframeptr->position)+(lastframeptr->framelength)))
                            {  // framelength is OK
                                if (nextvalidframeptr)
                                { // there's still a bad frame before
                                    if (nextvalidframeptr->position == lastframeptr->position)
                                    {
                                        cout <<"Frame "<<setw(5)<<lastvalidframeptr->headercounter<<" @ byte "<<setw(8)<<lastvalidframeptr->position<<" is "<<((nextvalidframeptr->position)-(lastvalidframeptr->position))-(lastvalidframeptr->framelength)<<" bytes too large."<<endl;
                                    }
                                    else
                                    {
                                        cout <<"Frame "<<setw(5)<<lastvalidframeptr->headercounter<<" @ byte "<<setw(8)<<lastvalidframeptr->position<<" is "<<(lastvalidframeptr->position)+(lastvalidframeptr->framelength)-(lastframeptr->position)<<" bytes too short."<<endl;
                                    }
                                    framingerrors++;
                                    delete nextvalidframeptr;
                                    nextvalidframeptr=0;
                                    delete lastvalidframeptr;
                                    lastvalidframeptr=0;
                                }
                                if (infolevel)
                                {
                                    if (infolevel > 1)
                                    {
                                        if (lastframeptr->id == 4)
                                        {
                                            cout <<"Frame "<<setw(5)<<lastframeptr->headercounter<<" @ byte "<<setw(8)<<lastframeptr->position<<", Mpeg 2.5, layer "<<lastframeptr->layer<<", "<<setw(3)<<lastframeptr->bitrate<<" Kbps, "<<setw(6)<<lastframeptr->frequency<<" Hz,  OK "<<endl;
                                        }
                                        else
                                        {
                                            cout <<"Frame "<<setw(5)<<lastframeptr->headercounter<<" @ byte "<<setw(8)<<lastframeptr->position<<", Mpeg "<<setw(3)<<lastframeptr->id<<", layer "<<lastframeptr->layer<<", "<<setw(3)<<lastframeptr->bitrate<<" Kbps, "<<setw(6)<<lastframeptr->frequency<<" Hz,  OK "<<endl;
                                        }
                                    }
                                    else
                                    {
                                        cout <<"Frame "<<setw(5)<<lastframeptr->headercounter<<" @ byte "<<setw(8)<<lastframeptr->position<<"  OK "<<endl;
                                    }
                                }
                                if (errorframeptr) delete errorframeptr; // clean up
                                errorframeptr=0;
                                if (firstvalidframe == -1)
                                {
                                    firstvalidframe=lastframeptr->position;
                                    headercounter++;
                                    (thisframeptr->headercounter)++;
                                }
                                delete lastframeptr;
                                lastframeptr=thisframeptr;
                                thisframeptr=0;
                                headercounter++;
                            }
                            else if ((thisframeptr->position) < ((lastframeptr->position)+(lastframeptr->framelength)))
                            { // Header inside frame
                                if (!(errorframeptr))
                                {
                                    errorframeptr=thisframeptr;
                                    thisframeptr=0;
                                }
                                else
                                {
                                    delete thisframeptr;
                                    thisframeptr=0;
                                }
                            }
                            else // Header outside frame
                            {
                                if (errorframeptr) // maybe this is the next valid frame
                                {
                                    if (!(lastvalidframeptr))
                                    {
                                        lastvalidframeptr=lastframeptr;
                                        nextvalidframeptr=thisframeptr;
                                    }
                                    else
                                    {
                                        delete lastframeptr;
                                        lastframeptr=0;
                                        delete thisframeptr;
                                        thisframeptr=0;
                                    }
                                    lastframeptr=errorframeptr;
                                    errorframeptr=0;
                                    thisframeptr=0;
                                    file->seek(lastframeptr->position+1);
                                    currentposition=lastframeptr->position+1;
                                    header[0]=file->get();
                                    header[1]=file->get();
                                    header[2]=file->get();
                                }
                                else // this is the next valid header
                                {
                                    cout <<"Frame "<<setw(5)<<lastframeptr->headercounter<<" @ byte "<<setw(8)<<lastframeptr->position<<" is "<<thisframeptr->position-lastframeptr->position-lastframeptr->framelength<<" bytes too long."<<endl;
                                    framingerrors++;
                                    delete lastframeptr;
                                    lastframeptr=thisframeptr;
                                    thisframeptr=0;
                                }
                            }
                        }
                        else  // this is the first valid header
                        {
                            // cout <<"First valid header @ byte "<<thisframeptr->position<<endl;
                            lastframeptr=thisframeptr;
                            thisframeptr=0;
                        }
                    }
                    else // invalid header, forget it
                    {
                        if (lastframeptr->position+lastframeptr->framelength == thisframeptr->position)
                        {
                            cout <<"Invalid header at right position (@ byte "<<thisframeptr->position<<")"<<endl;
                        }
                        else
                        {
                            // cout <<"Skipping invalid header @ byte "<<thisframeptr->position<<endl;
                        }
                        delete thisframeptr;
                        thisframeptr=0;
                    }
                }
                else // new frame
                {
                    cout <<"Error, could not allocate memory"<<endl;
                    errors++;
                }
            }
            else if ((header[0] == 'T') && (header[1] == 'A') && (header[2] == 'G')) // tag found
            {
                if (currentposition+128 == file->filesize)
                {
                    cout <<"Valid TAG found:"<<endl;
                    showtag(file);
                }
                else
                {
                    if (istag(file))
                    {
                        cout <<"Probably invalid TAG @ byte "<<currentposition<<":"<<endl;
                        showtag(file);
                        invalidtagcounter++;
                    }
                }
            }
/*--------------------------------- */
            header[0]=header[1];
            header[1]=header[2];    // prepare for next loop
            header[2]=file->get();
            currentposition++;
        }  // loop till eof
    }
    else
    {
        cout <<"Error, could not create Buffer"<<endl;
        errors++;
    }
    if (firstvalidframe != -1)
    {
        cout <<headercounter-1<<" valid frames found."<<endl;
        cout <<"First valid frame starts at byte "<<firstvalidframe<<endl;
        if (framingerrors) cout<<"Errors in frames: "<<framingerrors<<endl;
        if (invalidtagcounter) cout <<"Invalid TAGs: "<<invalidtagcounter<<endl;
    }
    else
    {
        cout <<"File \""<<argv[1]<<"\" is not a valid Mpeg audio file."<<endl;
        errors++;
    }
    delete file;
    file=0;
    if (errors) cout <<errors<<" applicationerrors occoured."<<endl;
    return errors;
}
///




