也说alsa音乐播放(mp3文件从零开始)
来源:互联网 发布:神州科捷工作知乎 编辑:程序博客网 时间:2024/06/06 06:52
首先也是最重要的是:我说大话了,本文也就是一个思路而已,如果你是音乐播放小白也想弄明白原理可以往下看,否则,return -1;
现有的音乐格式千差万别,于是就有了ffmpeg话说这个框架真是够牛逼,音频视频转码都不在话下,我是个死脑筋,遇到不懂的老是想弄明白,对于音乐播放感觉是一头雾水,经过几天的研究以后大致想明白了,对一个mp3文件要播放出来需要经过几个步骤:
1.转码,其实也就是提取文件中有用的音频信息2.经过第一步得到的wav波形文件
3.调用声卡来播放wav文件,对于linux 3.0以后的内核一般为alsa驱动,windows对wav也是天然支持的
关于转码可以见大婶写的转码系列教程http://lfp001.iteye.com/blog/739585
转码命令:ffmepg -i 1.mp3 -f wav 1.wav
编译: gcc -o alsa alsa.c -lasound
播放命令
./alsa 1.wav
//alsa.c 编写者未知,纯属引用#include<stdio.h>#include<stdlib.h>#include <string.h>#include <alsa/asoundlib.h>struct WAV_HEADER{ char rld[4]; //riff 标志符号 int rLen; char wld[4]; //格式类型(wave) char fld[4]; //"fmt" int fLen; //sizeof(wave format matex) short wFormatTag; //编码格式 short wChannels; //声道数 int nSamplesPersec ; //采样频率 int nAvgBitsPerSample;//WAVE文件采样大小 short wBlockAlign; //块对齐 short wBitsPerSample; //WAVE文件采样大小 char dld[4]; //”data“ int wSampleLength; //音频数据的大小} wav_header;int set_pcm_play(FILE *fp);int main(int argc,char *argv[]){ if(argc!=2) { printf("Usage:wav-player+wav file name\n"); exit(1); } int nread; FILE *fp; fp=fopen(argv[1],"rb"); if(fp==NULL) { perror("open file failed:\n"); exit(1); } nread=fread(&wav_header,1,sizeof(wav_header),fp); printf("nread=%d\n",nread); //printf("RIFF 标志%s\n",wav_header.rld); printf("文件大小rLen:%d\n",wav_header.rLen); //printf("wld=%s\n",wav_header.wld); //printf("fld=%s\n",wav_header.fld); // printf("fLen=%d\n",wav_header.fLen); //printf("wFormatTag=%d\n",wav_header.wFormatTag); printf("声道数:%d\n",wav_header.wChannels); printf("采样频率:%d\n",wav_header.nSamplesPersec); //printf("nAvgBitsPerSample=%d\n",wav_header.nAvgBitsPerSample); //printf("wBlockAlign=%d\n",wav_header.wBlockAlign); printf("采样的位数:%d\n",wav_header.wBitsPerSample); // printf("data=%s\n",wav_header.dld); printf("wSampleLength=%d\n",wav_header.wSampleLength); set_pcm_play(fp); return 0;}int set_pcm_play(FILE *fp){ int rc; int ret; int size; snd_pcm_t* handle; //PCI设备句柄 snd_pcm_hw_params_t* params;//硬件信息和PCM流配置 unsigned int val; int dir=0; snd_pcm_uframes_t frames; char *buffer; int channels=wav_header.wChannels; int frequency=wav_header.nSamplesPersec; int bit=wav_header.wBitsPerSample; int datablock=wav_header.wBlockAlign; unsigned char ch[100]; //用来存储wav文件的头信息 rc=snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if(rc<0) { perror("\nopen PCM device failed:"); exit(1); } snd_pcm_hw_params_alloca(¶ms); //分配params结构体 if(rc<0) { perror("\nsnd_pcm_hw_params_alloca:"); exit(1); } rc=snd_pcm_hw_params_any(handle, params);//初始化params if(rc<0) { perror("\nsnd_pcm_hw_params_any:"); exit(1); } rc=snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); //初始化访问权限 if(rc<0) { perror("\nsed_pcm_hw_set_access:"); exit(1); } //采样位数 switch(bit/8) { case 1:snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_U8); break ; case 2:snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); break ; case 3:snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S24_LE); break ; } rc=snd_pcm_hw_params_set_channels(handle, params, channels); //设置声道,1表示单声>道,2表示立体声 if(rc<0) { perror("\nsnd_pcm_hw_params_set_channels:"); exit(1); } val = frequency; rc=snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); //设置>频率 if(rc<0) { perror("\nsnd_pcm_hw_params_set_rate_near:"); exit(1); } rc = snd_pcm_hw_params(handle, params); if(rc<0) { perror("\nsnd_pcm_hw_params: "); exit(1); } rc=snd_pcm_hw_params_get_period_size(params, &frames, &dir); /*获取周期长度*/ if(rc<0) { perror("\nsnd_pcm_hw_params_get_period_size:"); exit(1); } size = frames * datablock; /*4 代表数据快长度*/ buffer =(char*)malloc(size); fseek(fp,58,SEEK_SET); //定位歌曲到数据区 while (1) { memset(buffer,0,sizeof(buffer)); ret = fread(buffer, 1, size, fp); if(ret == 0) { printf("歌曲写入结束\n"); break; } else if (ret != size) { } // 写音频数据到PCM设备 while(ret = snd_pcm_writei(handle, buffer, frames)<0) { usleep(2000); if (ret == -EPIPE) { /* EPIPE means underrun */ fprintf(stderr, "underrun occurred\n"); //完成硬件参数设置,使设备准备好 snd_pcm_prepare(handle); } else if (ret < 0) { fprintf(stderr, "error from writei: %s\n", snd_strerror(ret)); } } } snd_pcm_drain(handle); snd_pcm_close(handle); free(buffer); return 0;}
2 0
- 也说alsa音乐播放(mp3文件从零开始)
- MP3音乐播放器
- 播放音乐MP3
- 用Java播放mp3音乐
- ios平台播放。MP3音乐
- MFC播放MP3格式音乐
- Unity播放音乐(MP3)
- C语言播放MP3音乐
- arduino MP3 音乐播放器
- 嵌入式alsa+libmad实现mp3播放
- libmad+alsa 实现arm下mp3播放
- 播放pcm文件音乐不变调和正常播放MP3文件一样
- alsa学习--6.ffmpeg解码mp3后用alsa播放
- linux 基于alsa 使用libmad 解码库实现MP3文件的播放
- IOS 播放本地音乐(播放内存卡中的MP3) 及 文件的写入
- IOS 播放本地音乐(播放内存卡中的MP3) 及 文件的写入
- fedora 播放mp3文件
- C# 播放MP3文件
- HDU 1429
- Android - ImageButton单击切换按钮图片效果的实现
- POJ 1704-Georgia and Bob(阶梯博弈)
- C++STL模板容器(三)
- 测试CSDN的code
- 也说alsa音乐播放(mp3文件从零开始)
- C++STL模板容器(四)
- java构造器
- What qualities characrize a *great* PHD student
- HDU 1010 Tempter of the Bone
- va_start和va_end使用详解
- 探索Lua5.2内部实现:Garbage Collection(2)
- IOS键盘处理
- hadoop(八) - sqoop安装与使用