MP3的文件格式问题

lanstar200 2004-06-25 10:45:37
哪位大虾可以提供有关MP3文件格式方面的信息啊?
...全文
327 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
SpeedChina 2004-06-28
  • 打赏
  • 举报
回复
MP3文件数据由多个帧组成,帧是MP3文件最小组成单位。每个帧又由帧头、附加信息和声音数据组成。每个帧播放时间是0.026秒,其长度随位率的不同而不等。有些MP3文件末尾有些额外字节存放非声音数据的说明信息。

帧头格式
帧头长4字节,对于固定位率的MP3文件,所有帧的帧头格式一样其数据结构如下:
typedef FrameHeader{
unsigned int sync:11;//同步信息
unsigned int version:2;//版本
unsigned int layer:2;//层
unsigned int protection:1;// CRC校验
unsigned int bitrate:4;//位率
unsigned int frequency:2;//频率
unsigned int padding:1;//帧长调节
unsigned int private:1;//保留字
unsigned int mode:2;//声道模式
unsigned int mode extension:2;//扩充模式
unsigned int copyright:1;// 版权
unsigned int original:1;//原版标志
unsigned int emphasis:2;//强调模式
}HEADER, *LPHEADER;

此外Mp3还有ID3V1(在文件的尾部)和ID3V2(在文件的头部,此时需要计算Mp3的开始数据在文件中的偏移量啦)等相关的歌曲附加信息,需要查找相关的资料另行给分后进行补充。
zhangnanonnet 2004-06-25
  • 打赏
  • 举报
回复
太长了,没办法贴啊,其实网上有很多的
tyro_zhang 2004-06-25
  • 打赏
  • 举报
回复

/*____ codecEncodeChunk() _____________________________________________________*/

unsigned int codecEncodeChunk
(
int nSamples,
short *pSamples,
char *pDest
)
{
static double xr[2][2][576];
static double xr_dec[2][2][576];
static double pe[2][2];
static int l3_enc[2][2][576];
static III_psy_ratio ratio;
static III_scalefac_t scalefac;
int gr, ch;
int mean_bits, sideinfo_len;
int bitsPerFrame;
int j;

/*
static int fFirst = TRUE;

if (fFirst)
{
memset ((char *) &xr , 0, sizeof(xr));
memset ((char *) &xr_dec , 0, sizeof(xr_dec));
memset ((char *) &pe , 0, sizeof(pe));
memset ((char *) &l3_enc , 0, sizeof(l3_enc));
memset ((char *) &ratio , 0, sizeof(ratio));
memset ((char *) &l3_side , 0, sizeof(l3_side));
memset ((char *) &scalefac, 0, sizeof(scalefac));

fFirst = FALSE;
}
*/


/* rebuffer audio */

#if ORG_BUFFERS
rebuffer_audio (buffer, pSamples, nSamples, stereo);
#else
rebuffer_audio (pSamples, buffer, &buffer_idx, nSamples, stereo);
#endif


/* psychoacoustic model */

for (gr = 0; gr < 2; gr++)
for (ch = 0; ch < stereo; ch++)
psycho_anal
(
#if ORG_BUFFERS
&buffer[ch][gr*576],
&sam[ch][0],
#else
buffer[ch],
(buffer_idx+gr*576) & 2047,
#endif
ch,
3,
/*snr32,*/
&ratio.l[gr][ch][0],
&ratio.s[gr][ch][0],
&pe[gr][ch],
&l3_side.gr[gr].ch[ch].tt
);


/* polyphase filtering */

for (gr = 0; gr < 2; gr++)
{
int gr_plus_1 = gr_idx[gr+1];

for (ch = 0; ch < stereo; ch++)
{
for (j = 0; j < 18; j++)
{
windowFilterSubband
(
#if ORG_BUFFERS
&buffer[ch][gr*18*32+32*j],
ch,
#else
buffer[ch],
(buffer_idx+768-480+gr*18*32+32*j) & 2047,
#endif
l3_sb_sample[ch][gr_plus_1][j]
);
}
}
}


/* apply mdct to the polyphase outputs */

mdct_sub (&l3_sb_sample, xr, stereo, &l3_side, 2);


pEncodedOutput = pDest;
outputBit = 8;
pEncodedOutput[0] = 0;


if (frac_SpF != 0)
{
if (slot_lag > (frac_SpF-1.0))
{
slot_lag -= frac_SpF;
info.padding = 0;
}
else
{
info.padding = 1;
slot_lag += (1-frac_SpF);
}
}

bitsPerFrame = 8 * whole_SpF + (info.padding * 8);


/* determine the mean bitrate for main data */

sideinfo_len = 32;

if (stereo == 1)
sideinfo_len += 136;
else
sideinfo_len += 256;

if (info.error_protection)
sideinfo_len += 16;

mean_bits = (bitsPerFrame - sideinfo_len) / 2;


/* bit and noise allocation */

iteration_loop
(
pe,
xr,
&ratio,
&l3_side,
l3_enc,
mean_bits,
stereo,
xr_dec,
&scalefac,
&fr_ps,
0,
bitsPerFrame
);


/* write the frame to the bitstream */

III_format_bitstream
(
bitsPerFrame,
&fr_ps,
l3_enc,
&l3_side,
&scalefac,
xr,
NULL,
0
);


return pEncodedOutput - pDest;
}





/*____ codecExit() ____________________________________________________________*/

unsigned int codecExit (char *pDest)
{
pEncodedOutput = pDest;
outputBit = 8;
pEncodedOutput[0] = 0;

psycho_anal_exit ();
exitFormatBitstream ();
III_FlushBitstream ();

return pEncodedOutput - pDest;
}





/*____ codecFlush() _________________________________________________________*/

unsigned int codecFlush (char *pDest)
{
pEncodedOutput = pDest;
outputBit = 8;
pEncodedOutput[0] = 0;

flushFrame ();

whole_SpF = (int) avg_slots_per_frame;
frac_SpF = avg_slots_per_frame - (double) whole_SpF;
slot_lag = -frac_SpF;

l3_side.main_data_begin = 0;
fixStatic_reservoir ();

return pEncodedOutput - pDest;
}



tyro_zhang 2004-06-25
  • 打赏
  • 举报
回复
codec.c

/*
(c) Copyright 1998-2000 - Tord Jansson
======================================

This file is part of the BladeEnc MP3 Encoder, based on
ISO's reference code for MPEG Layer 3 compression, and might
contain smaller or larger sections that are directly taken
from ISO's reference code.

All changes to the ISO reference code herein are either
copyrighted by Tord Jansson (tord.jansson@swipnet.se)
or sublicensed to Tord Jansson by a third party.

BladeEnc is free software; you can redistribute this file
and/or modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.



------------ CHANGES ------------

2000-11-22 Andre Piotrowski

- big fix: module - original dist10 error - l3_sb_sample has to be of type 'L3SBS' not 'SBS'.
- bug fix: codecInit() - don't reset fInit-huffman_read_flag - read_huffcodetab() is a memory eater!

2000-12-11 ap

- reformatted
- speed up: use single buffer
*/

#include <stdlib.h>
#include <assert.h>

#include "common.h"
#include "l3psy.h"
#include "mdct.h"
#include "reservoir.h"
#include "formatbitstream2.h"
#include "l3bitstream.h"
#include "loop.h"
#include "encoder.h"
#include "codec.h"





extern int fInit_fft;





/************************************************************************/

#define SAMPLES_PER_FRAME 1152

static L3SBS l3_sb_sample;

static layer info;



#if ORG_BUFFERS
static short buffer[2][1152];
/* static float snr32[32]; */
static short sam[2][2048];
#else
static FLOAT buffer[2][2048];
static int buffer_idx;
#endif



static int whole_SpF;

static double frac_SpF, slot_lag;

static int stereo, error_protection;

static III_side_info_t l3_side;
static CodecInitOut sOut;

static frame_params fr_ps;



char *pEncodedOutput;
int outputBit;

volatile double avg_slots_per_frame;





/*____ codecInit() ____________________________________________________________*/

CodecInitOut *codecInit (CodecInitIn *psIn)
{
int j;

/* Read psIn */

switch (psIn->frequency)
{
case 48000: info.sampling_frequency = 1; break;
case 44100: info.sampling_frequency = 0; break;
case 32000: info.sampling_frequency = 2; break;
default : return FALSE;
}

switch (psIn->mode)
{
case 0: info.mode = MPG_MD_STEREO ; info.mode_ext = 0; break;
case 2: info.mode = MPG_MD_DUAL_CHANNEL; info.mode_ext = 0; break;
case 3: info.mode = MPG_MD_MONO ; info.mode_ext = 0; break;
default: return FALSE;
}

j = 0;
while (j < 15 && bitratex[1][j] != psIn->bitrate)
j++;
info.bitrate_index = j;

info.version = 1; /* Default: MPEG-1 */
info.emphasis = psIn->emphasis;
info.extension = psIn->fPrivate;
info.copyright = psIn->fCopyright;
info.original = psIn->fOriginal;
info.error_protection = psIn->fCRC;


/*_______ Static-fix _______________*/


fInit_mdct_sub = 0;
fInit_mdct = 0;

fInit_fft = 0;

fInit_iteration_loop = 0;
/* DON'T DO THAT ALL THE TIME
fInit_huffman_read_flag = 0;
*/

fixStatic_loop();

l3_side.main_data_begin = 0;
fixStatic_reservoir();


/*___________________________________*/

psycho_anal_init (psIn->frequency);
initWindowFilterSubband ();
initFormatBitstream ();

/* clear buffers */
memset ((char *) l3_sb_sample, 0, sizeof(l3_sb_sample));
memset((char *) buffer, 0, sizeof(buffer));
/* memset((char *) snr32, 0, sizeof(snr32));*/
#if ORG_BUFFERS
memset((char *) sam, 0, sizeof(sam));
#endif



fr_ps.header = &info;
fr_ps.tab_num = -1; /* no table loaded */
fr_ps.alloc = NULL;
fr_ps.actual_mode = info.mode;
fr_ps.stereo = (info.mode == MPG_MD_MONO) ? 1 : 2;
fr_ps.sblimit = SBLIMIT;
fr_ps.jsbound = SBLIMIT;


stereo = fr_ps.stereo;
error_protection = info.error_protection;

avg_slots_per_frame =
((double) SAMPLES_PER_FRAME / s_freq[1][info.sampling_frequency]) *
((double) bitratex[1][info.bitrate_index] / 8.0);
whole_SpF = (int) avg_slots_per_frame;
frac_SpF = avg_slots_per_frame - (double) whole_SpF;
slot_lag = -frac_SpF;

/* if (frac_SpF == 0)
info.padding = 0;
*/
genNoisePowTab();

/*________________________*/


if( stereo != 2 )
sOut.nSamples = SAMPLES_PER_FRAME;
else
sOut.nSamples = SAMPLES_PER_FRAME*2;

sOut.bufferSize = 2048;

return &sOut; /* How many samples we want in each chunk... */
}




tyro_zhang 2004-06-25
  • 打赏
  • 举报
回复
买本书吧,西安电子科大的《Windows 声音应用程序开发指南》
压缩、解码程序http://bladeenc.mp3.no 有时上不了,多试试
lanstar200 2004-06-25
  • 打赏
  • 举报
回复
偶这里不能收发mail,楼上的大哥能不能贴出来啊?
zhangnanonnet 2004-06-25
  • 打赏
  • 举报
回复
留下你的MAIL,我给你一个MP3 DECODE
zhangnanonnet 2004-06-25
  • 打赏
  • 举报
回复
http://www.codeproject.com/audio/cmp3info.asp

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧