All pastes #1867914 Raw Edit

Something

public text v1 · immutable
#1867914 ·published 2010-04-19 14:52 UTC
rendered paste body
#ifdef __cplusplus
extern "C"{
#endif

//typedef enum bool_t{false = 0, true} bool;//C...
#ifndef __cplusplus
typedef	int bool;
#define true 1
#define false 0
#endif


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

#define	FRAMESYNC 0x03ff

#define	MPEGVersion2_5 0x00
#define	MPEGreserved   0x01
#define	MPEGVersion2   0x02
#define	MPEGVersion1   0x03

#define LAYER1	0x03
#define LAYER2	0x02
#define LAYER3	0x01
#define LAYERreserved	0x00

#define BITRATEFREE	0xfffe
#define BITRATEBAD	0xffff

#define SAMPLINGFREQreserved 0x3

#define EMPHASYSreserved 0x10

#ifndef byte
typedef unsigned char byte;
#endif

/*
typedef struct{
	unsigned framesync	:11;	//Frame synchronizer
	unsigned MPEGID		: 2;	//MPEG version ID
	unsigned layer		: 2;	//Layer
	unsigned protectbit	: 1;	//CRC Protection
	//----
	unsigned bitrateindx: 4;	//Bitrate index
	unsigned samplefreq	: 2;	//Samplig rate frequency index
	unsigned paddingbit	: 1;	//Padding
	unsigned privatebit	: 1;	//Private bit
	//----
	unsigned channel	: 2;	//Channel
	unsigned modeext	: 2;	//Mode extension (only if Joint Stereo is set)
	unsigned copyright	: 1;	//Copyright
	unsigned original	: 1;	//Original
	unsigned emphasis	: 2;	//Emphasis
} MP3HEADER;
*/

#pragma pack( push, 1 )

enum { MP3H_FRAMESYNC, MP3H_MPEGID, MP3H_LAYER,
        MP3H_PROTECTBIT, MP3H_BITRATEINDX, MP3H_SAMPLEFREQ, MP3H_PADDINGBIT,
        MP3H_PRIVATEBIT, MP3H_CHANNEL, MP3H_MODEEXT, MP3H_COPYRIGHT,
        MP3H_ORIGINAL, MP3H_EMPHASIS };

short int masks[];
char shifts[];

#define getHAtr(h, m) (masks[m] & ((h)>>shifts[m]))

typedef struct{
	short framesync	;	//Frame synchronizer
	char MPEGID		;	//MPEG version ID
	char layer		;	//Layer
	char protectbit	;	//CRC Protection
	//----
	char bitrateindx;	//Bitrate index
	char samplefreq	;	//Samplig rate frequency index
	char paddingbit	;	//Padding
	char privatebit	;	//Private bit
	//----
	char channel	;	//Channel
	char modeext	;	//Mode extension (only if Joint Stereo is set)
	char copyright	;	//Copyright
	char original	;	//Original
	char emphasis	;	//Emphasis
} MP3HEADER;

typedef struct{
	char	tagid  [ 3];	//0-2     3  Tag identifier. Must contain "TAG" string if Tag is valid.
	char	name   [30];	//3-32   30  Song Name
	char	artist [30];	//33-62  30  Artist
	char	album  [30];	//63-92  30  Album
	int		year       ;	//93-96   4  Year
	char	comment[30];	//97-126 30  Comment
	char	genre      ;	//127  1  Genre
} MP3ID3TAG1;

typedef struct{
	char	tagid[3];//0-2  TAG identifier. It contains of string "ID3"
	short	tagverm	;//3-4  TAG version
	char	flags	;//5	Flags
	long	size	;//6-9  Size of TAG
} MP3ID3TAG2;


int MP3bitrate(const MP3HEADER *h);
int MP3SamplingFreq(const MP3HEADER *h);

bool readMP3header(FILE *f, MP3HEADER *h);
bool skipMP3Frame(FILE *f, const MP3HEADER *h);
bool skipMP3Tag(FILE *f);//ID3

bool isMP3CBR(FILE *f);
bool isMP3VBR(FILE *f);

int GetMP3FileBitrate(const char* fname);

#pragma pack( pop )

#ifdef __cplusplus
}
#endif



/*----------------------------------------------
bits V1,L1	V1,L2	V1,L3	V2,L1	V2, L2 & L3
0000 free	free	free	free	free
0001 32		32		32		32		8
0010 64		48		40		48		16
0011 96		56		48		56		24
0100 128	64		56		64		32
0101 160	80		64		80		40
0110 192	96		80		96		48
0111 224	112		96		112		56
1000 256	128		112		128		64
1001 288	160		128		144		80
1010 320	192		160		160		96
1011 352	224		192		176		112
1100 384	256		224		192		128
1101 416	320		256		224		144
1110 448	384		320		256		160
1111 bad	bad		bad		bad		bad
-----------------------------------------------*/

int bitrates[] = {
	BITRATEFREE, BITRATEFREE, BITRATEFREE, BITRATEFREE, BITRATEFREE,
	32,   32,  32,  32,	  8,
	64,   48,  40,  48,	 16,
	96,	  56,  48,  56,  24,
	128,  64,  56,  64,  32,
	160,  80,  64,  80,  40,
	192,  96,  80,  96,  48,
	224, 112,  96, 112,  56,
	256, 128, 112, 128,  64,
	288, 160, 128, 144,  80,
	320, 192, 160, 160,  96,
	352, 224, 192, 176, 112,
	384, 256, 224, 192, 128,
	416, 320, 256, 224, 144,
	448, 384, 320, 256, 160,
	BITRATEBAD, BITRATEBAD, BITRATEBAD, BITRATEBAD, BITRATEBAD
};
/*-----------------------------------
Sampling rate frequency index (values are in Hz) bits
   MPEG1   MPEG2   MPEG2.5
00 44100   22050   11025
01 48000   24000   12000
10 32000   16000   8000
11 reserv. reserv. reserv.
---------------------------------------*/
int samplingfreqs[] = {
	44100, 22050, 11025,
	48000, 24000, 12000,
	32000, 16000,  8000,
	SAMPLINGFREQreserved,SAMPLINGFREQreserved, SAMPLINGFREQreserved
};

short int masks[] = {
	0x03FF, 0x03, 0x03, 0x01,
	0x0f, 0x03,	0x01, 0x01,
	0x03, 0x03, 0x01, 0x01, 0x03};

char shifts[] = { 21, 19, 17, 16, 12, 10, 9, 8, 6, 4, 3, 2, 0 };

int unpacktagsize(MP3ID3TAG2 id){
	int a, b, c, d;
	a = ( id.size >> 3 ) & 0x0fe00000;
	b = ( id.size >> 2 ) & 0x001fc000;
	c = ( id.size >> 1 ) & 0x00003f80;
	d = ( id.size >> 0 ) & 0x0000007f;
	return	a>>21 | b>>7 | c<<7 | d<<21;
}

int MP3SamplingFreq(const MP3HEADER *h){
	int idx;
	switch(h->MPEGID){
	case MPEGVersion2_5:idx = 2;break;
	case MPEGVersion2:	idx = 1;break;
	case MPEGVersion1:	idx = 0;break;
	case MPEGreserved:	return SAMPLINGFREQreserved;
	}
	return samplingfreqs[(h->samplefreq * 3) + idx];
}

int MP3bitrate(const MP3HEADER *h){
	int index=0;
	if( h->MPEGID == MPEGVersion1 ){
		index = 3-h->layer;
	}else if( h->MPEGID == MPEGVersion2 || h->MPEGID == MPEGVersion2_5 ){
		index = (h->layer == LAYER1 ? 3 :4 );
	}
	return bitrates[ index + h->bitrateindx * 5 ];
}

bool skipMP3Frame(FILE *f, const MP3HEADER *h){
	int frsz;

	if(h->layer == LAYER1){
		frsz = (12 * MP3bitrate(h) * 1000 / MP3SamplingFreq(h) + h->paddingbit) * 4;
	}else if( (h->layer == LAYER2) || (h->layer == LAYER3) ){
		frsz = 144 * MP3bitrate(h) * 1000 / MP3SamplingFreq(h) + h->paddingbit;
	}else{
		frsz = 0;
	}
//printf("framesz: %d\n\n", frsz);
	return fseek(f, frsz, SEEK_CUR) == 0;

}

bool skipMP3Tag(FILE *f){
	MP3ID3TAG2 tag;

	rewind(f);
	if(fread(&tag, 1, sizeof(MP3ID3TAG2), f)<1) return false;

	if(!memcmp(tag.tagid, "ID3", 3)){//é tag id3v2 - saltar para fim da tag
		return fseek(f, unpacktagsize(tag), SEEK_CUR) == 0;
	}else{//não é tag id3v2 - inicio do ficheiro
		rewind(f);
	}
	return true;
}

bool readMP3header(FILE *f, MP3HEADER *h){
	int t, b;

	do{
		if(fread(&t, 1, 4, f)<1)
			return false;
		fseek(f, -3, SEEK_CUR);
		/*troca...*/
		b = (t & 0x000000ff);
		t = (t & 0xffffff00) | ((t>>24) & 0x000000ff);
		t = (t & 0x00ffffff) | ((b<<24) & 0xff000000);
		b = (t & 0x0000ff00);
		t = (t & 0xffff00ff) | ( (t>>8) & 0x0000ff00);
		t = (t & 0xff00ffff) | ( (b<<8) & 0x00ff0000);
		/*-----*/

		h->framesync	= getHAtr(t, MP3H_FRAMESYNC);
		h->MPEGID		= getHAtr(t, MP3H_MPEGID);
		h->layer		= getHAtr(t, MP3H_LAYER);
		h->bitrateindx	= getHAtr(t, MP3H_BITRATEINDX);
		h->samplefreq	= getHAtr(t, MP3H_SAMPLEFREQ);
		h->emphasis		= getHAtr(t, MP3H_EMPHASIS);

	}while(	(h->framesync   != FRAMESYNC)
		  ||(h->bitrateindx == 0x0f)
		  ||(h->bitrateindx == 0x00)
		  ||(h->MPEGID      == MPEGreserved)
		  ||(h->layer       == LAYERreserved)
		  ||(h->samplefreq  == SAMPLINGFREQreserved)
		  ||(h->emphasis	== EMPHASYSreserved));
	fseek(f, 3, SEEK_CUR);

//	h->framesync	= getHAtr(t, MP3H_FRAMESYNC);	//Frame synchronizer
//	h->MPEGID		= getHAtr(t, MP3H_MPEGID);		//MPEG version ID
//	h->layer		= getHAtr(t, MP3H_LAYER);		//Layer
	h->protectbit	= getHAtr(t, MP3H_PROTECTBIT);	//CRC Protection
//	h->bitrateindx	= getHAtr(t, MP3H_BITRATEINDX);	//Bitrate index
//	h->samplefreq	= getHAtr(t, MP3H_SAMPLEFREQ);	//Samplig rate frequency index
	h->paddingbit	= getHAtr(t, MP3H_PADDINGBIT);	//Padding
	h->privatebit	= getHAtr(t, MP3H_PRIVATEBIT);	//Private bit
	h->channel		= getHAtr(t, MP3H_CHANNEL);		//Channel
	h->modeext		= getHAtr(t, MP3H_MODEEXT);		//Mode extension (only if Joint Stereo is set)
	h->copyright	= getHAtr(t, MP3H_COPYRIGHT);	//Copyright
	h->original		= getHAtr(t, MP3H_ORIGINAL);	//Original
//	h->emphasis		= getHAtr(t, MP3H_EMPHASIS);	//Emphasis

	return true;
}

bool isMP3CBR(FILE *f){
	return true;
}

bool isMP3VBR(FILE *f){
	return false;
}

int GetMP3FileBitrate(const char* fname){
	FILE *f;
	MP3HEADER h;
	int brate;

	f = fopen(fname, "rb");
	if(!f) return -1;

	if(isMP3CBR(f)){
		skipMP3Tag(f);
		readMP3header(f, &h);
		brate = MP3bitrate(&h);
	}else if(isMP3VBR(f)){
		//
		brate = 0;
	}else
		brate = -1;
	fclose(f);
	return brate;
}