libmad解码mp3生成pcm文件
来源:互联网 发布:淘宝卖露华浓的 编辑:程序博客网 时间:2024/05/22 14:39
在之前的一篇文章中介绍了如何在linux下,使用libmad解码mp3并且播放,将源码编译了,可以正常的播放MP3文件,但是在项目里面需要将mp3解码成pcm文件,所以需要将之前的代码进行修改一下,修改是在原来的基础上的,这样可以测试一下。
/* * 本程序是从 minimad 改进而来,如要更详细的说明请参看 minimad.c * * MyMinimad.c , 2009/12/25 , 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 *start; unsigned long length;};static int decode (unsigned char const *, unsigned long);//static int init_alsa ();FILE *outFile;int main (int argc, char *argv[]){ struct stat stat; void *fdm; char const *file; int fd;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; return 0;}//static int init_alsa ()//{// snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;// char *pcm_name;// int rate = SAMPLE_RATE; /* Sample rate */// int exact_rate; /* 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 = 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;// }// return 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;}/*这一段是处理采样后的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, n; mad_fixed_t const *left_ch, *right_ch; unsigned char Output[6912], *OutputPtr; int fmt, wrote, speed, exact_rate, err, dir; nchannels = pcm->channels; n = nsamples = pcm->length; left_ch = pcm->samples[0]; right_ch = pcm->samples[1];// fmt = AFMT_S16_LE;// speed = pcm->samplerate * 2; /*播放速度是采样率的两倍 */ OutputPtr = Output;//将OutputPtr指向Output while (nsamples--) { signed int sample; sample = scale (*left_ch++); *(OutputPtr++) = sample >> 0; *(OutputPtr++) = sample >> 8; if (nchannels == 2) { sample = scale (*right_ch++); *(OutputPtr++) = sample >> 0; *(OutputPtr++) = sample >> 8; } } OutputPtr = Output;//由于之前的操作将OutputPtr的指针指向了最后,这时需要将其指针移动到最前面fwrite(OutputPtr, 1, n*2*nchannels, outFile);// snd_pcm_writei (pcm_handle, OutputPtr, n); OutputPtr = Output;//写完文件后,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 buffer buffer; struct mad_decoder decoder; int result; buffer.start = start; buffer.length = 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); return result;}
在终端运行gcc MyMinimad.c -o MyMinimad -lmad就可以生成解码mp3文件生成pcm的工具.
- libmad解码mp3生成pcm文件
- android 使用libmad 生成MP3左右声道的PCM文件
- 利用libmad解码mp3
- 利用libmad解码mp3
- libmad MP3解码
- libmad学习进阶2----利用libmad将mp3转码成pcm
- libmad学习进阶2----利用libmad将mp3转码成pcm
- 基于libmad编写mp3解码程序
- linux下使用libmad库实现mp3文件的解码、播放
- linux下使用libmad库实现mp3文件的解码、播放
- linux 基于alsa 使用libmad 解码库实现MP3文件的播放
- libmad madplay 播放mp3文件 gm8120 arm
- MP3解码库libmad到OpenCore的移植
- libmad解码MP3——/dev/dsp播放
- libmad解码MP3——/dev/dsp播放
- 关于libmad开源mp3音频解码库的使用
- 使用LibMad解码MP3,Windows上播放MP3,MP3转WAV实例代码
- 让终端支持播放mp3,移植mp3解码库libmad和madplay到嵌入式linux
- MSSQL2K - SQL Injector - Query String Parameter Attack
- 黑马程序员--java网络之tcp
- linux 有名管道FIFO
- Linux命令行访问网页
- 常见的网络协议收集
- libmad解码mp3生成pcm文件
- TQ210搭载Android4.0.3系统构建之ADC从驱动到HAL到JNI到应用程序(JNI篇)
- 黑马程序员--java 之 正则表达式
- wmsys.wm_concat(to_char(b.fieldname)) 行转列函数示例
- 网站访问量和数据量需要都很大,如何解决?
- 10 个你必须掌握的超酷 VI 命令技巧
- 结构体
- VS2012下基于Glut 绘制立方体示例程序:
- 如何合理设置Linux的swap分区