关键数据结构的帧结构:mad_herder和mad_frame

个MP3帧由帧头和帧数据构成Madlib分别填充mad_herder和mad_frame这两个结构然后进行解码mad_herder里包含mp3数据描述信息这个结构在frame.h头文件中定义:


view plaincopy to clipboardpr?
struct mad_header {
enum mad_layer layer; /* audio layer (1, 2, or 3) */
enum mad_mode mode; /* channel mode (see above) */
mode_extension; /* additional mode info */
enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
unsigned long bitrate; /* stream bitrate (bps) */
unsigned samplerate; /* sampling frequency (Hz) */
unsigned crc_check; /* frame CRC accumulator */
unsigned crc_target; /* final target CRC checksum */
flags; /* flags (see below) */
private_bits; /* private bits (see below) */
mad_timer_t duration; /* audio playing time of frame */
};
struct mad_header {
enum mad_layer layer; /* audio layer (1, 2, or 3) */
enum mad_mode mode; /* channel mode (see above) */
mode_extension; /* additional mode info */
enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
unsigned long bitrate; /* stream bitrate (bps) */
unsigned samplerate; /* sampling frequency (Hz) */
unsigned crc_check; /* frame CRC accumulator */
unsigned crc_target; /* final target CRC checksum */
flags; /* flags (see below) */
private_bits; /* private bits (see below) */
mad_timer_t duration; /* audio playing time of frame */
};



layer成员类型是enum mad_layer这个枚举类型有3个取值(123)分别对应MPEG音频1、2、3层;mode成员描述音频声道数和立体声类型取值为MAD_MODE_SINGLE_CHANNEL(单声道)、MAD_MODE_DUAL_CHANNEL(双声道)、MAD_MODE_JOINT_STEREO(联合立体声)、MAD_MODE_STEREO(普通立体声);接下来比特率、采样率、CRC校验、播放时间等信息直接来自mp3帧

mad_frame包含个帧头(mad_herder)和帧中采样数据该结构同样定义于frame.h头文件中:

view plaincopy to clipboardpr?
struct mad_frame {
struct mad_header header; /* MPEG audio header */
options; /* decoding options (from stream) */
mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
};
struct mad_frame {
struct mad_header header; /* MPEG audio header */
options; /* decoding options (from stream) */
mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
};


view plaincopy to clipboardpr?

enum mad_flow output(void *data,
struct mad_header const *header,
struct mad_pcm *pcm)
{
unsigned nchannels, nsamples;
mad_fixed_t const *left_ch, *right_ch;

/* pcm->samplerate contains the sampling frequency */

nchannels = pcm->channels;
nsamples = pcm->length;
left_ch = pcm->samples[0];
right_ch = pcm->samples[1];

while (nsamples--) {
signed sample;

/* output sample(s) in 16-bit signed little-endian PCM */

sample = scale(*left_ch);
putchar((sample >> 0) & 0xff);//输出低8位
putchar((sample >> 8) & 0xff);//输出高8位

(nchannels 2) {
sample = scale(*right_ch);
putchar((sample >> 0) & 0xff);//输出低8位
putchar((sample >> 8) & 0xff);//输出高8位
}
}

enum mad_flow output(void *data,
struct mad_header const *header,
struct mad_pcm *pcm)
{
unsigned nchannels, nsamples;
mad_fixed_t const *left_ch, *right_ch;

/* pcm->samplerate contains the sampling frequency */

nchannels = pcm->channels;
nsamples = pcm->length;
left_ch = pcm->samples[0];
right_ch = pcm->samples[1];

while (nsamples--) {
signed sample;

/* output sample(s) in 16-bit signed little-endian PCM */

sample = scale(*left_ch);
putchar((sample >> 0) & 0xff);//输出低8位
putchar((sample >> 8) & 0xff);//输出高8位

(nchannels 2) {
sample = scale(*right_ch);
putchar((sample >> 0) & 0xff);//输出低8位
putchar((sample >> 8) & 0xff);//输出高8位
}
}

其中option字段来自mad_stream结构sbsample[2][36][32]中保存就是从mp3文件中取得采样数据:2个声道每声道36个采样(可播放26ms音频每秒帧速率大约为38fps);overlap指针成我员不了解它用途希望有高手不吝赐教!

Madlib每次解码循环结束时解码完成个帧将1152个PCM采样数据保存在里传递给output回调作输出前处理压缩包里参考举例minimad.c中output回调只是简单地将PCM数据在屏幕上打印显示:
Tags: 

延伸阅读

最新评论

发表评论