Linux音频编程(二)声卡介绍
一、声卡
1、声卡是audio interface,它含有hardware buffer,而这个hardware buffer是在声卡里面,不是内存。声卡的缓存是环状的,则ALSA中是将数据分成连续的片段然后传到按单元片段传输。
2、当我们通过麦克风讲话的声音搜集到声卡里之后,将内存从声卡设备文件中读取声音数据的过程就是录音过程;把内存中的声音数据写入到声卡的设备文件中可以实现音频文件。
3、我们在/dev/snd/目录下用ls命令就可以看到相关的声卡设备。
4、模/数(ADC)转换器将模拟电压转换成离散的样本值。声音以固定的时间间隔被采样,采样的速率称为采样率。把样本输出到数/模(DAC)转换器,比如扩音器,最后转换成原来的模拟信号。
二、相关设备文件介绍
1、/dev/dsp
用于数字采样(sampling)和数字录音(recording)的设备文件,向该设备写数据时使用声卡上的D/A转换器进行放音,而向该设备读数据时使用声卡上的A/D转换器进行录音。
声卡使用DSP(数字信号处理器)来实现模拟信号和数字信号之间的转换(有D/A和A/D转换)。声卡中的DSP设备在以只读方式打开/dev/dsp时,使用A/D转换器变成数字采样后的样本,通过read系统调用从声卡读取数据进行声音的输入;以只写方式打开/dev/dsp时,数字信号经过D/A转换器变成模拟信号,通过write进行声音的输出。以读写的方式打开 /dev/dsp可同时进行声音的输入和输出。
2、/dev/sequencer合成器
3、/dev/mixer混音器
三、使用
1、在打开声卡之后可通过ioctl函数来设置声卡参数,函数如下所示:
int ioctl(int fd, int request, ...);
//参数fd是打开的文件的描述符,它是在设备打开时获得的;如果设备比较复杂,那么对它的控制请求相应地也会有很多种。
//参数request是命令,它的目的就是用来区分不同的控制请求;通常说来,在对设备进行控制时还需要有其它参数,这要根据不同的控制请求才能确定,并且可能是与硬件设备直接相关的。
//第三个参数是完成命令的操作需要的参数或返回的结果。它的意义取决于命令参数,可以是单个数,或是指向复杂的数据结构的指针。(由于ioctl函数面向所有设备文件,不同的设备又是千差万别,所以,第三个参数的意义、函数的返回值、错误代码等等都取决于command。并且,不同的设备,即使是相同的command也有不同的含义,需要的参数和返回值、错误代码等也不同。)
//ioctl函数中相关的命令如下:
SOUND_PCM_WRITE_BITS:设置声卡的量化位数,8或者16,有些声卡不支持16位;
SOUND_PCM_READ_BITS:获取当前声卡的量化位数;
SOUND_PCM_WRITE_CHANNELS:设置声卡的声道数目,1或者2,1为单声道,2为立体声;
SOUND_PCM_READ_CHANNELS:获取当前声卡的声道数;
SOUND_PCM_WRITE_RATE:设置声卡的采样频率,8K,16K等等;
SOUND_PCM_READ_RATE:获取声卡的采样频率
(1)声卡读取数据和向声卡写入数据时,具有特定的格式,默认为8位无符号数据、单声道、8KHz采样率,可通过ioctl系统调用来改变格式,可调节运行在Linux内核中的声卡驱动程序中缓冲区的大小,进而达到放音和录音想要的效果。例如:
//缓冲区大小设置
int setting = 0xnnnnssss;
int result = ioctl(handle, SNDCTL_DSP_SETFRAGMENT, &setting);
//参数setting实际上由两部分组成,其低16位标明缓冲区的尺寸,相应的计算公式为buffer_size = 2^ssss;
//若参数setting低16位的值为16,那么相应的缓冲区的大小会被设置为65536字节。参数setting的高16位则用来标明分片(fragment)的最大序号,它的取值范围从2一直到0x7FFF,其中0x7FFF表示没有任何限制。
//设置声卡声道数目
int channels = 0; //0=mono 1=stereo
int result = ioctl(handle, SNDCTL_DSP_STEREO, &channels);
//设置采样格式
int format = AFMT_U8;
int result = ioctl(handle, SNDCTL_DSP_SETFMT, &format);
//设置采样频率
int rate = 22050;
int result = ioctl(handle, SNDCTL_DSP_SPEED, &rate);
//调用ioctl时将第二个参数的值设置为SNDCTL_DSP_SPEED,同时在第三个参数中指定采样频率的数值。
//在 Linux下进行音频编程时最常用到的几种采样频率是11025Hz、16000Hz、22050Hz、32000Hz和44100Hz。
2、直接使用系统调用控制声卡的是tinyalsa库,位于目录/external/tinyalsa下,编译生成库文件libtinyalsa.so(只涉及两个文件mixer.c,pcm.c),编译生成工具 tinycap,tinymix,tinypcminfo,tinyplay,可用于直接控制音频通道,进行录音播音测试。tinyalsa中使用:
pcm_open()来打开声卡;
pcm_write()来播放音乐;
pcm_read()来录音。
3、config 的配置很重要,tinyalsa直接从wav文件把channels,rate,等读出来并配置进声卡。
//转换成config
config.channels = channels; //声道数目
config.rate = rate; //采样频率
config.period_size = 1024; //周期
config.period_count = 4; //count
if (bits == 32)
config.format = PCM_FORMAT_S32_LE; //
else if (bits == 16)
config.format = PCM_FORMAT_S16_LE;
config.start_threshold = 0;
config.stop_threshold = 0;
config.silence_threshold = 0;
//
pcm = pcm_open(card, device, PCM_IN, &config);
if (!pcm || !pcm_is_ready(pcm)) {
printf("Unable to open PCM device (%s)\n",pcm_get_error(pcm));
return 0;
}
四、
1、spdif接口支持rawdata和pcmdata模式。
当音频channel设置成channels=4的时候,spdif会相应设置成rawdata模式。当音频channel设置成channels=2或者1的时候,spdif会设置成pcmdata模式。spdif是一个独立的音频驱动,接口支持alsalib中的标准接口。
2、Hdmiaudio支持rawdata和pcmdata模式。
当音频channel设置成channels=4的时候,hdmiaudio会相应设置成rawdata模式。当音频channel设置成channels=2或者1的时候,hdmiaudio会设置成pcmdata模式。Hdmiaudio是一个独立的音频驱动,接口支持alsalib中的标准接口。
Linux音频编程(二)声卡介绍的更多相关文章
- Linux音频编程指南
Linux音频编程指南 虽然目前Linux的优势主要体现在网络服务方面,但事实上同样也有着非常丰富的媒体功能,本文就是以多媒体应用中最基本的声音为对象,介绍如何在Linux平台下开发实际的音频应用程序 ...
- Linux音频编程指南(转)
转自: http://www.ibm.com/developerworks/cn/linux/l-audio/ Linux音频编程指南 虽然目前Linux的优势主要体现在网络服务方面,但事实上同样也有 ...
- Linux音频编程
1. 背景 在<Jasper语音助理介绍>中, 介绍了Linux音频系统, 本文主要介绍了Linux下音频编程相关内容. 音频编程主要包括播放(Playback)和录制(Record), ...
- [转] - Linux网络编程 -- 网络知识介绍
(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端 网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...
- Linux网络编程(二)
Linux网络编程(二) 使用多进程实现服务器并发访问. 采用多进程的方式实现服务器的并发访问的经典范例. 程序实现功能: 1.客户端从标准输入读入一行文字,发送到服务器. 2.服务器接收到客户端发来 ...
- Linux音频编程(一)ALSA介绍
Linux下的音频编程中有OSS和ALSA,本篇文章将对ALSA进行相关介绍.ALSA提供一系列基于命令行的工具集,比如混音器(mixer),音频文件播放器(aplay),以及控制特定声卡特定属性的工 ...
- 【Linux系统编程应用】Linux音频编程基础(一)【转】
转自:https://blog.csdn.net/dengjin20104042056/article/details/52435290 一.数字音频 音频信号是一种连续变化的模拟信号,但计算机只能处 ...
- Linux音频编程(三)混音器介绍
一.介绍 1.mixer:用来控制多个输入.输出的音量,也控制输入(microphone,line-in,CD)之间的切换,可以将多个信号组合或者叠加在一起.声卡上的混音器由多个混音通道组成,它们可以 ...
- linux 音频编程
http://blog.csdn.net/sea918/article/details/7249216 1.音频开发模型: OSS(open sound system) linux/unix 平 ...
随机推荐
- 记一次使用LR测试UDP和TCP的过程
背景 最近项目要做性能测试,要出要一份性能报告,让我出一个有关Tcp和Udp的功能模块的测试,流程大概是这样,先走TCP协议协商一下会话,协商成功后走Udp收发数据. 有点简单啊,自己写个功能模块测一 ...
- Redis的分布式和主备配置调研
目前Redis实现集群的方法主要是采用一致性哈稀分片(Shard),将不同的key分配到不同的redis server上,达到横向扩展的目的. 对于一致性哈稀分片的算法,Jedis-2.0.0已经提供 ...
- 关于Oracle本地连接出现与监听有关的问题的解决方法探讨
关于Oracle本地连接出现与监听有关的问题的解决方法探讨 监听的作用: 用于应用桌面即用户与数据库服务器建立连接的媒介,客户端发送连接请求,监听识别请求并建立客户端与服务器的连接后,监听的使命并完成 ...
- SpringBoot分布式:Dubbo+zookeeper
西部开源-秦疆老师:SpringBoot + Dubbo + zookeeper 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! 基础知识 ...
- hadoop2.7作业提交详解之文件分片
在前面一篇文章中(hadoop2.7之作业提交详解(上))中涉及到文件的分片. JobSubmitter.submitJobInternal方法中调用了int maps = writeSplits(j ...
- Linux之vim详解
第一次使用vim,啥都不懂,输入也不能输入,退出也不会退出,特别的尴尬....后来慢慢的接触学习,发现vim真的挺好用的,不过上手有点慢,多用就对了,用多了我相信你也会喜欢这个文本编辑工具的 一.vi ...
- Kubernetes容器云平台建设实践
[51CTO.com原创稿件]Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署.大规模可伸缩.应用容器化管理.伴随着云原生技术的迅速崛起,如今Kubernetes 事实上已经 ...
- Day 02--选题与设计(二)
1.今天我们主要设计了一下我们微信小程序可以实现的功能,客户操作的基本流程,研究了墨刀这个工具的使用方法并试着将想法转化为原型设计项目.我们给自己的系统起名为“天天好餐”.我们认为食堂订送餐与网络上的 ...
- django 获取当前访问的URL
next_url = request.path_info print(next_url) print(request.get_full_path()) //打印出全路径(路径和参数) print(re ...
- hdu6703_array
题意 给定一个1到\(n\)的全排列,两种操作,将\(a_{pos}\)修改为\(a_{pos}+1000000\),询问第一个大于等于\(k\)的且不在\(a_1...a_r\)的数. 分析 由于\ ...