关键数据结构之帧结构:mad_herder和mad_frame计算机等级考试

文章作者 100test 发表时间 2009:07:08 02:56:37
来源 100Test.Com百考试题网


  编辑特别推荐:

  全国计算机等级考试(等考)指定教材

  全国计算机等级考试学习视频

  全国计算机等级考试网上辅导招生

  全国计算机等级考试时间及科目预告

  百考试题教育全国计算机等级考试在线测试平台

  全国计算机等级考试资料下载

  全国计算机等级考试论坛

  一个MP3帧由帧头和帧数据构成。Madlib分别填充mad_herder和mad_frame这两个结构,然后进行解码。mad_herder里包含mp3数据的描述信息,这个结构在frame.h头文件中定义:
  view plaincopy to clipboardprint?
  struct mad_header {
  enum mad_layer layer. /* audio layer (1, 2, or 3) */
  enum mad_mode mode. /* channel mode (see above) */
  int mode_extension. /* additional mode info */
  enum mad_emphasis emphasis. /* de-emphasis to use (see above) */
  unsigned long bitrate. /* stream bitrate (bps) */
  unsigned int samplerate. /* sampling frequency (Hz) */
  unsigned short crc_check. /* frame CRC accumulator */
  unsigned short crc_target. /* final target CRC checksum */
  int flags. /* flags (see below) */
  int 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) */
  int mode_extension. /* additional mode info */
  enum mad_emphasis emphasis. /* de-emphasis to use (see above) */
  unsigned long bitrate. /* stream bitrate (bps) */
  unsigned int samplerate. /* sampling frequency (Hz) */
  unsigned short crc_check. /* frame CRC accumulator */
  unsigned short crc_target. /* final target CRC checksum */
  int flags. /* flags (see below) */
  int private_bits. /* private bits (see below) */
  mad_timer_t duration. /* audio playing time of frame */
  }.
  layer成员的类型是enum mad_layer,这个枚举类型有3个取值(1,2,3),分别对应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 clipboardprint?
  struct mad_frame {
  struct mad_header header. /* MPEG audio header */
  int 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 */
  int 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 clipboardprint?
  static
  enum mad_flow output(void *data,
  struct mad_header const *header,
  struct mad_pcm *pcm)
  {
  unsigned int 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 int 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位
  if (nchannels == 2) {
  sample = scale(*right_ch ).
  putchar((sample >.>. 0) &. 0xff).//输出低8位
  putchar((sample >.>. 8) &. 0xff).//输出高8位
  }
  }
  static
  enum mad_flow output(void *data,
  struct mad_header const *header,
  struct mad_pcm *pcm)
  {
  unsigned int 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 int 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位
  if (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数据在屏幕上打印显示.

相关文章


C程序语言中数学函数计算机等级考试
C任意进制转换程序计算机等级考试
关键数据结构之帧结构:mad_herder和mad_frame计算机等级考试
用VC验证EMAIL有效性计算机等级考试
用DOS批处理来做数字图像处理计算机等级考试
内存分配管理的代码用C实现计算机等级考试
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛