Avatar billede spiritusanta Nybegynder
23. oktober 2002 - 14:09 Der er 4 kommentarer og
1 løsning

MP3 længde

Jeg programmere i C++ Builder.

Findes der en kode, der kan finde længden af et MP3 nummer?

Håber der er nogen, der kan hjælpe

MVH Spirit
Avatar billede soepro Nybegynder
23. oktober 2002 - 14:38 #1
Følgende kode tolker header informationen fra en MP3 fil:

#include <conio.h>
#include <string.h>
#include <stdio.h>

#define  bool int

// MP3 file decoding.
unsigned long bithdr;

int getFrameSync()    { return ((bithdr>>21) & 2047); };
int getVersionIndex()  { return ((bithdr>>19) & 3);  };
int getLayerIndex()    { return ((bithdr>>17) & 3);  };
int getProtectionBit() { return ((bithdr>>16) & 1);  };
int getBitrateIndex()  { return ((bithdr>>12) & 15); };
int getFrequencyIndex(){ return ((bithdr>>10) & 3);  };
int getPaddingBit()    { return ((bithdr>> 9) & 1);  };
int getPrivateBit()    { return ((bithdr>> 8) & 1);  };
int getModeIndex()    { return ((bithdr>> 6) & 3);  };
int getModeExtIndex()  { return ((bithdr>> 4) & 3);  };
int getCoprightBit()  { return ((bithdr>> 3) & 1);  };
int getOrginalBit()    { return ((bithdr>> 2) & 1);  };
int getEmphasisIndex() { return ((bithdr    ) & 3);  };

void loadHeader(char c[4]) {
  // Turn the four bytes into a unsigned long.
  bithdr = (unsigned long)( ( (c[0] & 255) << 24) |
                            ( (c[1] & 255) << 16) |
                            ( (c[2] & 255) <<  8) |
                            ( (c[3] & 255)      )
                          );
} // Load header.

bool isValidHeader(void) {
  // Check that valid MP3 header.
  return ( ((getFrameSync()      & 2047)==2047) &&
          ((getVersionIndex()  &    3)!=  1) &&
          ((getLayerIndex()    &    3)!=  0) &&

          // due to lack of support of the .mp3 format
          // no "public" .mp3's should contain information
          // like this anyway... :)
          ((getBitrateIndex()  &  15)!=  0) &&
          ((getBitrateIndex()  &  15)!=  15) &&
          ((getFrequencyIndex() &    3)!=  3) &&
          ((getEmphasisIndex()  &    3)!=  2)    );
} // isValidHeader

// this returns the MPEG version [1.0-2.5]
float getVersion() {
  float table[4] = {
                    2.5, 0.0, 2.0, 1.0
                  };

  // return modified value
  return table[getVersionIndex()];
} // getVersion

// this returns the Layer [1-3]
int getLayer() {
  return ( 4 - getLayerIndex() );
} // getLayer

int getBitrate() {
  const int table[2][3][16] = {
            {        //MPEG 2 & 2.5
              {0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0}, //Layer III
              {0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0}, //Layer II
              {0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0}  //Layer I
            },{      //MPEG 1
              {0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,0}, //Layer III
              {0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, //Layer II
              {0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448,0}  //Layer I
            }
          };

  // the bitrate is not only dependent of the bitrate index,
  // the bitrate also varies with the MPEG version and Layer version
  return table[(getVersionIndex() & 1)][(getLayerIndex() -1)][getBitrateIndex()];
} // getBitrate

unsigned int getFrequency() {
  unsigned int table[4][3] = {
                              {32000, 16000,  8000}, //MPEG 2.5
                              {    0,    0,    0}, //reserved
                              {22050, 24000, 16000}, //MPEG 2
                              {44100, 48000, 32000}  //MPEG 1
                            };
  // the frequency is not only dependent of the bitrate index,
  // the bitrate also varies with the MPEG version
  return table[getVersionIndex()][getFrequencyIndex()];
} // getFrequency

char *getMode(void) {
  switch(getModeIndex()) {
    case 1: return "Joint Stereo";
    case 2: return "Dual Channel";
    case 3: return "Single Channel";
  }
  return "Stereo";
} // getMode

int main(int argc, char *argv[])
{
  FILE *mp3File;
  char  mp3Hdr[4];

  if (argc < 2
  || (mp3File = fopen(argv[1], "rb"))          == NULL
  ||  fread(mp3Hdr, sizeof(mp3Hdr), 1, mp3File) != 1)
  {
    cprintf("Too few arguments (%d), non-existing or invalid file.(%s)\r\n",
            argc, argv[1]);
    return -1;
  };

  // Check if valid MP3 file.
  loadHeader(mp3Hdr);
  if (!isValidHeader())
  {
    cprintf("Header for %s not valid.\r\n", argv[1]);
    return -1;
  }

  // Then display all information about the MP3 file.
  cprintf("MP3 information for \'%s\':\r\n", argv[1]);
  cprintf("=====================%.*s==\r\n", strlen(argv[1]),
          "==============================");

  cprintf("Version    : %1.1f\r\n", getVersion());
  cprintf("Layer      : %d\r\n", getLayer());

  cprintf("Bit-rate  : %u\r\n", getBitrate());
  cprintf("Frequency  : %u\r\n", getFrequency());

  cprintf("Mode      : %s\r\n", getMode());

  return 0;
} // Main
Avatar billede soepro Nybegynder
23. oktober 2002 - 14:40 #2
Emnet er behandlet før under http://www.eksperten.dk/spm/18465
Avatar billede spiritusanta Nybegynder
23. oktober 2002 - 14:48 #3
Finder programmet også længden (tiden) af MP3 filen?
Avatar billede soepro Nybegynder
23. oktober 2002 - 15:06 #4
spiritusanta >> Nej, men den må enten stå i filen, eller kunne beregnes - prøv at søge på google under "MP3 header information" - der er masser af links.
Avatar billede spiritusanta Nybegynder
15. april 2003 - 21:56 #5
tror bare jeg lukker det her nu og forsøger at få svar,  når jeg får lidt mere tid til at programmere :)

Men ellers tak for hjælpen soepro... du får lidt point her for dit arbejde :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester