Alsa-lib实现播放wav音频

1.alsa-lib移植

例程中使用的alsa-lib库是1.2.6版本的,目前最新的release版本已经到1.2.7版本了,可以根据自身需求下载。

具体下载链接可以访问下面alsa官网的下载链接

https://www.alsa-project.org/files/pub/lib/

下载完alsa-lib库后,我们解压后进入文件夹然后执行下列命令,进行交叉编译

mkdir builds
./configure --prefix=$PWD/builds --host=arm cc=arm-linux-gnueabihf-gcc
make
make install

所有的lib库和头文件都会在builds文件夹下,执行file + lib库,查看交叉编译是否完成,下列是32bit 小端模式,表示交叉编译完成

/project/alsa-lib-1.2.6$ file build/lib/libasound.so.2.0.0
build/lib/libasound.so.2.0.0: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=568ab75e8ab65df19ba5f34b536694ee4449ce6f, not stripped

2.播放wav音频

1.实现流程

alsa-lib具体的播放音频步骤如下,可以参照官网的例程

1.相关变量定义

2.申请hwparams变量内存 snd_pcm_hw_params_alloca(&pcm->hwparams)

3.打开pcm设备snd_pcm_open

4.初始化hwparams的结构体空间

5.设置数据的属性

​ 1.设置数据的读写模式(一般音频双通道分交错访问模式)

​ 2.设置数据的采样格式(每bit的样本长度)

​ 3.设置数据的通道数

​ 4.设置数据的采样速率

​ 5.设置数据的采样周期

​ 每帧的大小 = 采样格式 * 通道数 / 8bit

​ 特定的周期内的帧数 = 周期大小 * 周期数 / 每帧的大小

​ 比如 某个音频的 采样格式是SND_PCM_FORMAT_S16_LE , 通道数是 2 ,所以一帧的音频大小是 16 x 2 /8 = 4个字节,

周期数为20,周期大小为8192,这个周期内帧数一共有 20 x 8192 >> 2 = 40960 帧

6.申请存放buff的空间 (按帧数计算)snd_pcm_hw_params_set_buffer_size

7.读取音频数据

8.调用snd_pcm_writei 进行播放

2.具体实现

具体的代码在,这个例程只实现了播放wav文件,后续继续更新其他功能

git@github.com:lilixinxin/Alsa_example.git

alsa-lib的封装的结构体

typedef struct pcm_params {//pcm name like plughw:0,0char pcm_card_name[64];//pcm device handlesnd_pcm_t *pcm_handle;//pcm stream directionsnd_pcm_stream_t stream_direction;//specify configution for pcmsnd_pcm_hw_params_t *hwparams;//channel numint channel_num;//周期数int periods;//sample format bit per samplesnd_pcm_format_t sample_format;//PCM access type 交错模式或者交错snd_pcm_access_t access_type;//采样率int sample_rate;//每个周期的大小int period_szie;//frames 帧数int frames;
}Pcm_params;

初始化alsa 相关参数

//初始化alsa device
int Alsa_Dev_init(Pcm_params *pcm)
{int ret;//allocate snd_pcm_hw_params_tsnd_pcm_hw_params_alloca(&pcm->hwparams);//open pcm deviceif(snd_pcm_open(&pcm->pcm_handle, pcm->pcm_card_name, pcm->stream_direction, 0) < 0){fprintf(stderr, "Error opening PCM device %s\n", pcm->pcm_card_name);return -1;}/* Init hwparams with full configuration space */if (snd_pcm_hw_params_any(pcm->pcm_handle, pcm->hwparams) < 0) {fprintf(stderr, "Can not configure this PCM device.\n");return -1;}//设置数据访问模式if (snd_pcm_hw_params_set_access(pcm->pcm_handle, pcm->hwparams, pcm->access_type) < 0) {fprintf(stderr, "Can not set hw params access\n");return -1;}//set sample format bit per sampleif(snd_pcm_hw_params_set_format(pcm->pcm_handle, pcm->hwparams, pcm->sample_format) < 0){fprintf(stderr, "snd_pcm_hw_params_set_format fail\n");return -1;}//set channel numif(snd_pcm_hw_params_set_channels(pcm->pcm_handle, pcm->hwparams, pcm->channel_num) < 0){fprintf(stderr, "snd_pcm_hw_params_set_channels fail\n");return -1;}//set periodif(snd_pcm_hw_params_set_periods(pcm->pcm_handle, pcm->hwparams, pcm->periods, 0) < 0){fprintf(stderr, "snd_pcm_hw_params_set_periods fail\n");return -1;}//set sample rateif(snd_pcm_hw_params_set_rate_near(pcm->pcm_handle, pcm->hwparams, &pcm->sample_rate, 0) < 0){fprintf(stderr, "snd_pcm_hw_params_set_rate_near fail\n");return -1;}//每帧大小  每bit样本长度 * channel_num / 8bit//buffer size 按帧计算器 周期数 * 每个周期时间/* Set buffer size (in frames). The resulting latency is given by *//* latency = periodsize * periods / (rate * bytes_per_frame)     *///pcm->frames = (pcm->period_szie * pcm->periods) >> 2;if (snd_pcm_hw_params_set_buffer_size(pcm->pcm_handle, pcm->hwparams, pcm->frames) < 0) {fprintf(stderr, "Error setting buffersize.\n");return(-1);}/* Apply HW parameter settings to *//* PCM device and prepare device  */if (snd_pcm_hw_params(pcm->pcm_handle, pcm->hwparams) < 0) {fprintf(stderr, "Error setting HW params.\n");return(-1);}return 0;}
//播放
int Alsa_Playback(Pcm_params *pcm, char **buf)
{int pcmreturn;while ((pcmreturn = snd_pcm_writei(pcm->pcm_handle, buf, pcm->frames)) < 0) {snd_pcm_prepare(pcm->pcm_handle);fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>\n");}return 0;
}

实现播放

  //申请buff空间int buffsize = pcm.period_szie * pcm.periods;buff = (char *)malloc(buffsize);if(buff == NULL){fprintf(stderr, "malloc fail\n");return -1;}while(1){ret = fread(buff, 1, buffsize, fp);printf("read buff len, :%d\n", ret);if(ret == 0){printf("end of music file input! \n");exit(1);}if(ret < 0){printf("read pcm from file! \n");exit(1);}while ((ret = snd_pcm_writei(pcm.pcm_handle, buff, pcm.frames)) < 0) {snd_pcm_prepare(pcm.pcm_handle);fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>\n");}//Alsa_Playback(&pcm, &buff);}

Alsa-lib实现播放wav音频相关推荐

  1. 实现在线播放Wav音频文件,支持IE和Google

    最近在弄一个在线播放Wav音频文件的功能,发现audio只支持在google浏览器下才能访问,ie是不支持的,但是ie支持embed标签的播放. getWebIE:function(){var use ...

  2. Java 采集声音_通过java采集PC麦克风音频及播放wav音频文件

    AudioFormat对象 sampleRate 采样率 每秒音频采样数量 sampleSizeInBits 采样位数 每个采样的位数 channels 声道 1: Mono 单声道,2:Stereo ...

  3. Linux下使用C++播放wav音频文件

    Linux下使用C++播放wav音频文件 安装openal第三方库 上代码 安装openal第三方库 unbuntu下安装命令:sudo apt-get install libopenal-dev 安 ...

  4. Linux alsa-lib c语言 播放wav音频

    编程步骤: 1.指定使用最新的ALSA API #define ALSA_PCM_NEW_HW_PARAMS_API 2.包含头文件 #include <alsa/asoundlib.h> ...

  5. QT播放Wav音频并显示波形

    1.前言 因为项目需要,做了个小工具来做前期准备. 这个需求实现两步:播放和显示波形. 播放方面,一开始选择FMod,小工具快做好的时候偶然发现FMod需要商业授权,所以只能放弃.试了试ffmpeg+ ...

  6. Android使用AudioTrack播放WAV音频文件

    目录 1.wav文件格式 2.wav文件解析 3.wav文件播放 QA: 开始播放wav的时候使用了系统的播放器mediaplayer进行播放,但是无奈mediaplayer支持的实在不好. 好些年前 ...

  7. windows播放wav音频文件

    摘要   遇到过很三次win10系统下调用sndPlaySound导致虚拟内存(分页缓冲池)泄露的情况,于是乎便尝试换个方式播放wav文件,使用zplay库进行播放,还是存在泄露.后来参照网上的教程调 ...

  8. Python 调用pyaudio库录制以及播放wav音频文件

    1.Pyaudio简介 PyAudio 是语音处理的 Python 库,提供了比较丰富的功能. 2.功能 python的Pyaud模块可以调用电脑的麦克风或音响进行录音,音频播放,生成wav文件等. ...

  9. AudioTrack 播放wav音频文件

    Refrence https://blog.csdn.net/qq_15255121/article/details/115168456 https://blog.csdn.net/qq_152551 ...

最新文章

  1. Python各种包下载地址
  2. Spring Cloud Alibaba 统一门户:基于网关的统一用户认证方案
  3. python语法学习
  4. 8086 DS 和 ES 寄存器
  5. 【LaTex】LaTeX Warning: Citation xxx on page xxx undefined on input line xxx
  6. FunPlus特效专家张韶勇:如何利用跨平台工具快速制作像素动画?
  7. 数据结构与算法之花费铜板最小和利润最大题目
  8. WSDL4J解析WSDL文件方法
  9. 2021年暑期旅游数据报告
  10. 移动网络安全_新突破!青海移动在2020年中国移动网络安全运维技能竞赛大赛中荣获三等奖!...
  11. 在datasnap 中使用unidac 访问数据(客户端)
  12. Vue:使用highCharts
  13. 3、简单了解Angular应用的启动过程
  14. 世界之窗浏览器 v 3.6.1.0 [官方最新版]
  15. 163发送邮件服务器拒收,向网易163邮箱发信常见退信说明
  16. 脑洞大开!把 14 亿中国人拉到一个微信群 ?
  17. android textview 设置字体,Android 设置TextView自动调整字体大小
  18. 当VR踏入足球赛事会是如何?用数学运算又是如何?
  19. 在线的色值转换RGB网址
  20. java学习笔记(22)java输入标签,单选框,复选框,添加文件,文本域,下拉框

热门文章

  1. python春节集五福_2020 春节集五福最详细收集攻略
  2. 法律如何看待区块链资产
  3. 学习笔记(06):自然语言处理Word2Vec视频学习教程-使用gensim构建word2vec词向量
  4. 毕业论文管理系统(图)
  5. 7ML52211BA27超声波液位计7ML52212BA17质保售后
  6. 过程改进的关注点之项目管理过程
  7. 如何计算近似纳什均衡_《纳什均衡与博弈论》读书笔记
  8. 分享一个高效的桌面办公助手
  9. 北航计算机考研报录比2019,北京航空航天大学2016-2020年研究生招生数据汇总!含总报录比!...
  10. springboot踩坑日记——Field xxx.xxx.xxx required a bean of type 'xxx.xxx.xxx' that could not be found