参考:https://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <getopt.h>
  5. #include <alsa/asoundlib.h>
  6. #include <unistd.h>
  7.  
  8. typedef struct {
  9. char *file_name;
  10. char *device;
  11. int ch;
  12. int bit;
  13. int rate;
  14. snd_pcm_format_t format;
  15. unsigned int buffer_time;
  16. unsigned int period_time;
  17. snd_pcm_uframes_t buffer;
  18. snd_pcm_uframes_t period;
  19. }CONFIG_T;
  20.  
  21. typedef struct {
  22. char id[];
  23. int size;
  24. }RIFF_HEADER_T;
  25.  
  26. typedef struct {
  27. char format[];
  28. char sub_id_1[];
  29. int sub_size_1;
  30. short fmt;
  31. short ch;
  32. int sample_rate;
  33. int byte_rate;
  34. short block_align;
  35. short bits_per_sample;
  36. }WAVE_HEADER_T;
  37.  
  38. typedef struct {
  39. char sub_id_2[];
  40. int sub_size_2;
  41. }DATA_HEADER_T;
  42.  
  43. RIFF_HEADER_T riff_header;
  44. WAVE_HEADER_T wave_header;
  45. DATA_HEADER_T data_header;
  46. CONFIG_T config;
  47.  
  48. static void help(void)
  49. {
  50. printf(
  51. "Usage: pcm [OPTION]... [FILE]...\n"
  52. "-h,--help help\n"
  53. "-D,--device playback device\n"
  54. "-i,--input_file only support wav file\n"
  55. "\n");
  56. }
  57.  
  58. static void parse_cmd(int argc, char **argv)
  59. {
  60. struct option long_option[] =
  61. {
  62. {"help", , NULL, 'h'},
  63. {"device", , NULL, 'D'},
  64. {"input_file", , NULL, 'i'},
  65. {NULL, , NULL, },
  66. };
  67. while () {
  68. int c;
  69. if ((c = getopt_long(argc, argv, "hD:i:", long_option, NULL)) < )
  70. break;
  71. switch (c) {
  72. case 'h':
  73. help();
  74. break;
  75. case 'D':
  76. config.device = strdup(optarg);
  77. break;
  78. case 'i':
  79. config.file_name = strdup(optarg);
  80. break;
  81. }
  82. }
  83. }
  84.  
  85. static snd_pcm_format_t get_format(int bits_per_sample)
  86. {
  87. snd_pcm_format_t format = SND_PCM_FORMAT_S8;
  88. switch(bits_per_sample) {
  89. case :
  90. format = SND_PCM_FORMAT_S8;
  91. break;
  92. case :
  93. format = SND_PCM_FORMAT_S16_LE;
  94. break;
  95. case :
  96. format = SND_PCM_FORMAT_S24_LE;
  97. break;
  98. case :
  99. format = SND_PCM_FORMAT_S32_LE;
  100. break;
  101. }
  102. return format;
  103. }
  104.  
  105. static int config_init(CONFIG_T *pConfig)
  106. {
  107. FILE *fp = NULL;
  108. if (NULL == pConfig) {
  109. return -;
  110. }
  111. fp = fopen(pConfig->file_name, "rb");
  112. if (NULL == fp) {
  113. return -;
  114. }
  115.  
  116. fread((void *)&riff_header, sizeof(RIFF_HEADER_T), , fp);
  117. fread((void *)&wave_header, sizeof(WAVE_HEADER_T), , fp);
  118. if (wave_header.sub_size_1 > sizeof (WAVE_HEADER_T) -)
  119. fseek(fp, wave_header.sub_size_1 - (sizeof (WAVE_HEADER_T) - ), SEEK_CUR);
  120. fread((void *)&data_header, sizeof(DATA_HEADER_T), , fp);
  121. pConfig->ch = wave_header.ch;
  122. pConfig->rate= wave_header.sample_rate;
  123. pConfig->bit= wave_header.bits_per_sample;
  124. pConfig->format = get_format(wave_header.bits_per_sample);
  125. fclose(fp);
  126. return ;
  127. }
  128.  
  129. static int set_hwparams(snd_pcm_t *handle)
  130. {
  131. snd_pcm_hw_params_t *params;
  132. unsigned int rrate;
  133. snd_pcm_uframes_t size;
  134. int err, dir;
  135. snd_pcm_hw_params_alloca(&params);
  136. /* choose all parameters */
  137. err = snd_pcm_hw_params_any(handle, params);
  138. if (err < ) {
  139. printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
  140. return err;
  141. }
  142. /* set the interleaved read/write format */
  143. err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
  144. if (err < ) {
  145. printf("Access type not available for playback: %s\n", snd_strerror(err));
  146. return err;
  147. }
  148. /* set the sample format */
  149. err = snd_pcm_hw_params_set_format(handle, params, config.format);
  150. if (err < ) {
  151. printf("Sample format not available for playback: %s\n", snd_strerror(err));
  152. return err;
  153. }
  154. /* set the count of channels */
  155. err = snd_pcm_hw_params_set_channels(handle, params, config.ch);
  156. if (err < ) {
  157. printf("Channels count (%u) not available for playbacks: %s\n", config.ch, snd_strerror(err));
  158. return err;
  159. }
  160. /* set the stream rate */
  161. rrate = config.rate;
  162. err = snd_pcm_hw_params_set_rate_near(handle, params, &rrate, );
  163. if (err < ) {
  164. printf("Rate %uHz not available for playback: %s\n", config.rate, snd_strerror(err));
  165. return err;
  166. }
  167. if (rrate != config.rate) {
  168. printf("Rate doesn't match (requested %uHz, get %iHz)\n", config.rate, err);
  169. return -EINVAL;
  170. }
  171. /* set the buffer time */
  172. err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &config.buffer_time, &dir);
  173. if (err < ) {
  174. printf("Unable to set buffer time %u for playback: %s\n", config.buffer_time, snd_strerror(err));
  175. return err;
  176. }
  177. err = snd_pcm_hw_params_get_buffer_size(params, &size);
  178. if (err < ) {
  179. printf("Unable to get buffer size for playback: %s\n", snd_strerror(err));
  180. return err;
  181. }
  182. config.buffer = size;
  183. /* set the period time */
  184. err = snd_pcm_hw_params_set_period_time_near(handle, params, &config.period_time, &dir);
  185. if (err < ) {
  186. printf("Unable to set period time %u for playback: %s\n", config.period_time, snd_strerror(err));
  187. return err;
  188. }
  189. err = snd_pcm_hw_params_get_period_size(params, &size, &dir);
  190. if (err < ) {
  191. printf("Unable to get period size for playback: %s\n", snd_strerror(err));
  192. return err;
  193. }
  194. config.period = size;
  195. /* write the parameters to device */
  196. err = snd_pcm_hw_params(handle, params);
  197. if (err < ) {
  198. printf("Unable to set hw params for playback: %s\n", snd_strerror(err));
  199. return err;
  200. }
  201. return ;
  202. }
  203. static int set_swparams(snd_pcm_t *handle)
  204. {
  205. int err;
    snd_pcm_sw_params_t *swparams;
  206. snd_pcm_sw_params_alloca(&swparams);
  207. /* get the current swparams */
  208. err = snd_pcm_sw_params_current(handle, swparams);
  209. if (err < ) {
  210. printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
  211. return err;
  212. }
  213. /* start the transfer when the buffer is almost full: */
  214. /* (buffer_size / avail_min) * avail_min */
  215. err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (config.buffer / config.period) * config.period);
  216. if (err < ) {
  217. printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
  218. return err;
  219. }
  220.  
  221. /* write the parameters to the playback device */
  222. err = snd_pcm_sw_params(handle, swparams);
  223. if (err < ) {
  224. printf("Unable to set sw params for playback: %s\n", snd_strerror(err));
  225. return err;
  226. }
  227. return ;
  228. }
  229.  
  230. /*
  231. * Underrun and suspend recovery
  232. */
  233.  
  234. static int xrun_recovery(snd_pcm_t *handle, int err)
  235. {
  236. printf("stream recovery\n");
  237. if (err == -EPIPE) { /* under-run */
  238. err = snd_pcm_prepare(handle);
  239. if (err < )
  240. printf("Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err));
  241. return ;
  242. } else if (err == -ESTRPIPE) {
  243. while ((err = snd_pcm_resume(handle)) == -EAGAIN)
  244. sleep(); /* wait until the suspend flag is released */
  245. if (err < ) {
  246. err = snd_pcm_prepare(handle);
  247. if (err < )
  248. printf("Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err));
  249. }
  250. return ;
  251. }
  252. return err;
  253. }
  254.  
  255. static int write_loop(snd_pcm_t *handle)
  256. {
  257. int err;
  258. size_t remain, read_size;
  259. FILE *fp = NULL;
  260. char *read_buffer = NULL, *offset = NULL;
  261. int bytes_per_frame = config.ch * (config.bit >> );
  262. read_size = config.period * bytes_per_frame;
  263. fp = fopen(config.file_name, "rb");
  264. if (NULL == fp) {
  265. return -;
  266. }
  267. read_buffer = (char * )malloc(read_size);
  268. fseek(fp, , SEEK_CUR);
  269.  
  270. while () {
  271. memset(read_buffer ,, read_size);
  272. err = fread(read_buffer ,, read_size, fp);
  273. if (err <= )
  274. break;
  275. offset = read_buffer;
  276. remain = err / bytes_per_frame;
  277. while (remain> ) {
  278. err = snd_pcm_writei(handle, offset, remain);
  279. if (err == -EAGAIN)
  280. continue;
  281. if (err < ) {
  282. if (xrun_recovery(handle, err) < ) {
  283. printf("Write error: %s\n", snd_strerror(err));
  284. exit(EXIT_FAILURE);
  285. }
  286. continue;
  287. }
  288. offset += err * bytes_per_frame;
  289. remain -= err;
  290. }
  291. }
  292. free(read_buffer);
  293. fclose(fp);
  294. return ;
  295. }
  296.  
  297. int main(int argc, char **argv)
  298. {
  299. int err = ;
  300. snd_pcm_t *handle;
  301. memset (&config, , sizeof(CONFIG_T));
  302. config.buffer_time = ;//us
  303. config.period_time = ;
  304. parse_cmd(argc, argv);
  305. config_init(&config);
  306. if ((err = snd_pcm_open(&handle, config.device, SND_PCM_STREAM_PLAYBACK, )) < ) {
  307. printf("Playback open error: %s\n", snd_strerror(err));
  308. return ;
  309. }
  310.  
  311. if ((err = set_hwparams(handle)) < ) {
  312. printf("Setting of hwparams failed: %s\n", snd_strerror(err));
  313. exit(EXIT_FAILURE);
  314. }
  315. if ((err = set_swparams(handle)) < ) {
  316. printf("Setting of swparams failed: %s\n", snd_strerror(err));
  317. exit(EXIT_FAILURE);
  318. }
  319. write_loop(handle);
  320. snd_pcm_close(handle);
    return 0;
  321. }

Makefile:

  1. ALSA_INC_PATH=/home/fellow/alsa-lib-1.2./output/usr/include
  2. ALSA_LIB_PATH=/usr/lib/i386-linux-gnu
  3. ALSA_PLUG_PATH=/usr/lib/i386-linux-gnu/alsa-lib
  4.  
  5. export LD_LIBRARY_PATH=${ALSA_LIB_PATH}:${ALSA_PLUG_PATH}:$LD_LIBRARY_PATH
  6. export CC=gcc
  7. export CFLAGS=-I${ALSA_INC_PATH}
  8. export LDFLAGS=-L{ALSA_LIB_PATH} -lasound
  9. SOURCE=alsa_test.c
  10. TARGET=alsa_test
  11. all:
  12. ${CC} ${SOURCE} ${CFLAGS} ${LDFLAGS} -o ${TARGET}

./alsa_test -D default -i xx.wav

ALSA Lib-简单的播放例子的更多相关文章

  1. lib和dll的例子

    .dll和.lib的区别 lib是静态库,dll一般是动态链接库(也有可能是别的)比如要编译个exe,lib在编译的时候就会被编译到exe里,作为程序的一部分而dll是不被编译进去,是运行的时候才调入 ...

  2. 一个简单的cmake例子

    一个简单的cmake例子CMakeLists.txt,生成动态库文件,可以指定发布目录. 尚不支持: 1.交叉编译环境配置 2.添加依赖库   #在当前目录新建一个build目录,然后cd build ...

  3. ALSA lib基本概念

    1.channel 通道,即我们熟知的声道数.左/右声道,5.1channel等等 2.sample A sample is a single value that describes the amp ...

  4. Android开发6:Service的使用(简单音乐播放器的实现)

    前言 啦啦啦~各位好久不见啦~博主最近比较忙,而且最近一次实验也是刚刚结束~ 好了不废话了,直接进入我们这次的内容~ 在这篇博文里我们将学习Service(服务)的相关知识,学会使用 Service ...

  5. Android 实现简单音乐播放器(二)

    在Android 实现简单音乐播放器(一)中,我介绍了MusicPlayer的页面设计. 现在,我简单总结一些功能实现过程中的要点和有趣的细节,结合MainActivity.java代码进行说明(写出 ...

  6. Android 实现简单音乐播放器(一)

    今天掐指一算,学习Android长达近两个月了,今天开始,对过去一段时间的学习收获以及遇到的疑难杂症做一些总结. 简单音乐播放器是我自己完成的第一个功能较为完整的APP,可以说是我的Android学习 ...

  7. html5 简单音乐播放器

    html5 简单音乐播放器 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> < ...

  8. 一个简单的CORBA例子

    因为对CORBA分析的需要,这里写一个简单的CORBA例子.从JDK1.2开始,JDK中集成了ORB的实现,本例子使用了JDK1.7,对于JDK1.2+应该都没有问题.这个例子实现一个简单的加减乘除的 ...

  9. 菜鸟学习Hibernate——简单的一个例子

    一.Hibernate开发. 上篇博客已经为大家介绍了持久层框架的发展流程,持久层框架的种类. 为了能够使用Hibernate快速上手,我们先讲解一个简单的Hibernate应用实例hibernate ...

随机推荐

  1. javascript json语句 与 js语句的互转

    //var data = "weihexin" //var data = ["weihexin", 1] var data = {name:"weih ...

  2. Centos7.5中Nginx报错:nginx: [error] invalid PID number "" in "/run/nginx.pid" 解决方法

    服务器重启之后,执行 nginx -t 是OK的,然而在执行 nginx -s reload 的时候报错 nginx: [error] invalid PID number "" ...

  3. vue路由--动态路由

    前面介绍的路由都是路径和组件一对一映射的 有时候需要多个路径映射到一个组件,这个组件根据参数的不同动态改变,这时候需要用到动态路由 动态路由这样定义路由路径: path: '/foo/:id'--可以 ...

  4. C# ,数据导出到带有级联下拉框的模板(一,模板的级联功能)

    一.首先解决如何做模板中增加级联功能 1,首先打开一个新的Excel文件,新增sheet,把分类保存在里面,如下图所示 2.回到sheet1,选中要增加下拉框的行(注意:请排除首行,首行是标题) 3. ...

  5. 【转】Redis内部数据结构详解——ziplist

    本文是<Redis内部数据结构详解>系列的第四篇.在本文中,我们首先介绍一个新的Redis内部数据结构--ziplist,然后在文章后半部分我们会讨论一下在robj, dict和zipli ...

  6. Linux运维---02.制作trove-redis镜像

    redis-3.2 镜像制作及验证 镜像制作 1.安装redis yum install redis yum install epl-release yum install python-pip gi ...

  7. Java的开发—面向对象的7大原则之开闭原则(一)

    开闭原则(Open Close Principle) 一.定义: 软件中的(类.模块.函数等等)应该对于扩展是开放的,对于修改时关闭的.意味着一个实体允许在不改变它的源代码的前提变更它的行为 这里的软 ...

  8. python--虚拟环境的使用

    下载virtualenv # pip3 install virtualenv 创建虚拟环境(自定义虚拟环境名称为Aechery_env) # virtualenv -p python3 Archery ...

  9. linux中其他搜索命令(locate/which/whereis/grep)

    目录 locate which whereis grep locate 解释 命令名称:locate 命令所在路径:/usr/bin/locate 执行权限:所有用户 功能描述:在文件资料库中查找文件 ...

  10. 全国省市,4个直辖市geoCoord数据,用于echart gl 3d地图

    var geoCoordMap = { '北京': [116.4551, 40.2539], '东城区':[116.418757,39.917544], '西城区':[116.366794,39.91 ...