MP3文件解析

原创 2013年12月04日 21:54:57

目前解析了 MP3的头,帧头。接下来要做的就是 哈夫曼解码了。。。无力了囧

MP3文件的整体数据解析不过也算是个成长的见证,从去年怎么也弄不明白。到今天。:)好好学习天天向上


#ifndef __FRAME__INFO__H__

#define __FRAME__INFO__H__


const int SamplingRateTable[][4] =
{
{ 44100, 22050, 11025 }, // 00
{ 48000, 24000, 12000 }, // 01
{ 32000, 16000, 8000 }, // 10
{ 0,     0,     0} // 11
};

const int SamplingSizeTable[3][3] = 
{
{ 384, 384, 384 },
{ 1152, 1152, 1152 },
{ 1152, 576, 576 }
};

const short int BitrateTable[2][3][15] =
{
    {
        {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
        {0,32,48,56,64 ,80 ,96 ,112,128,160,192,224,256,320,384},
        {0,32,40,48,56 ,64 ,80 ,96 ,112,128,160,192,224,256,320}
    },
    {
        {0,32,48,56,64 ,80 ,96 ,112,128,144,160,176,192,224,256},
        {0,8 ,16,24,32 ,40 ,48 ,56 ,64 ,80 ,96 ,112,128,144,160},
        {0,8 ,16,24,32 ,40 ,48 ,56 ,64 ,80 ,96 ,112,128,144,160}
    }
};

#ifndef BYTE
typedef unsigned char BYTE;
#endif


struct XINGInfo{
unsigned char VBRID[4];
unsigned int Flags ;
unsigned int FramesNumber;
unsigned int BytesNumber;
char TOC[100];
int Quality ;
};

class FrameInfo
{
public:
// 同步标识
unsigned short mSycnFlag;
// MPEG版本
BYTE mMPEGVersion;
// 
BYTE mLayerIndex;
// Protection bit
BYTE mProtection;
// 比特率索引
BYTE mBps;
// 采样索引
BYTE mSamplingIndex;
// Padding bit
BYTE mPadding;
// 保护
BYTE mPrivate;
// Channel
BYTE mChannelMode;
// 扩展模式
BYTE mModeExtension;

BYTE mCopyright;

BYTE mOriginal;

BYTE mEmphasis;

public:
bool init(int fixFrameHeard);

// 获取比特率
short int getBitrate();

// 获取采样大小
int getSamplingSize();

// 获取采样率
int  getSamplingRate();

int getFrameSize();

// 获取边信息大小
int getEdgeSize();
};



struct ID3V2_HEADER{
char Header[3];
char Ver;      
char Revision;
char Flag;    
char Size[4];
};

struct ID3V2_FRAME_HEADER{
char FrameID[4];
char Size[4];
char Flag[2];
};


struct ID3V1{
char Header[3];    
char Title[30];    
char Artist[30];  
char Album[30];    
char Year[4];      
char Comment[28];
char reserve;      
char track;;      
char Genre;        
};

#include "cocos2d.h"

class MP3File
{
private:

// 初始化IDV3头
bool initID3V2Header();
// 初始化第一帧的数据 
bool initFirstFrame();

// 是否拥有IDV3头
bool m_bHaveID3V2;

private: // 
// IDV3
ID3V2_HEADER mID3V2Header;
// 数据缓存
unsigned char* m_pDataBuffer;
// 缓存数据长度
unsigned long m_lDataLength;
public:

// 获取第一帧开始位置
int getFrameOffset();

// 获取标签头
int getFrameSize();
// 初始化到文件
bool initFile(const char* pszFilepath);

// 解析文件
static MP3File* parse(const char* pszFilepath);



};


#endif





#include "FrameInfo.h"

bool FrameInfo::init(int fixFrameHeard){

// 同步头
this->mSycnFlag = (fixFrameHeard & 0xFFE00000) >> 16;
if(this->mSycnFlag != 0xFFE0){
return false;
}

// 2  0000 0000 0001 1000 0000 0000 0000 0000
this->mMPEGVersion = (fixFrameHeard & 0x180000) >> 19;

// 2  0000 0000 0000 0110 0000 0000 0000 0000
this->mLayerIndex = (fixFrameHeard & 0x60000) >> 17;
    
// 1  0000 0000 0000 0001 0000 0000 0000 0000
this->mProtection = (fixFrameHeard & 0x10000) >> 16;
// 4  0000 0000 0000 0000 1111 0000 0000 0000
this->mBps = (fixFrameHeard & 0xF000) >> 12;
// 2  0000 0000 0000 0000 0000 2200 0000 0000
this->mSamplingIndex = (fixFrameHeard & 0xC00) >> 10;

// 1  0000 0000 0000 0000 0000 0010 0000 0000
this->mPadding = (fixFrameHeard & 0x200) >> 9;
// 1  0000 0000 0000 0000 0000 0001 0000 0000
this->mPrivate = (fixFrameHeard & 0x100) >> 8;
// 2  0000 0000 0000 0000 0000 0000 1100 0000
this->mChannelMode = (fixFrameHeard & 0xC0) >> 6;
// 2  0000 0000 0000 0000 0000 0000 0011 0000
this->mModeExtension = (fixFrameHeard & 0x30) >> 4;
// 1  0000 0000 0000 0000 0000 0000 00000 1000
this->mCopyright = (fixFrameHeard & 0x8) >> 3;
// 1  0000 0000 0000 0000 0000 0000 0000 0100
this->mOriginal = (fixFrameHeard & 0x4) >> 2;
// 2  0000 0000 0000 0000 0000 0000 0000 0011
this->mEmphasis = (fixFrameHeard & 0x3);

//=============一些修正=================================================
switch(this->mMPEGVersion){
case 0: this->mMPEGVersion = 3; break;
case 2: this->mMPEGVersion = 2; break;
case 3: this->mMPEGVersion = 0; break;
}

switch(this->mLayerIndex){
    case 1: this->mLayerIndex = 3; break;
    case 2: this->mLayerIndex = 2; break;
    case 3: this->mLayerIndex = 1; break;
    };
if(this->mPadding){
        this->mPadding = ( this->mLayerIndex == 1 ? 4 : 1 );
    }

return true;
}

short int FrameInfo::getBitrate(){
int index_I = this->mMPEGVersion == 0 ? 0 : 1;
int index_II = this->mLayerIndex - 1;



return BitrateTable[index_I][index_II][this->mBps];
}

int FrameInfo::getSamplingRate(){

return SamplingRateTable[this->mSamplingIndex][this->mMPEGVersion];
} 

int FrameInfo::getFrameSize(){

return ((this->mMPEGVersion == 0 ? 144 : 77) * (getBitrate()*1000) / getSamplingRate()) + this->mPadding;
}

int FrameInfo::getSamplingSize(){
int index = 0;
switch(this->mMPEGVersion){
case 0: // MPEG 1
index = 0;
case 2: // MPEG 2
index = 1;
case 3: // MPEG 3
index = 2;
}

return SamplingSizeTable[this->mLayerIndex - 1][index];
}

int FrameInfo::getEdgeSize(){
switch(this->mMPEGVersion){
case 0: // MPEG 1
if(mChannelMode == 1) return 32; else return 17;
case 2: // MPEG 2
if(mChannelMode == 1) return 17; else return 9;
case 3: // MPEG 3
if(mChannelMode == 1) return 17; else return 9;
}
return 0;
}

#include "MP3File.h"
#include "FrameInfo.h"

int MP3File::getFrameOffset(){

return getFrameSize() + 0;
}

int MP3File::getFrameSize(){
return (int)(mID3V2Header.Size[0]&0x7F)*0x200000 +
(mID3V2Header.Size[1]&0x7F)*0x400 + 
(mID3V2Header.Size[2]&0x7F)*0x80 + 
(mID3V2Header.Size[3]&0x7F) + 10; 
}

bool MP3File::initID3V2Header(){

memcpy(&mID3V2Header, m_pDataBuffer, sizeof(ID3V2_HEADER));
char headr[4];
memcpy(headr, mID3V2Header.Header, 3);
headr[3] = '\000';

return strcmp(headr, "ID3") == 0;
}

unsigned int fixData(int data){
unsigned int res = 0;
res |= (data & 0x000000ff) << 24;
res |= (data >> 8 & 0x000000ff) << 16; 
res |= (data >> 16 & 0x000000ff) << 8; 
res |= (data >> 24 & 0x000000ff); 
return res;
}


#include "cocos2d.h"
bool MP3File::initFirstFrame(){
int framePos = getFrameOffset();

int frameHeard;
memcpy(&frameHeard, m_pDataBuffer + framePos, 4);
FrameInfo* frameInfo = new FrameInfo();
frameInfo->init(fixData(frameHeard));
int size = frameInfo->getFrameSize();

int i = frameInfo->mMPEGVersion;

// 得到XING头
framePos += frameInfo->getEdgeSize() + 4;
XINGInfo xing;
memset(&xing, 0, sizeof(XINGInfo));
memcpy(&xing, m_pDataBuffer + framePos, sizeof(XINGInfo));
xing.Flags = fixData(xing.Flags);
xing.FramesNumber = fixData(xing.FramesNumber);
xing.BytesNumber = fixData(xing.BytesNumber);
xing.Quality = fixData(xing.Quality);


// 开始遍历帧
framePos = getFrameOffset();
for(int i = 0 ; i < xing.FramesNumber ; i++){

memcpy(&frameHeard, m_pDataBuffer + framePos, 4);
frameInfo->init(fixData(frameHeard));

size = frameInfo->getFrameSize();

unsigned char* data_pos = m_pDataBuffer + framePos;

unsigned char* frameData = new unsigned char[size];
memcpy(frameData, data_pos, size);
for(int i = 0 ; i < size ; i++){
//cocos2d::CCLog("%i", frameData[i]);
}

framePos += size;
}

return true;
}

bool MP3File::initFile(const char* pszFilepath){
// 载入数据
m_pDataBuffer = cocos2d::CCFileUtils::sharedFileUtils()->getFileData(pszFilepath, "rb", &m_lDataLength);

// 初始化头
m_bHaveID3V2 = initID3V2Header();

// 如果是标准IDV3
if(m_bHaveID3V2){
// 初始化第一帧
initFirstFrame();

}
return true;
}

MP3File* MP3File::parse(const char* pszFilepath){
MP3File* mp3File = new MP3File();

if(mp3File->initFile(pszFilepath)){
return mp3File;
}

delete mp3File;

return mp3File;
}


相关文章推荐

视频文件格式解析之 3GP与MP4

1. 概述 流行的文件格式背后都有大公司的支持。FLV得益于ADOBE公司推动的网络视频分享风潮,而AVI则是MICROSOFT首创的RIFF即视频和音频交 织在一起同步播放。 3GP/MP4是AP...
  • yanfake
  • yanfake
  • 2012年05月09日 12:25
  • 2002

毕业设计(音乐播放器)之二(MP3文件标签解析)

目前MP3文件比较通用的标签有ID3v1,ID3V2,APEv2. 一、ID3v1位于Mp3文件的最后128个字节,其中包括: 第一部分为固定的$54 14 47,表示'TAG'这三个...
  • a477997
  • a477997
  • 2012年03月27日 11:05
  • 416

Mp3文件格式解析

最近使用red5流化mp3遇到点问题,先对Mp3的格式做一下解释!后续会对遇到问题及解决方法做介绍。 一、mp3文件结构 mp3文件包含3部分:ID3v2(不是必须的),FRAME(必须有),ID...
  • zzaihl
  • zzaihl
  • 2011年11月03日 16:56
  • 769

视频文件格式解析之 3GP/MP4 .

1. 概述 流行的文件格式背后都有大公司的支持。FLV得益于ADOBE公司推动的网络视频分享风潮,而AVI则是MICROSOFT首创的RIFF即视频和音频交 织在一起同步播放。 3GP/MP4是AP...
  • kl222
  • kl222
  • 2012年09月07日 20:33
  • 4117

MP3 lrc文件的解析

今天在看Mars 的mp3播放器的视频时,看到lrc歌词文件的匹配, lrc文件的格式为 [00:01.00]第一次 [00:03.00]光良 [00:05.00]作词:张天成 作曲:光良 ...

android 播放器解析MP3文件乱码分析

我们从windows的中文操作系统下,下载下来mp3,Tag正常显示,推进Android机后,却出现乱码,这是为什么呢?      之所以在中文系统中没有特别的问题,是因为通常电脑生成的MP3简体中...

MP3格式音频文件结构解析

一、概述 Layer-3 音频文件,MPEG(Moving Picture Experts Group) 在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG音频文件是MPEG1 标准中的声音...

MP3格式音频文件结构解析

一、概述 Layer-3 音频文件,MPEG(Moving Picture Experts Group) 在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG音频文件是MPEG1 标准中的声音...

MP3文件解析详解

此文章为skoootxl2008原创,转载请注明出处,尊重他人劳动成果。 概述      MP3文件是我们常见的音频文件格式,它内部的结构如何?音乐播放器是如何解析MP3文件的呢?...

3GP/MP4 视频文件格式解析及其播放原理(转)

视频文件格式解析之 3GP/MP4 1. 概述 流行的文件格式背后都有大公司的支持。FLV得益于ADOBE公司推动的网络视频分享风潮,而AVI则是MICROSOFT首创的RIF...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MP3文件解析
举报原因:
原因补充:

(最多只允许输入30个字)