libmad解码mp3需要多大苹果8运行内存多大

STM32 软解MP3
libmad helix MP3软解码 - STM32 - 意法半导体STM32/STM8技术社区
后使用快捷导航没有帐号?
查看: 13223|回复: 24
STM32 软解MP3
libmad helix MP3软解码
在线时间11 小时
主题帖子好友
忘记是哪里下载的了,发到这里给大家共享一下.
(4 MB, 下载次数: 883)
14:33 上传
点击文件名下载附件
(1.36 MB, 下载次数: 700)
14:35 上传
点击文件名下载附件
(242 Bytes, 下载次数: 497)
14:35 上传
点击文件名下载附件
在线时间20 小时
主题帖子好友
中级会员, 积分 277, 距离下一级还需 223 积分
中级会员, 积分 277, 距离下一级还需 223 积分
回复:STM32 软解MP3
libmad helix MP3软解码
LZ可否用RAR压缩再传上来,我下载下来怎么都解不出来,用HAOYA的工具
在线时间0 小时
主题帖子好友
新手上路, 积分 694, 距离下一级还需 -644 积分
新手上路, 积分 694, 距离下一级还需 -644 积分
RE:STM32 软解MP3
libmad helix MP3软解码
谢谢!楼主分享!
在线时间1 小时
主题帖子好友
金牌会员, 积分 2728, 距离下一级还需 2272 积分
金牌会员, 积分 2728, 距离下一级还需 2272 积分
回复:STM32 软解MP3
libmad helix MP3软解码
在线时间0 小时
主题帖子好友
新手上路, 积分 10, 距离下一级还需 40 积分
新手上路, 积分 10, 距离下一级还需 40 积分
回复:STM32 软解MP3
libmad helix MP3软解码
在线时间1 小时
主题帖子好友
新手上路, 积分 18, 距离下一级还需 32 积分
新手上路, 积分 18, 距离下一级还需 32 积分
回复:STM32 软解MP3
libmad helix MP3软解码
duoxe duoDASD
在线时间1 小时
主题帖子好友
新手上路, 积分 8, 距离下一级还需 42 积分
新手上路, 积分 8, 距离下一级还需 42 积分
回复:STM32 软解MP3
libmad helix MP3软解码
谢谢,已经下载,还没试。
在线时间14 小时
主题帖子好友
中级会员, 积分 223, 距离下一级还需 277 积分
中级会员, 积分 223, 距离下一级还需 277 积分
回复:STM32 软解MP3
libmad helix MP3软解码
楼主辛苦了!!
在线时间14 小时
主题帖子好友
中级会员, 积分 223, 距离下一级还需 277 积分
中级会员, 积分 223, 距离下一级还需 277 积分
回复:STM32 软解MP3
libmad helix MP3软解码
楼主辛苦了!!
在线时间0 小时
主题帖子好友
新手上路, 积分 20, 距离下一级还需 30 积分
新手上路, 积分 20, 距离下一级还需 30 积分
回复:STM32 软解MP3
libmad helix MP3软解码
这个源码是我在21ic上首发的,当时还处于测试阶段,基本能用,但问题还很多。现在已经做出了开发板,有兴趣的可以在淘宝上搜索 libmad即可找到。
站长推荐 /2
,同时大家也可以下载电子版学习
Tel: 3-8064
备案号: 苏ICP备号-2
|||意法半导体STM32/STM8技术社区
Powered bysponsored links
libmad解码mp3生成pcm文件
在之前的一篇文章中介绍了如何在linux下,使用libmad解码mp3并且播放,将源码编译了,可以正常的播放MP3文件,但是在项目里面需要将mp3解码成pcm文件,所以需要将之前的代码进行修改一下,修改是在原来的基础上的,这样可以测试一下。
* 本程序是从 minimad 改进而来,如要更详细的说明请参看 minimad.c
* MyMinimad.c ,
, SiChuan University , China
* 编译: gcc MyMinimad.c -o MyMinimad -lmad -lasound
* 运行: ./MyMinimad filename.mp3
* 使用libmad解码mp3然后保存成pcm文件。
* 编译: gcc MyMinimad.c -o MyMinimad -lmad
* 运行: ./MyMinimad filename.mp3 outputfilename.pcm
#include &stdio.h&
#include &stdlib.h&
#include &unistd.h&
#include &sys/stat.h&
#include &sys/mman.h&
//#include &sys/soundcard.h&
#include &sys/ioctl.h&
#include &sys/fcntl.h&
#include &sys/types.h&
#include &mad.h&
//#include &alsa/asoundlib.h&
#define SAMPLE_RATE 44100
#define CHANNELS 2
#define PCM_DEVICE &plughw:0,0&
static snd_pcm_hw_params_t *hwparams = NULL;
static snd_pcm_t *pcm_handle = NULL;
struct buffer
unsigned char const *
static int decode (unsigned char const *, unsigned long);
//static int init_alsa ();
FILE *outF
int main (int argc, char *argv[])
char const *
if(argc != 3 )return -1;
outFile = fopen(argv[2], &w+&);
file = argv[1];
fd = open (file, O_RDONLY);
if (fstat (fd, &stat) == -1 || stat.st_size == 0)
return -1;
fdm = mmap (0, stat.st_size, PROT_READ, MAP_SHARED, fd, 0);//将文件内容拷贝到内存里面
if (fdm == MAP_FAILED)
return -1;
if (init_alsa () == -1)
fprintf (stderr, &init_alsa() error/n&);
return -1;
decode (fdm, stat.st_size);//进行解码
fclose(outFile);//关闭文件指针
if (munmap (fdm, stat.st_size) == -1)
return -1;
//static int init_alsa ()
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
char *pcm_
int rate = SAMPLE_RATE;
/* Sample rate */
int exact_
/* Sample rate returned by */
pcm_name = strdup (PCM_DEVICE);
snd_pcm_hw_params_alloca (&hwparams);
if (snd_pcm_open (&pcm_handle, pcm_name, stream, 0) & 0)
fprintf (stderr, &Error opening PCM device %s/n&, pcm_name);
return -1;
if (snd_pcm_hw_params_any (pcm_handle, hwparams) & 0)
fprintf (stderr, &Can not configure this PCM device./n&);
return -1;
if (snd_pcm_hw_params_set_access (pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) & 0)
fprintf (stderr, &Error setting access./n&);
return -1;
if (snd_pcm_hw_params_set_format (pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE) & 0)
fprintf (stderr, &Error setting format./n&);
return -1;
exact_rate =
if (snd_pcm_hw_params_set_rate_near (pcm_handle, hwparams, &exact_rate, 0) & 0)
fprintf (stderr, &Error setting rate./n&);
return -1;
if (rate != exact_rate)
fprintf (stderr, &The rate %d Hz is not supported by your hardware./n==& Using %d Hz instead./n&, rate, exact_rate);
if (snd_pcm_hw_params_set_channels (pcm_handle, hwparams, CHANNELS) & 0)
fprintf (stderr, &Error setting channels./n&);
return -1;
if (snd_pcm_hw_params (pcm_handle, hwparams) & 0)
fprintf (stderr, &Error setting HW params./n&);
return -1;
static enum mad_flow input (void *data, struct mad_stream *stream)
struct buffer *buffer =
if (!buffer-&length)
return MAD_FLOW_STOP;
mad_stream_buffer (stream, buffer-&start, buffer-&length);
buffer-&length = 0;
return MAD_FLOW_CONTINUE;
/*这一段是处理采样后的pcm音频 */
static inline signed int scale (mad_fixed_t sample)
sample += (1L && (MAD_F_FRACBITS - 16));
if (sample &= MAD_F_ONE)
sample = MAD_F_ONE - 1;
else if (sample & -MAD_F_ONE)
sample = -MAD_F_ONE;
return sample && (MAD_F_FRACBITS + 1 - 16);
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_
unsigned char Output[6912], *OutputP
int fmt, wrote, speed, exact_rate, err,
nchannels = pcm-&
n = nsamples = pcm-&
left_ch = pcm-&samples[0];
right_ch = pcm-&samples[1];
fmt = AFMT_S16_LE;
speed = pcm-&samplerate * 2;
/*播放速度是采样率的两倍 */
OutputPtr = O//将OutputPtr指向Output
while (nsamples--)
sample = scale (*left_ch++);
*(OutputPtr++) = sample && 0;
*(OutputPtr++) = sample && 8;
if (nchannels == 2)
sample = scale (*right_ch++);
*(OutputPtr++) = sample && 0;
*(OutputPtr++) = sample && 8;
OutputPtr = O//由于之前的操作将OutputPtr的指针指向了最后,这时需要将其指针移动到最前面
fwrite(OutputPtr, 1, n*2*nchannels, outFile);
snd_pcm_writei (pcm_handle, OutputPtr, n);
OutputPtr = O//写完文件后,OutputPtr的指针也移动到了最后,这时需要将其指针移动到最前面
return MAD_FLOW_CONTINUE;
static enum mad_flow error (void *data, struct mad_stream *stream, struct mad_frame *frame)
return MAD_FLOW_CONTINUE;
static int decode (unsigned char const *start, unsigned long length)
struct mad_
buffer.start =
buffer.length =
mad_decoder_init (&decoder, &buffer, input, 0, 0, output, error, 0);
mad_decoder_options (&decoder, 0);
result = mad_decoder_run (&decoder, MAD_DECODER_MODE_SYNC);
mad_decoder_finish (&decoder);
在终端运行gcc& MyMinimad.c -o MyMinimad -lmad就可以生成解码mp3文件生成pcm的工具.
资料转载自网上 自己进行了小修改 能生成资源但没进行验证
转载来自:http://blog.csdn.net/blogercn/archive//4432331.aspx
#include &stdio.h& #include &stdlib.h& #include &assert.h& #i ...
mp3是流媒体,所以一个完整文件往往比较大而且不能一次装入sound缓存,所以其buffer管理就成了最大难题,至于解码部分其实还是很简单的,下面是仅关于解码部分的说明
首先应该在自己的工程中包含以下三个库: libid3tag-0.15.1b libmad-0.15.1b libz-1.1.4 必要的三个结构体及相关的初始化 mad_stream st ...
一.编译libmad库
1.下载libmad源码,解压.
2. ./configure --prefix=/usr (安装到/usr/lib目录)
3.make & make install
出现错误信息 error: unrecognized command line option &-f ...
转眼间不做wp开发,投身于php事业已然一年了,转身看到8.1的发布,俨然一片欣欣向荣的景象,但是开发社区却没比一年前有过多大的提高,这并不是一个好现象,遂在git上开源了之前音频处理库,希望能对社区有所贡献,地址如下:/sandcu/wpaudio 觉得有用的同学请在git上点个星,好让更多的同学看到,下面开始正文. 用 ...
libmad:是一个开源的高精度mpeg音频解码库,支持 MPEG-1(Layer I, Layer II 和 LayerIII(也就是 MP3).LIBMAD 提供 24-bit 的 PCM 输出,完全是定点计算,非常适合没有浮点支持的平台上使用.使用 libmad 提供的一系列 API,就可以非常简单地实现 MP3 数据解码工作.在 libmad 的源代 ...MP3软解码库Libmad详细解释_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
MP3软解码库Libmad详细解释
&&介绍了MP3解码算法流程,对Libmad源代码进行分析,并附带了Libmad的交叉编译过程。
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩41页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
libmad库中附带minimad,hige level API example,minimad执行使用minimad,再加上一些音频参数设置,即可实现一个简单的mp3播放程序;首先:在minimad.c中加入以下代码,# include &stdio.h&# include &unistd.h&# include &sys/stat.h&# include &sys/mman.h&#include &stdlib.h&#include &fcntl.h&#include &sys/types.h&#include &sys/ioctl.h&#include &sys/soundcard.h&# include "mad.h"#undef putchar
int writedsp(int c) {return write(soundfd, (char *)&c, 1);}
void set_dsp(){int rate = 441000;;&&&&&&&&&&&&&&& /* 采样频率 44.1KHz*/int format = AFMT_S16_LE; /*&&&& 量化位数 16&&&&& */int channels = 2;&&&&&&&&&&&&&&&& /*&&&& 声道数 2&&&&&&&&&& */
soundfd = open ( "/dev/dsp", O_WRONLY);ioctl(soundfd, SNDCTL_DSP_SPEED, &rate);ioctl(soundfd, SNDCTL_DSP_SETFMT, &format);ioctl(soundfd, SNDCTL_DSP_CHANNELS, &channels);}
修改minimad代码如下:1.在main函数中解码前调用set_dsp(),解码结束后close(soundfd);
int main(int argc, char *argv[]){void *
if (argc != 1)&&& return 1;
if (fstat(STDIN_FILENO, &stat) == -1 ||&&&&& stat.st_size == 0)&&& return 2;
fdm = mmap(0, stat.st_size, PROT_READ, MAP_SHARED, STDIN_FILENO, 0);if (fdm == MAP_FAILED)&&& return 3;
set_dsp(); //here
decode(fdm, stat.st_size);
if (munmap(fdm, stat.st_size) == -1)&&& return 4;
close(soundfd); //here
return 0;}
2.修改output函数中的putchar为writedsp:enum mad_flow output(void *data,&&&&&&&&&&&& struct mad_header const *header,&&&&&&&&&&&& struct mad_pcm *pcm){unsigned int nchannels,mad_fixed_t const *left_ch, *right_
/* pcm-&samplerate contains the sampling frequency */
nchannels = pcm-&nsamples = pcm-&left_ch&& = pcm-&samples[0];right_ch = pcm-&samples[1];
while (nsamples--) {&&&
&&& /* output sample(s) in 16-bit signed little-endian PCM */
&&& sample = scale(*left_ch++);&&& writedsp((sample && 0) & 0xff);&&& writedsp((sample && 8) & 0xff);
&&& if (nchannels == 2) {&&&&& sample = scale(*right_ch++);&&&&& writedsp((sample && 0) & 0xff);&&&&& writedsp((sample && 8) & 0xff);&&& }}
return MAD_FLOW_CONTINUE;}
播放命令:#./minimad &music.mp3
结果:DBM上运行顺畅,而开发板上很卡,估计是AC97驱动还有待改善。
阅读(4603)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'采用libmad编写最简单的mp3播放器',
blogAbstract:'
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}libmad使用一步步进阶 - CSDN博客
libmad使用一步步进阶
原文地址:
libmad是一个开源mp3解码库,其对mp3解码算法做了很多优化,性能较好,很多播放器如mplayer、xmms等都是使用这个开源库进行解码的;如果要设计mp3播放器而又不想研究mp3解码算法的话,libmad是个不错的选择,可是问题来了:
libmad配套的相关文档太少,可以说几乎没有,只有一个示例程序minimad.c,但没有一定经验的人根本不知道怎么编译这个minimad.c,就算是编译了也不知道怎么运行、怎么播放mp3;网上讲libmad和minimad.c的文章很多,但能解释清楚的少之又少,大家都是抄来抄去,要么是不懂装懂,要么是懂了一点就自以为精通了,这样一来的结果是:在网上搜两天也弄不明白libmad究竟怎么使用。
所幸手里有Altera公司的一个工程,借助对该工程的分析、minimad.c中少的可怜的注释和网上搜索的Linux音频方面的相关知识,反复思考编码,总算把libmad库用起来了,现记录一下其使用方法,在帮助别人的同时也方便自己回头查询。 在开始之前,最好先把mp3文件格式和Linux音频编程方面的知识先学习一下,不然后面有的东西可能听不懂,还有就是一定要熟悉Linux系统,后面的代码都是在linux系统中用gcc编译的,在Windows下不能用的。 首先看下面几个问题,这也是我一开始最迷惑的,弄明白这几个问题了,也就对libmad库的使用相当熟悉了:
minimad.c怎么编译?编译后怎么运行?运行时的输入输出分别是什么,或者说运行时什么效果?怎样播放minimad输出的数据?或者说怎么播放解码后的数据?minimad运行时,mp3数据来源是标准输入,能不能改为从文件中读入数据?该怎么改?minimad运行时首先要将整个mp3文件读入内存,能不能改成边解码边读入的形式,比如每次读入16K,解码完再读入16K,而又不影响播放的连贯性,这样可以节省内存开销,方便在嵌入式系统中使用;怎样用libmad做一个简单的mp3播放器?
一个一个来讲吧。
minimad.c怎么编译?编译后怎么运行?运行时的输入输出分别是什么,或者说运行时什么效果?& 在Linux下(我前面说了,本文所有的工作都是在Linux进行)先安装libmad,说白了就是把libmad库导入C标准库,安装方法见libmad-0.15.1b中的README和INSTALL文件。 安装libmad后,新建一个文件夹,将libmad-0.15.1b中的minimad.c和mad.h复制过来,用gcc编译minimad.c,编译命令为(假设要生成的可执行程序为minimad):&gcc
-o minimad minimad.c -lmad minimad程序从标准输入读入mp3文件,然后将解码后的音频数据送到标准输出,我们可以用重定向的方式从文件中读入数据并将结果写至文件,命令如下:&./minimad tmp.pcm
怎样播放minimad输出的数据?或者说怎么播放解码后的数据?& 假设你有Linux音频编程方面的基础的话,这个应该不成问题,如果没有也没关系,在Linux的设计理念中,一切皆是文件,音频设备也是文件,只需要打 开/dev/dsp(音频设备)这个文件,然后将解码后的数据写入这个文件即可实现播放,新建pcmplay.c文件,拷入如下代码:&
int main(int argc, char *argv[])
char buf[1024];
/*simple rate 44.1KHz*/
/*quatize args*/
/*sound channel*/
if(argc != 2)
fprintf(stderr, &usage : %s \n&, argv[0]);
if((fd = open(argv[1], O_RDONLY)) & 0)
fprintf(stderr, &Can't open sound file!\n&);
if((id = open(&/dev/dsp&, O_WRONLY)) 0)
write(id, buf, i);
//printf(&i=%d\n&, i);
close(fd);
close(id);
编译pcmplay文件,然后就可以用生成的可执行程序播放第一步中声称的tmp.pcm文件,命令如下:&
gcc -o pcmplay pcmplay.c
./minimad tmp.pcm
播放时可能会变调,这是因为上面这段代码中将音频设备采样率固定设置为44.1k,而mp3文件不一定是这个采样率,解决方法后面会讲。&
minimad运行时,mp3数据来源是标准输入,能不能改为从文件中读入数据?该怎么改? 当然可以改,而且改起来相当的简单,如果不知道怎么改只能说明自己没仔细看minimad.c,你可能不知道struct stat是什么,也不清楚mmap()函数有什么用,但这些都可以在网上查到的,查了之后稍加分析就会发现原来就是把一片数据放入一块内存并得到它的长度 而已,那改成文件读入的方式也很容易,用fopen打开文件,计算一下文件的长度,然后用fread把数据全部读出来即可,这里就不贴代码了。&minimad运行时首先要将整个mp3文件读入内存,能不能改成边解码边读入的形式,比如每次读入16K,解码完再读入16K,而又不影响播放的连贯性,这样可以节省内存开销,方便在嵌入式系统中使用; 修改input()函数,在调用libmad中的mad_decoder_run()实现播放时,首先检查待解码缓存区中有没有数据,有则 解码,没有则调用input()函数一次以填充数据(填充多少可以自己指定),然后开始解码,解码后的数据交给output()函数处理,解码过程中,一 旦待解码缓存区中的解码数据不够则再次调用input()函数……
在这里还要提一下struct buffer这个结构体,这个结构体是在input、output和decoder之间传送数据的载体,可以自行定义,比如我的数据来源是文件,待解码数 据缓存区大小为4K,要传递的私有数据包括文件指针、当前的位置、数据缓冲区、缓冲区的实际大小、文件的总大小等,则我这里定义如下:&
struct buffer {
/*file pointer*/
/*file length*/
/*current position*/
unsigned char fbuf[BUFSIZE];
/*buffer*/
/*indeed size of buffer*/
typedef struct buffer mp3_
修改input()函数为如下形式,则每次调用填充BUFSIZE字节的数据:&
enum mad_flow input(void *data,
struct mad_stream *stream)
mp3_file *mp3
unproc_data_
/*the unprocessed data's size*/
mp3fp = (mp3_file *)
if(mp3fp-&fpos flen)
unproc_data_size = stream-&bufend - stream-&next_
memcpy(mp3fp-&fbuf, mp3fp-&fbuf+mp3fp-&fbsize-unproc_data_size, unproc_data_size);
copy_size = BUFSIZE - unproc_data_
if(mp3fp-&fpos + copy_size & mp3fp-&flen)
copy_size = mp3fp-&flen - mp3fp-&
fread(mp3fp-&fbuf+unproc_data_size, 1, copy_size, mp3fp-&fp);
mp3fp-&fbsize = unproc_data_size + copy_
mp3fp-&fpos
+= copy_
/*Hand off the buffer to the mp3 input stream*/
mad_stream_buffer(stream, mp3fp-&fbuf, mp3fp-&fbsize);
ret_code = MAD_FLOW_CONTINUE;
ret_code = MAD_FLOW_STOP;
return ret_
注意:在上面的代码中涉及到了断桢问题,即一桢跨了两个BUFSIZE,这时候应该将缓冲区中的剩余数据先移至缓冲区头部,然后再从文件中读出数据填充缓冲区。&
怎样用libmad设计一个简单的mp3播放器?& 修改output()函数。 我在上面说过了,解码后的数据通过output()函数进行处理,在minimad.c中output()函数直接将解码后的数据送到标准输出,其实只要将这里修改为送到音频设备就可以实现播放了。 还有一点需要说明的是:mp3文件的采样率不是固定不变的,解码后的数据中包括采样率,在播放过程中,一旦采样率发生变化,要重新设置一下音频设备。 新建一个mp3player.c文件,然后将下面的代码复制进去,编译生成mp3player,这就是一个简单的mp3播放器了,可以用./mp3player
1.mp3命令来播放1.mp3文件。&
#include &mad.h&
#define BUFSIZE 8192
* This is a private message structure. A generic pointer to this structure
* is passed to each of the callback functions. Put here any data you need
* to access from within the callbacks.
struct buffer {
/*file pointer*/
/*file length*/
/*current position*/
unsigned char fbuf[BUFSIZE];
/*buffer*/
/*indeed size of buffer*/
typedef struct buffer mp3_
/*soundcard file*/
unsigned int prerate = 0;
/*the pre simple rate*/
int writedsp(int c)
return write(soundfd, (char *)&c, 1);
void set_dsp()
int format = AFMT_S16_LE;
int channels = 2;
soundfd = open(&/dev/dsp&, O_WRONLY);
ioctl(soundfd, SNDCTL_DSP_SETFMT, &format);
ioctl(soundfd, SNDCTL_DSP_CHANNELS, &channels);
* This is perhaps the simplest example use of the MAD high-level API.
* Standard input is mapped into memory via mmap(), then the high-level API
* is invoked with three callbacks: input, output, and error. The output
* callback converts MAD's high-resolution PCM samples to 16 bits, then
* writes them to standard output in little-endian, stereo-interleaved
static int decode(mp3_file *mp3fp);
int main(int argc, char *argv[])
long flen, fsta,
mp3_file *mp3
if (argc != 2)
mp3fp = (mp3_file *)malloc(sizeof(mp3_file));
if((mp3fp-&fp = fopen(argv[1], &r&)) == NULL)
printf(&can't open source file.\n&);
fsta = ftell(mp3fp-&fp);
fseek(mp3fp-&fp, 0, SEEK_END);
fend = ftell(mp3fp-&fp);
flen = fend -
if(flen fp, 0, SEEK_SET);
fread(mp3fp-&fbuf, 1, BUFSIZE, mp3fp-&fp);
mp3fp-&fbsize = BUFSIZE;
mp3fp-&fpos
= BUFSIZE;
mp3fp-&flen
set_dsp();
decode(mp3fp);
close(soundfd);
fclose(mp3fp-&fp);
* This is the input callback. The purpose of this callback is to (re)fill
* the stream buffer which is to be decoded. In this example, an entire file
* has been mapped into memory, so we just call mad_stream_buffer() with the
* address and length of the mapping. When this callback is called a second
* time, we are finished decoding.
enum mad_flow input(void *data,
struct mad_stream *stream)
mp3_file *mp3
unproc_data_
/*the unprocessed data's size*/
mp3fp = (mp3_file *)
if(mp3fp-&fpos flen)
unproc_data_size = stream-&bufend - stream-&next_
memcpy(mp3fp-&fbuf, mp3fp-&fbuf+mp3fp-&fbsize-unproc_data_size, unproc_data_size);
copy_size = BUFSIZE - unproc_data_
if(mp3fp-&fpos + copy_size & mp3fp-&flen)
copy_size = mp3fp-&flen - mp3fp-&
fread(mp3fp-&fbuf+unproc_data_size, 1, copy_size, mp3fp-&fp);
mp3fp-&fbsize = unproc_data_size + copy_
mp3fp-&fpos
+= copy_
/*Hand off the buffer to the mp3 input stream*/
mad_stream_buffer(stream, mp3fp-&fbuf, mp3fp-&fbsize);
ret_code = MAD_FLOW_CONTINUE;
ret_code = MAD_FLOW_STOP;
return ret_
* The following utility routine performs simple rounding, clipping, and
* scaling of MAD's high-resolution samples down to 16 bits. It does not
* perform any dithering or noise shaping, which would be recommended to
* obtain any exceptional audio quality. It is therefore not recommended to
* use this routine if high-quality output is desired.
static inline
signed int scale(mad_fixed_t sample)
/* round */
sample += (1L &= MAD_F_ONE)
sample = MAD_F_ONE - 1;
else if (sample & (MAD_F_FRACBITS + 1 - 16);
* This is the output callback function. It is called after each frame of
* MPEG audio data has been completely decoded. The purpose of this callback
* is to output (or play) the decoded PCM audio.
enum mad_flow output(void *data,
struct mad_header const *header,
struct mad_pcm *pcm)
unsigned int nchannels,
mad_fixed_t const *left_ch, *right_
/* pcm-&samplerate contains the sampling frequency */
rate= pcm-&
nchannels = pcm-&
= pcm-&samples[0];
= pcm-&samples[1];
/* update the sample rate of dsp*/
if(rate != prerate)
ioctl(soundfd, SNDCTL_DSP_SPEED, &rate);
while (nsamples--) {
/* output sample(s) in 16-bit signed little-endian PCM */
sample = scale(*left_ch++);
writedsp((sample && 0) & 0xff);
writedsp((sample && 8) & 0xff);
if (nchannels == 2) {
sample = scale(*right_ch++);
writedsp((sample && 0) & 0xff);
writedsp((sample && 8) & 0xff);
return MAD_FLOW_CONTINUE;
* This is the error callback function. It is called whenever a decoding
* error occurs. The error is indicated by stream-& the list of
* possible MAD_ERROR_* errors can be found in the mad.h (or stream.h)
* header file.
static enum mad_flow error(void *data,
struct mad_stream *stream,
struct mad_frame *frame)
mp3_file *mp3fp =
fprintf(stderr, &decoding error 0x%04x (%s) at byte offset %u\n&,
stream-&error, mad_stream_errorstr(stream),
stream-&this_frame - mp3fp-&fbuf);
/* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */
return MAD_FLOW_CONTINUE;
* This is the function called by main() above to perform all the decoding.
* It instantiates a decoder object and configures it with the input,
* output, and error callback functions above. A single call to
* mad_decoder_run() continues until a callback function returns
* MAD_FLOW_STOP (to stop decoding) or MAD_FLOW_BREAK (to stop decoding and
* signal an error).
static int decode(mp3_file *mp3fp)
struct mad_
/* configure input, output, and error functions */
mad_decoder_init(&decoder, mp3fp,
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);
本文已收录于以下专栏:
相关文章推荐
1.1同步方式和异步方式MadLib是以帧为单位解码mp3文件的,所谓同步方式是指解码函数在解码完一帧后才返回并带回出错信息,异步方式是指解码函数在调用后立即返回,通过消息传递解码状态信息。1.2 M...
近来要把WinCE.Net平台的的程序移植到Pocket PC上,出现了一点小麻烦。原有工程中有个DirectShow的封装类,用来播放MP3格式的音频,而Pocket PC 2003不支持Direc...
闲着也是闲着,就学习了下LibMad解码MP3(解码成PCM数据流),顺便把Windows上播放PCM,以及PCM文件转换成WAV文件学习了下。以前做过PCM转WAV,原理很简单,就是在PCM...
先说个人的一点见解:真实地去分析一个协议的数据帧,还是对照着“TCP/IP详解卷1:协议”上的四层模型更加合适(四层模型见这儿:点击打开链接),按照 OSI 7层模型的话有些东西对应起来会比较困惑。
1.madplay-0.15.2b.tar.gz
2.libmad-0.15.1b.tar.gz
3 libid3tag-0.15.1b.tar.gz
 方法是:./configu...
/*modify by hfl */
#define ALSA_PCM_NEW_HW_PARAMS_API
第四篇博客【SSH进阶之路】一步步重构MVC实现Struts框架——封装业务逻辑和跳转路径(四),我们解决了第一个问题:封装业务逻辑和跳转路径。第五篇博客【SSH进阶之路】一步步重构MVC实现Stru...
      【SSH进阶之路】Struts基本原理 + 实现简单登录(二)
      【SSH进阶之路】一步步重构MVC实现Struts框架——从一个简单MVC开始(三)
http://blog.csdn.net/guolin_blog/article/details/
不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回顾一下...
他的最新文章
讲师:宋宝华
讲师:何宇健
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 32位系统支持多大内存 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信