基于libmad 的简单MP3流媒体播放器的实现

豆豆网   技术应用频道   2007年03月10日  【字号: 收藏本文

本文详细介绍基于libmad 的简单MP3流媒体播放器的实现

SND_PCM_ACCESS_RW_NONINTERLEAVED

  非交错访问。每个 PCM 帧只是一个声道需要的数据,如果使用多个声道,那么第一帧是第一个声道的数据,第二帧是第二个声道的数据,依此类推。

  函数 snd_pcm_hw_params_set_format() 设置数据格式,主要控制输入的音频数据的类型、无符号还是有符号、是 little-endian 还是 bit-endian。比如对于 16-bit 长度的采样数据可以设置为:

SND_PCM_FORMAT_S16_LE   有符号16 bit Little Endian
SND_PCM_FORMAT_S16_BE   有符号16 bit Big Endian
SND_PCM_FORMAT_U16_LE   无符号16 bit Little Endian
SND_PCM_FORMAT_U16_BE   无符号 16 bit Big Endian

  比如对于 32-bit 长度的采样数据可以设置为:

SND_PCM_FORMAT_S32_LE   有符号32 bit Little Endian
SND_PCM_FORMAT_S32_BE   有符号32 bit Big Endian
SND_PCM_FORMAT_U32_LE   无符号32 bit Little Endian
SND_PCM_FORMAT_U32_BE   无符号 32 bit Big Endian

  函数 snd_pcm_hw_params_set_channels() 设置音频设备的声道,常见的就是单声道和立体声,如果是立体声,设置最后一个参数为2。snd_pcm_hw_params_set_rate_near () 函数设置音频数据的最接近目标的采样率。snd_pcm_hw_params( ) 从设备配置空间选择一个配置,让函数 snd_pcm_prepare() 准备好 PCM 设备,以便写入 PCM 数据。snd_pcm_writei() 用来把交错的音频数据写入到音频设备。

  初始化 PCM 设备的例程如下:

  清单 6:初始化 PCM 设备的例程

/* open a PCM device */
int open_device(struct mad_header const *header)
{
  int err;
  snd_pcm_hw_params_t *hw_params;
  char *pcm_name = "plughw:0,0";
  int rate = header->samplerate;
  int channels = 2;
  if (header->mode == 0) {
   channels = 1;
  } else {
   channels = 2;
  }
  if ((err = snd_pcm_open (&playback_handle,
              pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
   printf("cannot open audio device %s (%s)
",
   pcm_name,
   snd_strerror (err));
   return -1;
  }
  if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
   printf("cannot allocate hardware parameter structure (%s)
",
   snd_strerror (err));
   return -1;
  }
  if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
   printf("cannot initialize hardware parameter structure (%s)
",
   snd_strerror (err));
   return -1;
  }
  if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params,
       SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
   printf("cannot set access type (%s)
",
   snd_strerror (err));
   return -1;
  }
  
  if ((err = snd_pcm_hw_params_set_format (playback_handle,
       hw_params, SND_PCM_FORMAT_S32_LE)) < 0) {
   printf("cannot set sample format (%s)
",
   snd_strerror (err));
   return -1;
  }
  if ((err = snd_pcm_hw_params_set_rate_near (playback_handle,
       hw_params, &rate, 0)) < 0) {
   printf("cannot set sample rate (%s)
",
   snd_strerror (err));
   return -1;
  }
  if ((err = snd_pcm_hw_params_set_channels (playback_handle,
       hw_params, channels)) < 0) {
   printf("cannot set channel count (%s)
",
   snd_strerror (err));
   return -1;
  }
  if ((err = snd_pcm_hw_params (playback_handle,
       hw_params)) < 0) {
   printf("cannot set parameters (%s)
",
   snd_strerror (err));
   return -1;
  }
  snd_pcm_hw_params_free (hw_params);
  if ((err = snd_pcm_prepare (playback_handle)) < 0) {
   printf("cannot prepare audio interface for use (%s)
",
   snd_strerror (err));
   return -1;
  }
  return 0;
}

责编:豆豆技术应用

正在加载评论...