alsa 用户空间编程【转】
本文转载自:http://blog.csdn.net/sjin_1314/article/details/12872581
- /**alsa play test
- *ALSA用户空间编译,ALSA驱动的声卡在用户空间,不宜直接使用
- *文件接口中,而应使用alsa-lib
- *打开---->设置参数--->读写音频数据 ALSA全部使用alsa-lib中的API
- *交叉编译
- *export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
- *arm-linux-gcc -o alsa_play alsa_play_test.c -L. -lasound
- *需要交叉编译后的libasound.so库的支持
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include "alsa/asoundlib.h"
- int main(int argc, char *argv[])
- {
- int i;
- int ret;
- int buf[128];
- unsigned int val;
- int dir=0;
- char *buffer;
- int size;
- snd_pcm_uframes_t frames;
- snd_pcm_uframes_t periodsize;
- snd_pcm_t *playback_handle;//PCM设备句柄pcm.h
- snd_pcm_hw_params_t *hw_params;//硬件信息和PCM流配置
- if (argc != 2) {
- printf("error: alsa_play_test [music name]\n");
- exit(1);
- }
- printf("play song %s by wolf\n", argv[1]);
- FILE *fp = fopen(argv[1], "rb");
- if(fp == NULL)
- return 0;
- fseek(fp, 100, SEEK_SET);
- //1. 打开PCM,最后一个参数为0意味着标准配置
- ret = snd_pcm_open(&playback_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
- if (ret < 0) {
- perror("snd_pcm_open");
- exit(1);
- }
- //2. 分配snd_pcm_hw_params_t结构体
- ret = snd_pcm_hw_params_malloc(&hw_params);
- if (ret < 0) {
- perror("snd_pcm_hw_params_malloc");
- exit(1);
- }
- //3. 初始化hw_params
- ret = snd_pcm_hw_params_any(playback_handle, hw_params);
- if (ret < 0) {
- perror("snd_pcm_hw_params_any");
- exit(1);
- }
- //4. 初始化访问权限
- ret = snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
- if (ret < 0) {
- perror("snd_pcm_hw_params_set_access");
- exit(1);
- }
- //5. 初始化采样格式SND_PCM_FORMAT_U8,8位
- ret = snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_U8);
- if (ret < 0) {
- perror("snd_pcm_hw_params_set_format");
- exit(1);
- }
- //6. 设置采样率,如果硬件不支持我们设置的采样率,将使用最接近的
- //val = 44100,有些录音采样频率固定为8KHz
- val = 8000;
- ret = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, &val, &dir);
- if (ret < 0) {
- perror("snd_pcm_hw_params_set_rate_near");
- exit(1);
- }
- //7. 设置通道数量
- ret = snd_pcm_hw_params_set_channels(playback_handle, hw_params, 2);
- if (ret < 0) {
- perror("snd_pcm_hw_params_set_channels");
- exit(1);
- }
- /* Set period size to 32 frames. */
- frames = 32;
- periodsize = frames * 2;
- ret = snd_pcm_hw_params_set_buffer_size_near(playback_handle, hw_params, &periodsize);
- if (ret < 0)
- {
- printf("Unable to set buffer size %li : %s\n", frames * 2, snd_strerror(ret));
- }
- periodsize /= 2;
- ret = snd_pcm_hw_params_set_period_size_near(playback_handle, hw_params, &periodsize, 0);
- if (ret < 0)
- {
- printf("Unable to set period size %li : %s\n", periodsize, snd_strerror(ret));
- }
- //8. 设置hw_params
- ret = snd_pcm_hw_params(playback_handle, hw_params);
- if (ret < 0) {
- perror("snd_pcm_hw_params");
- exit(1);
- }
- /* Use a buffer large enough to hold one period */
- snd_pcm_hw_params_get_period_size(hw_params, &frames, &dir);
- size = frames * 2; /* 2 bytes/sample, 2 channels */
- buffer = (char *) malloc(size);
- fprintf(stderr,
- "size = %d\n",
- size);
- while (1)
- {
- ret = fread(buffer, 1, size, fp);
- if(ret == 0)
- {
- fprintf(stderr, "end of file on input\n");
- break;
- }
- else if (ret != size)
- {
- }
- //9. 写音频数据到PCM设备
- while(ret = snd_pcm_writei(playback_handle, buffer, frames)<0)
- {
- usleep(2000);
- if (ret == -EPIPE)
- {
- /* EPIPE means underrun */
- fprintf(stderr, "underrun occurred\n");
- //完成硬件参数设置,使设备准备好
- snd_pcm_prepare(playback_handle);
- }
- else if (ret < 0)
- {
- fprintf(stderr,
- "error from writei: %s\n",
- snd_strerror(ret));
- }
- }
- }
- //10. 关闭PCM设备句柄
- snd_pcm_close(playback_handle);
- return 0;
- }
alsa 用户空间编程【转】的更多相关文章
- Linux块设备驱动(二) _MTD驱动及其用户空间编程
MTD(Memory Technology Device)即常说的Flash等使用存储芯片的存储设备,MTD子系统对应的是块设备驱动框架中的设备驱动层,可以说,MTD就是针对Flash设备设计的标准化 ...
- SPI编程1:用户空间的读写操作
spi_device 虽然用户空间不需要直接用到spi_device结构体,但是这个结构体和用户空间的程序有密切的关系,理解它的成员有助于理解SPI设备节点的IOCTL命令,所以首先来介绍它.在内核中 ...
- 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口
Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...
- Linux usb子系统(三):通过usbfs操作设备的用户空间驱动
内核中提供了USB设备文件系统(usbdevfs,Linux 2.6改为usbfs,即USB文件系统),它和/proc类似,都是动态产生的.通过在/etc/fstab文件中添加如下一行:none /p ...
- 用户空间网络提升 NFV 的性能
本文是一篇翻译,翻译自https://software.intel.com/en-us/blogs/2015/06/12/user-space-networking-fuels-nfv-perform ...
- linux内核空间和用户空间详解
linux驱动程序一般工作在内核空间,但也可以工作在用户空间.下面我们将详细解析,什么是内核空间,什么是用户空间,以及如何判断他们.Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Li ...
- 用户空间和内核空间通讯之【Netlink 中】
原文地址:用户空间和内核空间通讯之[Netlink 中] 作者:wjlkoorey258 今天我们来动手演练一下Netlink的用法,看看它到底是如何实现用户-内核空间的数据通信的.我们依旧是在2.6 ...
- 用户空间和内核空间通讯之【Netlink 上】
原文地址:用户空间和内核空间通讯之[Netlink 上] 作者:wjlkoorey258 引言 Alan Cox在内核1.3版本的开发阶段最先引入了Netlink,刚开始时Netlink是以字符驱动接 ...
- Linux系统调用具体解释(怎样从用户空间进入内核空间)
系统调用概述 计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同一时候执行的多个进程都须要訪问这些资源,为了更好的管理这些资源进程是不同意直接操作的,全部对这些资源的訪问都必须有操作系统控制. ...
随机推荐
- Mongodb——文档数据库
mongodb是一个文档数据库. mongo操作 多个修改操作,但每个修改携带的数据包较小,可操作考虑批量操作.bulkWrite()改善性能. MongoCollection是线程安全的. db.c ...
- 8 switch case
当一个case成立,从这个case向后穿透所有case,即使后面的case条件不成立 包括default,直到程序结束或者遇到break程序才结束. 1.case是常量,且不能重复 2.表达式可以是b ...
- day41 网络编程
目录 网络架构 单机架构 CS架构 BS架构 互联网和互联网的组成(教材版) 边缘部分: 核心部分: 互联网的组成 硬件 软件 打开网页的过程(科普版) 物理层 数据链路层 网络层 传输层 抽象层 网 ...
- Enable ssh root login in Solaris
1. Change the file /etc/ssh/sshd_config with PermitRootLogin yes to replace PermitRootLogin no 2. re ...
- 18清明校内测试T3
扫雷(mine) Time Limit:1000ms Memory Limit:128MB 题目描述 rsy最近沉迷于一款叫扫雷的游戏. 这个游戏是这样的.一开始网格上有n*m个位置,其中有一些位 ...
- java面试题(转)
1.面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:- 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些 ...
- PAT 1060. Are They Equal
If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered ...
- CTF中编码与加解密总结
CTF中那些脑洞大开的编码和加密 转自:https://www.cnblogs.com/mq0036/p/6544055.html 0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到 ...
- java 多线程面试题
1.什么是线程? 线程是操作系统能够运行的最小调度单位,他被包含在进程中,是进程中实际运作的单位. 2.线程和进程的区别 线程是进程的子集,一个进程有很多线程,每个线程执行不同的任务,不同的进程使用不 ...
- JavaScript中的call()和apply()方法,借此实现继承
1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...