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 = (sample >> 0);
	rdata = (sample >> 8);
	//printf("ssss\n");
	*(outputptr++)=ldata;
	*(outputptr++)=rdata;
	//printf("buflen%d\n",strlen(outputbuf[i]));

	if (nchannels == 2)
	{
		sample = scale(*right_ch++);
		ldata = (sample >> 0);
		rdata = (sample >> 8);
		*(outputptr++)=ldata;
		*(outputptr++)=rdata;
	}
  }
	n*=4;
	outputptr=outputbuf;
	while(n)
	{
		write_num=write(fd_sound,outputptr,n);
		outputptr+=write_num;
		n-=write_num;
  		//printf("n:%d\n",n);
	}
	outputptr=outputbuf;

  return MAD_FLOW_CONTINUE;
}

static
enum mad_flow error(void *data,
		    struct mad_stream *stream,
		    struct mad_frame *frame)
{
  struct buffer *buffer = data;

  fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n",
	  stream->error, mad_stream_errorstr(stream),
	  stream->this_frame - buffer->start);

  /* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */

  return MAD_FLOW_CONTINUE;
}

static int decode(unsigned char const *start, unsigned long length)
{
  struct buffer buffer;
  struct mad_decoder decoder;
  int result;

  /* initialize our private message structure */

  buffer.start  = start;
  buffer.length = length;

  /* configure input, output, and error functions */

  mad_decoder_init(&decoder, &buffer,
		   input, 0 /* header */, 0 /* filter */, output,
		   error, 0 /* message */);

  /* start decoding */

  result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC);

  /* release the decoder */

  mad_decoder_finish(&decoder);

  return result;
}

int main(int argc, char **argv)
{
	if(argc < 3)
	{
		printf("argc error\n");
		return -1;
	}
	int rate_set, bits_set, ch_set,fd_file_path=0,DataLen;
	char file_path[256]={0};
	int *psound_data_buf=NULL;
	struct stat stat;
	void *fdm;
	//ch_set=2;
	//bits_set=16;
	//rate_set=44100;
	if(sscanf(argv[1], "%s", &file_path)!= 1 ||sscanf(argv[2], "%d", &vol_val)!= 1)
	{
		printf("argv error\n");
		return -1;
	}
	if(vol_val<0)
		vol_val=26;
	if(strcmp(&file_path[strlen(file_path)-4],".wav")!=0 && strcmp(&file_path[strlen(file_path)-4],".mp3")!=0)
	{
		printf("file is not wav or mp3 farmat\n");
		return -1;

	}
	while((fd_sound = open("/dev/dsp",O_WRONLY)) == -1) {
		 printf("Can not open /dev/dsp\n");
		 return -1;
	 }
	fd_file_path = open(file_path,O_RDONLY);
	if(fd_file_path == -1)
	{
		printf("fd_file_path open file error");
		goto exit;
	}

	if(strcmp(&file_path[strlen(file_path)-4],".wav")==0)
	{
		wav_struct FileWav;
		psound_data_buf=(int *)malloc(SND_OUT_BUF_SIZE);
		if(psound_data_buf == NULL)
			goto exit;

		memset(&FileWav,0,sizeof(FileWav));
		if((DataLen = read(fd_file_path, &FileWav, sizeof(FileWav)))>0)
		{
			if((strncmp(FileWav.rif_info.riff,RIFF_FIELD,strlen(RIFF_FIELD)) == 0)&&(strncmp(FileWav.rif_info.wave,WAVE_FIELD,strlen(WAVE_FIELD)) == 0))
			{
				rate_set=FileWav.fmt_info.sample_rate;
				ch_set=FileWav.fmt_info.channel_nb;
				bits_set=FileWav.fmt_info.bits_per_sample;
			}
			else
			{
				printf("wav head error\n");
				goto exit;
			}
		}
		else
		{
			goto exit;
		}
		//printf("sample:%d,channel:%d,bits:%d,vol_val:%d\n", rate_set,ch_set,bits_set,vol_val);
		ioctl(fd_sound, SNDCTL_DSP_SYNC, &rate_set);
		ioctl(fd_sound, SOUND_PCM_WRITE_RATE, &rate_set);
		ioctl(fd_sound, SNDCTL_DSP_SETFMT, &bits_set);
		ioctl(fd_sound, SOUND_PCM_WRITE_CHANNELS, &ch_set);
		ioctl(fd_sound, SOUND_MIXER_WRITE_VOLUME, &vol_val);
		while((DataLen=read(fd_file_path, psound_data_buf ,SND_OUT_BUF_SIZE))>0)
			write(fd_sound, psound_data_buf, DataLen);
			free(psound_data_buf);
	}
	/*mp3 play*/
	else if(strcmp(&file_path[strlen(file_path)-4],".mp3")==0)
	{
		if(fstat(fd_file_path,&stat)==-1||stat.st_size==0)
			goto exit;
		fdm=mmap(0,stat.st_size,PROT_READ,MAP_SHARED,fd_file_path,0);
		if(fdm==MAP_FAILED)
			goto exit;
		decode(fdm,stat.st_size);

	}

exit:
	if(munmap(fdm,stat.st_size)==-1)
	{
		printf("munmap error\n");
	}
	if(fd_file_path>0)
	{
		close(fd_file_path);
		fd_file_path=0;
	}
	if(fd_sound>0)
	{
		close(fd_sound);
		fd_sound=0;
	}

return 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 播放

时间: 2024-10-14 00:58:38

MP3/WAV 播放的相关文章

基于ALSA的WAV播放和录音程序

http://blog.csdn.net/azloong/article/details/6140824 这段时间在探索ALSA架构,从ALSA Core到ALSA Lib,再到Android Audio System.在看ALSA Lib时,写了一个比较典型的基于ALSA的播放录音程序.程序包包含四个部分: WAV Parser是对WAV文件的分析和封装,这里只针对Standard WAV File: SND Common是Playback 和Record共同操作,如SetParams.Rea

Nginx实现MP3的播放和下载

参考: http://segmentfault.com/blog/p_chou/1190000000437323?utm_source=tuicool http://www.netingcn.com/nginx-add-header.html http://nginx.org/cn/docs/http/ngx_http_rewrite_module.html 项目需要MP3下载的功能,GOOGLE了几篇文章,参考实现了这个功能,用时大概3个番茄钟,了解了Nginx内置变量和正则判断请求URL的方

简单mp3音频播放器的实现

本篇主要介绍使用Mediaplayer实现mp3简易音乐播放器,程序运行界面如下 下面是代码实现,因为代码比较简单,注释已经比较明确了. public class PlayActivity extends Activity implements OnClickListener { private EditText filenameText; // 音频播放的主要类 private MediaPlayer mediaPlayer; private String filename; // 记录播放位

推荐漂亮的flash网页MP3音乐播放器

文章来源:PHP开发学习门户 地址:http://www.php#thinking.com/archives/491  (去点#) 在网页制作中,如果想在网页中插入mp3音乐来增添网页的互动感,提升用户体验度,这个时候网页音乐播放器就很有必要了,一般的情况下如果用背景音乐播放的话有几个很不友好的地方 1.随网页加载就播放,用户不能暂停,停止播放 2.一般浏览器兼容性差,很少能通用全部浏览器 所以一款基于flash的网页音乐播放器就很有必要了. 他有以下一些优点 1.浏览器兼容性好,现在一般的主流

JS单曲调用百度mp3音乐播放器代码

在网上找的单曲调用百度mp3音乐播放器的代码,改了改,文本框输入歌曲名,中文逗号,歌手名,回车就可以试听了.几点说明:  百度音乐api 音乐文件地址,span,p,div,等都可以,ID 必须是songplay:  参数说明,第一个是歌曲名字,第二个是演唱者,最后一个如果为空则自动播放,不为空则手动播放.  参数间用中文逗号 , 分隔 ,点击按钮或者回车都可以播放. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN

推荐美丽的flash网页MP3音乐播放器

文章来源:PHP开发学习门户 地址:http://www.phpthinking.com/archives/491 在网页制作中.假设想在网页中插入mp3音乐来增添网页的互动感,提升用户体验度,这个时候网页音乐播放器就非常有必要了.一般的情况下假设用背景音乐播放的话有几个非常不友好的地方 1.随网页载入就播放,用户不能暂停.停止播放 2.一般浏览器兼容性差.非常少能通用所有浏览器 所以一款基于flash的网页音乐播放器就非常有必要了. 他有下面一些长处 1.浏览器兼容性好.如今一般的主流浏览器都

Android开发本地及网络Mp3音乐播放器(十五)网络音乐及歌词下载功能实现

实现功能: 实现网络音乐歌词下载功能(下载音乐的同时,下载对应歌词) 下载好的歌词目前不在播放器内,可以通过文件浏览器查看. 后续将博文,将实现本地音乐歌词下载和已下载音乐扫描功能. 因为,没有自己的服务器,所以网络音乐所有相关功能(包含搜索音乐.下载音乐.下载歌词)均无法保证时效性,建议,尽快下载和练习:如果你下载时候,已经因为我采集的服务器更改规则,请给我留言,如果可以解决,我将在有空的时候献上新的源码. 截止到目前的源码下载: http://download.csdn.net/album/

Android开发本地及网络Mp3音乐播放器(十四)网络音乐下载功能实现

实现功能: 实现网络音乐搜索功能 实现网络音乐下载功能 下载好的音乐目前不在播放器内,可以通过文件浏览器查看. 后续将博文,将实现歌词和下载音乐扫描功能. 经过将近4天,才发布这一篇博客,明显更新博客速度变慢了,因为没有自己的音乐服务器,网络上的音乐网站在这边博客发表的2016年5月已经很难找到免费且在线下载的了,就算找到解析也是一个难题.如果你在练习同样功能的Demo,请尽快下载练习,因为博主也无法保证我Demo下载功能时效性,因为我解析的音乐网站可能分分钟修改网页源码!!! 截止到目前的源码

Android开发本地及网络Mp3音乐播放器(九)音乐收藏与列表切换

实现功能: 使用快速开发框架xUtils中的DbUtils模块,为音乐收藏功能做准备 实现PlayActivity(独立音乐播放界面)收藏.取消收藏按钮 实现MainActivity(主界面)菜单选择事件进入MyLoveMusicActivity(音乐收藏界面) 实现本地音乐列表与音乐收藏列表切换功能 (目前源码,只实现了音乐收藏列表,菜单中最近播放列表后续会进行补充) 截止到目前的源码下载: http://download.csdn.net/detail/iwanghang/9504916 x