-static HMP3Decoder mp3dec = 0;
-static int mp3_buffer_offs = 0;
-
-
-static int find_sync_word(unsigned char *buf, int nBytes)
-{
- unsigned char *p, *pe;
-
- /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
- for (p = buf, pe = buf + nBytes - 4; p < pe; p++)
- {
- int pn;
- if (p[0] != 0xff) continue;
- pn = p[1];
- if ((pn & 0xf8) != 0xf8 || // currently must be MPEG1
- (pn & 6) == 0) { // invalid layer
- p++; continue;
- }
- pn = p[2];
- if ((pn & 0xf0) < 0x20 || (pn & 0xf0) == 0xf0 || // bitrates
- (pn & 0x0c) != 0) { // not 44kHz
- continue;
- }
-
- return p - buf;
- }
-
- return -1;
-}
-
-
-static int try_get_header(unsigned char *buff, MP3FrameInfo *fi)
-{
- int ret, offs1, offs = 0;
-
- while (1)
- {
- offs1 = find_sync_word(buff + offs, 2048 - offs);
- if (offs1 < 0) return -2;
- offs += offs1;
- if (2048 - offs < 4) return -3;
-
- // printf("trying header %08x\n", *(int *)(buff + offs));
-
- ret = MP3GetNextFrameInfo(mp3dec, fi, buff + offs);
- if (ret == 0 && fi->bitrate != 0) break;
- offs++;
- }
-
- return ret;
-}
-
-int mp3_get_bitrate(FILE *f, int len)
-{
- unsigned char buff[2048];
- MP3FrameInfo fi;
- int ret;
-
- memset(buff, 0, 2048);
-
- if (mp3dec) MP3FreeDecoder(mp3dec);
- mp3dec = MP3InitDecoder();
-
- fseek(f, 0, SEEK_SET);
- ret = fread(buff, 1, 2048, f);
- fseek(f, 0, SEEK_SET);
- if (ret <= 0) return -1;
-
- ret = try_get_header(buff, &fi);
- if (ret != 0 || fi.bitrate == 0) {
- // try to read somewhere around the middle
- fseek(f, len>>1, SEEK_SET);
- fread(buff, 1, 2048, f);
- fseek(f, 0, SEEK_SET);
- ret = try_get_header(buff, &fi);
- }
- if (ret != 0) return ret;
-
- // printf("bitrate: %i\n", fi.bitrate / 1000);
-
- return fi.bitrate / 1000;
-}
-