首页 > 代码库 > MP3/WAV 播放

MP3/WAV 播放

一.编译libmad 



1.先下载压缩包到本地,并解压

 tar -xvzf  libmad-0.15.1b.tar.gz   -C   ./

2.进入源码目录并配置

编写一个配置文件,便于< 修改和编译 >  文件内容如下

./configure CC=arm-linux-gcc  --host=arm-linux  --build=i686-pc-linux-gnu  --enable-fpm=arm  --enable-shared --disable-debugging --prefix=/home/tang/WIFI-Music/MPlayer/libmad-0.15.1b_install  

执行配置 并记录信息



3.make 编译 并记录信息



Tips 



修改makefile ,删除 " --fforce-mem "

4.  make  install 安装 并记录信息



tips

需要调用的库和文件为:libmad.so   mad.h 

二.编写 程序代码

1.可播放wav、mp3 两种格式代码。

< play-wav-or-mp3.c >

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/types.h>
#include <fcntl.h>
#include <sys/types.h>
#include <semaphore.h>
#include <sys/stat.h> 
#include <string.h>
#include <errno.h>
#include <linux/soundcard.h>

#include <termio.h>
#include <getopt.h>
#include <time.h>
#include <strings.h>
#include <signal.h>
#include "wav.h"
#include "mad.h"
#include <sys/mman.h>


#define SND_OUT_BUF_SIZE	0x2000	

struct buffer {
  unsigned char const *start;
  unsigned long length;
};

int fd_sound;
int n;
int vol_val;
int i=0;
static
enum mad_flow input(void *data,
		    struct mad_stream *stream)
{
  struct buffer *buffer = data;

  if (!buffer->length)
    return MAD_FLOW_STOP;

  mad_stream_buffer(stream, buffer->start, buffer->length);

  buffer->length = 0;

  return MAD_FLOW_CONTINUE;
}

static signed int scale(mad_fixed_t sample)
{
  /* round */
  sample += (1L << (MAD_F_FRACBITS - 16));

  /* clip */
  if (sample >= MAD_F_ONE)
    sample = MAD_F_ONE - 1;
  else if (sample < -MAD_F_ONE)
    sample = -MAD_F_ONE;

  /* quantize */
  return sample >> (MAD_F_FRACBITS + 1 - 16);
}

static
enum mad_flow output(void *data,
		     struct mad_header const *header,
		     struct mad_pcm *pcm)
{
  unsigned short nchannels ,nsamples;
  unsigned int  nsamplerate;
  unsigned char ldata,rdata;
  unsigned char outputbuf[8196],*outputptr;
  int write_num;
  mad_fixed_t const *left_ch, *right_ch;

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

  nchannels = pcm->channels;
  nsamplerate = pcm->samplerate;
  n=nsamples  = pcm->length;
  left_ch   = pcm->samples[0];
  right_ch  = pcm->samples[1];
  
  if(i==0){
		int bits_set=16;
		ioctl(fd_sound, SNDCTL_DSP_SYNC, &nsamplerate);
		ioctl(fd_sound, SOUND_PCM_WRITE_RATE, &nsamplerate);
		ioctl(fd_sound, SNDCTL_DSP_SETFMT, &bits_set);
		ioctl(fd_sound, SOUND_PCM_WRITE_CHANNELS, &nchannels);
		ioctl(fd_sound, SOUND_MIXER_WRITE_VOLUME, &vol_val);
	}
	i++;
  outputptr=outputbuf;
  while (nsamples--) {
    signed int sample;

    /* output sample(s) in 16-bit signed little-endian PCM */
	sample = scale(*left_ch++);
	ldata = http://www.mamicode.com/(sample >> 0);>
< wav.h >

#ifndef _WAV_H_
#define _WAV_H_

/*_____ I N C L U D E S ____________________________________________________*/


/*_____ M A C R O S ________________________________________________________*/

#define WAV_HEADER_SIZE   sizeof(wav_struct)

/* RIFF info */
#define RIFF_FIELD        "RIFF"
#define WAVE_FIELD        "WAVE"

/* FMT info */
#define FMT_FIELD         "FMT "
#define FMT_LENGTH        ((unsigned long)(16))  /* data start beg of sector */
/* wave format */
#define PCM_FMT           ((unsigned short)0x0100)
/* channel number */
#define MONO              ((unsigned short)0x0100)
#define STEREO            ((unsigned short)0x0200)
/* bytes per sample */
#define ONE_BYTE          ((unsigned short)0x0100)
#define TWO_BYTE          ((unsigned short)0x0200)
/* bits per sample */
#define EIGHT_BIT         ((unsigned short)0x0800)
#define SIXTEEN_BIT       ((unsigned short)0x1000)
/* DATA info */
#define DATA_FIELD        'data'


/*_____ D E F I N I T I O N ________________________________________________*/

/* WAV Format Structure */

typedef struct
{ /* RIFF info */
  char    riff[4];
  unsigned long  pack_length;
  char    wave[4];
} riff_struct;

typedef struct
{ /* FMT info */
  char    fmt[4];
  unsigned long  fmt_length;
  unsigned short  wav_format; 
  unsigned short  channel_nb;
  unsigned long  sample_rate;
  unsigned long  bytes_per_second;
  unsigned short  bytes_per_sample;
  unsigned short  bits_per_sample;
} fmt_struct;

typedef struct
{ /* DATA info */
  char    dat[4];
  unsigned long  data_length;
} data_struct;

typedef struct
{
  riff_struct   rif_info;
  fmt_struct    fmt_info;
  data_struct   dat_info;
} wav_struct;


/*_____ D E C L A R A T I O N ______________________________________________*/



#endif  /* _WAV_H_ */
    

动态编译  arm-none-linux-gnueabi-gcc play-wav-or-mp3.c  -o  play-wav-or-mp3  -lmad  -L./ 

运行  ./play-wav-or-mp3  xxx.mp3/wav  70   

argc[1] 为播放歌曲,argc[2] 为音量大小


MP3/WAV 播放