#ifndef _MP3STAT_H #define _MP3STAT_H #include "input.h" class mp3 : public input { public: mp3 () : input(), type("audio/mpeg") {;} virtual ~mp3() {;} inline virtual std::string getType() const { return(type); } virtual void statfile (statistic *); private: typedef unsigned long ulong; typedef unsigned int uint; typedef unsigned short ushort; typedef unsigned char uchar; typedef signed char schar; const std::string type; static int min_valid; static int FREEFORMAT; static int FORBIDDEN; static uint CONST_MASK; static int layer_tab[4]; static int bitrate1_tab[16][3]; static int bitrate2_tab[16][3]; static double sampd1_tab[4]; static int samp_1_tab[4]; static double sampd2_tab[4]; static int samp_2_tab[4]; struct Header { uint emphasis:2, // fix 2 reserved original:1, // fix copyright:1, // fix mode_extension:2, // (not fix!) mode:2, // fix private_bit:1, padding_bit:1, sampling_frequency:2, // fix 3 reserved bitrate_index:4, // 15 forbidden protection_bit:1, // fix layer_index:2, // fix 0 reserved ID:1, // fix 1==mpeg1.0 0==mpeg2.0 syncword:12; // fix must 0xfff bool isValid () const { if (syncword != 0xfff) return false; if (ID == 1) { // mpeg 1.0 if ((layer_index != 0) && (bitrate_index != 15) && (sampling_frequency != 3) && (emphasis != 2)) return true; return false; } else { // mpeg 2.0 if ((layer_index != 0) && (bitrate_index != 15) && (sampling_frequency != 3) && (emphasis != 2)) return true; return false; } } bool sameConstant (Header h) const { if ((*(uint *) this) == (*(uint *) & h)) return true; if ((syncword == h.syncword) && (ID == h.ID) && (layer_index == h.layer_index) && (protection_bit == h.protection_bit) && (sampling_frequency == h.sampling_frequency) && (mode == h.mode) && (copyright == h.copyright) && (original == h.original) && (emphasis == h.emphasis) && 1) return true; else return false; } int bitrate () const { if (ID) return bitrate1_tab[bitrate_index][layer () - 1]; else return bitrate2_tab[bitrate_index][layer () - 1]; } int layer () const { return layer_tab[layer_index]; } double version () const { if (ID) return 1.0; else return 2.0; } enum { STEREO, JOINT_STEREO, DUAL_CHANNEL, SINGLE_CHANNEL }; const char *mode_str () const { switch (mode) { case 0: return "stereo"; case 1:return "joint stereo"; case 2:return "dual channel"; case 3:return "single chann"; } return 0; } const char *short_mode_str () const { switch (mode) { case 0: return "st"; case 1:return "js"; case 2:return "dc"; case 3:return "sc"; } return 0; } enum { emp_NONE, emp_50_15_MICROSECONDS, emp_RESERVED, emp_CCITT_J_17 }; const char *emphasis_str () const { switch (emphasis) { case 0: return "no emph"; case 1:return "50/15us"; case 2:return "reservd"; case 3:return "C. J.17"; } return 0; } const char *short_emphasis_str () const { switch (emphasis) { case 0: return "n"; case 1:return "5"; case 2:return "!"; case 3:return "J"; } return 0; } double samp_rate () const { if (ID) return sampd1_tab[sampling_frequency]; else return sampd2_tab[sampling_frequency]; } int samp_int_rate () const { if (ID) return samp_1_tab[sampling_frequency]; else return samp_2_tab[sampling_frequency]; } int get_int () const { return *((const int *) this); } }; static inline Header get_header (const uchar *); static inline void set_header (uchar *, Header); static inline int frame_length (Header); int find_next_header (const uchar *, int, int); void scan_mp3 (uchar *, int, statistic *); }; #endif