本文转载自:http://blog.csdn.net/sjin_1314/article/details/12872581

  1. /**alsa play test
  2. *ALSA用户空间编译,ALSA驱动的声卡在用户空间,不宜直接使用
  3. *文件接口中,而应使用alsa-lib
  4. *打开---->设置参数--->读写音频数据 ALSA全部使用alsa-lib中的API
  5. *交叉编译
  6. *export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
  7. *arm-linux-gcc -o alsa_play alsa_play_test.c -L. -lasound
  8. *需要交叉编译后的libasound.so库的支持
  9. *
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include "alsa/asoundlib.h"
  14. int main(int argc, char *argv[])
  15. {
  16. int i;
  17. int ret;
  18. int buf[128];
  19. unsigned int val;
  20. int dir=0;
  21. char *buffer;
  22. int size;
  23. snd_pcm_uframes_t frames;
  24. snd_pcm_uframes_t periodsize;
  25. snd_pcm_t *playback_handle;//PCM设备句柄pcm.h
  26. snd_pcm_hw_params_t *hw_params;//硬件信息和PCM流配置
  27. if (argc != 2) {
  28. printf("error: alsa_play_test [music name]\n");
  29. exit(1);
  30. }
  31. printf("play song %s by wolf\n", argv[1]);
  32. FILE *fp = fopen(argv[1], "rb");
  33. if(fp == NULL)
  34. return 0;
  35. fseek(fp, 100, SEEK_SET);
  36. //1. 打开PCM,最后一个参数为0意味着标准配置
  37. ret = snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
  38. if (ret < 0) {
  39. perror("snd_pcm_open");
  40. exit(1);
  41. }
  42. //2. 分配snd_pcm_hw_params_t结构体
  43. ret = snd_pcm_hw_params_malloc(&hw_params);
  44. if (ret < 0) {
  45. perror("snd_pcm_hw_params_malloc");
  46. exit(1);
  47. }
  48. //3. 初始化hw_params
  49. ret = snd_pcm_hw_params_any(playback_handle, hw_params);
  50. if (ret < 0) {
  51. perror("snd_pcm_hw_params_any");
  52. exit(1);
  53. }
  54. //4. 初始化访问权限
  55. ret = snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
  56. if (ret < 0) {
  57. perror("snd_pcm_hw_params_set_access");
  58. exit(1);
  59. }
  60. //5. 初始化采样格式SND_PCM_FORMAT_U8,8位
  61. ret = snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_U8);
  62. if (ret < 0) {
  63. perror("snd_pcm_hw_params_set_format");
  64. exit(1);
  65. }
  66. //6. 设置采样率,如果硬件不支持我们设置的采样率,将使用最接近的
  67. //val = 44100,有些录音采样频率固定为8KHz
  68. val = 8000;
  69. ret = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &val, &dir);
  70. if (ret < 0) {
  71. perror("snd_pcm_hw_params_set_rate_near");
  72. exit(1);
  73. }
  74. //7. 设置通道数量
  75. ret = snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2);
  76. if (ret < 0) {
  77. perror("snd_pcm_hw_params_set_channels");
  78. exit(1);
  79. }
  80. /* Set period size to 32 frames. */
  81. frames = 32;
  82. periodsize = frames * 2;
  83. ret = snd_pcm_hw_params_set_buffer_size_near(playback_handle, hw_params, &periodsize);
  84. if (ret < 0)
  85. {
  86. printf("Unable to set buffer size %li : %s\n", frames * 2, snd_strerror(ret));
  87. }
  88. periodsize /= 2;
  89. ret = snd_pcm_hw_params_set_period_size_near(playback_handle, hw_params, &periodsize, 0);
  90. if (ret < 0)
  91. {
  92. printf("Unable to set period size %li : %s\n", periodsize,  snd_strerror(ret));
  93. }
  94. //8. 设置hw_params
  95. ret = snd_pcm_hw_params(playback_handle, hw_params);
  96. if (ret < 0) {
  97. perror("snd_pcm_hw_params");
  98. exit(1);
  99. }
  100. /* Use a buffer large enough to hold one period */
  101. snd_pcm_hw_params_get_period_size(hw_params, &frames, &dir);
  102. size = frames * 2; /* 2 bytes/sample, 2 channels */
  103. buffer = (char *) malloc(size);
  104. fprintf(stderr,
  105. "size = %d\n",
  106. size);
  107. while (1)
  108. {
  109. ret = fread(buffer, 1, size, fp);
  110. if(ret == 0)
  111. {
  112. fprintf(stderr, "end of file on input\n");
  113. break;
  114. }
  115. else if (ret != size)
  116. {
  117. }
  118. //9. 写音频数据到PCM设备
  119. while(ret = snd_pcm_writei(playback_handle, buffer, frames)<0)
  120. {
  121. usleep(2000);
  122. if (ret == -EPIPE)
  123. {
  124. /* EPIPE means underrun */
  125. fprintf(stderr, "underrun occurred\n");
  126. //完成硬件参数设置,使设备准备好
  127. snd_pcm_prepare(playback_handle);
  128. }
  129. else if (ret < 0)
  130. {
  131. fprintf(stderr,
  132. "error from writei: %s\n",
  133. snd_strerror(ret));
  134. }
  135. }
  136. }
  137. //10. 关闭PCM设备句柄
  138. snd_pcm_close(playback_handle);
  139. return 0;
  140. }

alsa 用户空间编程【转】的更多相关文章

  1. Linux块设备驱动(二) _MTD驱动及其用户空间编程

    MTD(Memory Technology Device)即常说的Flash等使用存储芯片的存储设备,MTD子系统对应的是块设备驱动框架中的设备驱动层,可以说,MTD就是针对Flash设备设计的标准化 ...

  2. SPI编程1:用户空间的读写操作

    spi_device 虽然用户空间不需要直接用到spi_device结构体,但是这个结构体和用户空间的程序有密切的关系,理解它的成员有助于理解SPI设备节点的IOCTL命令,所以首先来介绍它.在内核中 ...

  3. 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口

    Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...

  4. Linux usb子系统(三):通过usbfs操作设备的用户空间驱动

    内核中提供了USB设备文件系统(usbdevfs,Linux 2.6改为usbfs,即USB文件系统),它和/proc类似,都是动态产生的.通过在/etc/fstab文件中添加如下一行:none /p ...

  5. 用户空间网络提升 NFV 的性能

    本文是一篇翻译,翻译自https://software.intel.com/en-us/blogs/2015/06/12/user-space-networking-fuels-nfv-perform ...

  6. linux内核空间和用户空间详解

    linux驱动程序一般工作在内核空间,但也可以工作在用户空间.下面我们将详细解析,什么是内核空间,什么是用户空间,以及如何判断他们.Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Li ...

  7. 用户空间和内核空间通讯之【Netlink 中】

    原文地址:用户空间和内核空间通讯之[Netlink 中] 作者:wjlkoorey258 今天我们来动手演练一下Netlink的用法,看看它到底是如何实现用户-内核空间的数据通信的.我们依旧是在2.6 ...

  8. 用户空间和内核空间通讯之【Netlink 上】

    原文地址:用户空间和内核空间通讯之[Netlink 上] 作者:wjlkoorey258 引言 Alan Cox在内核1.3版本的开发阶段最先引入了Netlink,刚开始时Netlink是以字符驱动接 ...

  9. Linux系统调用具体解释(怎样从用户空间进入内核空间)

    系统调用概述 计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同一时候执行的多个进程都须要訪问这些资源,为了更好的管理这些资源进程是不同意直接操作的,全部对这些资源的訪问都必须有操作系统控制. ...

随机推荐

  1. 编写高质量的js之恰当选用if和switch

    switch结构中存在很多限制,存在这些限制的主要目的是提高多重分支结构的执行效率.因此,如果能够使用switch结构,就不要选择if结构. 无论是使用if结构,还是使用switch结构,应该确保下面 ...

  2. html5——多媒体(一)

    <audio> 1.autoplay 自动播放 2.controls 是否显不默认播放控件 3.loop 循环播放 4.preload 预加载 同时设置autoplay时些属性失效 5.由 ...

  3. 【译】x86程序员手册15-5.2页转换

    5.2 Page Translation 页转换 In the second phase of address transformation, the 80386 transforms a linea ...

  4. adjtimex和时钟的几个概念tick,freq,ppm,jiffies

    adjtimex使用 今天遇到一个ntp的同步问题.服务器上配置好了ntpd,在启动前也手动进行过同步,但是过段时间ntpq查询发现服务器即便能选出同步服务器,但是系统的时间偏差越来越大. 服务器上实 ...

  5. LDAP个人理解

    在新的公司办公,所有的后台系统或文档系统都公用一个LDAP账号. 接触到这个新名词,就查了一下,谈谈个人理解: LDAP是个协议, 简单地说,可以把LDAP服务理解为一套存放你账户密码的数据库系统.市 ...

  6. [luogu3155 CQOI2009] 叶子的染色(树形dp)

    传送门 Solution 十分简单的树形dpQwQ,转移关系:父亲染了儿子不用染 只需要确定根就是简单树形dp,而其实根可以随便取一个非叶子节点 可以分情况讨论发现答案并不会改变 Code //By ...

  7. Linux自动化之基于http的pxe安装服务

    PXE:     Preboot Excution Environment 预启动执行环境     Intel公司研发     基于Client/Server的网络模式,支持远程主机通过网络从远端服务 ...

  8. vue项目中的常见问题(vue-cli版本3.0.0)

    一.样式问题 1.vue中使用less 安装less依赖 npm install less less-loader --save-dev 在使用时 在style标签中加入 lang="les ...

  9. CTF中编码与加解密总结

    CTF中那些脑洞大开的编码和加密 转自:https://www.cnblogs.com/mq0036/p/6544055.html 0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到 ...

  10. [NOIP2016day1T1] 玩具迷題(toy)

    题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉 ...