一、数字音频

音频信号是一种连续变化的模拟信号,但计算机仅仅能处理和记录二进制的数字信号。由自然音源得到的音频信号必须经过一定的变换,成为数字音频信号之后,才干送到计算机中作进一步的处理。

数字音频系统通过将声波的波型转换成一系列二进制数据,来实现对原始声音的重现,实现这一步骤的设备常被称为模/数转换器(A/D)。A/D转换器以每秒钟上万次的速率对声波进行採样,每个採样点都记录下了原始模拟声波在某一时刻的状态,通常称之为样本(sample),而每一秒钟所採样的数目则称为採样频率,通过将一串连续的样本连接起来。就能够在计算机中描写叙述一段声音了。对于採样过程中的每个样本来说,数字音频系统会分配一定存储位来记录声波的振幅,一般称之为採样分辨率或者採样精度,採样精度越高,声音还原时就会越细腻。

数字音频涉及到的概念许多,对于在Linux下进行音频编程的程序猿来说。最重要的是理解声音数字化的两个关键步骤:採样和量化

採样就是每隔一定时间就读一次声音信号的幅度。而量化则是将採样得到的声音信号幅度转换为数字值,从本质上讲,採样是时间上的数字化,而量化则是幅度上的数字化。

以下介绍几个在进行音频编程时常常须要用到的技术指标:

採样频率

採样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度样本的次数。採样频率的选择应该遵循奈奎斯特(Harry Nyquist)採样理论:假设对某一模拟信号进行採样,则採样后可还原的最高信号频率仅仅有採样频率的一半,或者说仅仅要採样频率高于输入信号最高频率的两倍,就能从採样信号系列重构原始信号。

正常人听觉的频率范围大约在20Hz~20kHz之间,依据奈奎斯特採样理论,为了保证声音不失真,採样频率应该在40kHz左右。经常使用的音频採样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,假设採用更高的採样频率,还能够达到DVD的音质。

量化位数 

量化位数是对模拟音频信号的幅度进行数字化。它决定了模拟信号数字化以后的动态范围,经常使用的有8位、12位和16位。

量化位越高,信号的动态范围越大,数字化后的音频信号就越可能接近原始信号,但所须要的存贮空间也越大。

声道数 

声道数是反映音频数字化质量的还有一个重要因素,它有单声道和双声道之分。

双声道又称为立体声,在硬件中有两条线路,音质和音色都要优于单声道,但数字化后占领的存储空间的大小要比单声道多一倍。

二、声卡驱动

出于对安全性方面的考虑,Linux下的应用程序无法直接对声卡这类硬件设备进行操作,而是必须通过内核提供的驱动程序才干完毕。在Linux上进行音频编程的本质就是要借助于驱动程序,来完毕对声卡的各种操作。对硬件的控制涉及到寄存器中各个比特位的操作,通常这是与设备直接相关而且对时序的要求很严格,假设这些工作都交由应用程序猿来负责。那么对声卡的编程将变得异常复杂而困难起来,驱动程序的作用正是要屏蔽硬件的这些底层细节,从而简化应用程序的编写。

眼下Linux下经常使用的声卡驱动程序主要有两种:OSSALSA

ALSA和OSS最大的不同之处在于ALSA是由志愿者维护的自由项目,而OSS则是由公司提供的商业产品,因此在对硬件的适应程度上OSS要优于ALSA,它可以支持的声卡种类很多其它。

ALSA尽管不及OSS运用得广泛。但却具有更加友好的编程接口,而且全然兼容于OSS,相应用程序猿来讲无疑是一个更佳的选择。

三、Linux  OSS音频设备驱动

3.1 OSS驱动的组成

OSS标准中有2个最主要的音频设备:mixer(混音器)和DSP(数字信号处理器)。

在声卡的硬件电路中,mixer是一个非常重要的组成部分,它的作用是将多个信号组合或者叠加在一起,对于不同的声卡来说,其混音器的作用可能各不同样。

OSS驱动中。/dev/mixer设备文件是应用程序对mixer进行操作的软件接口。

混音器电路通常由两个部分组成:输入混音器(input mixer)和输出混音器(output mixer)。

输入混音器负责从多个不同的信号源接收模拟信号,这些信号源有时也被称为混音通道或者混音设备。模拟信号通过增益控制器和由软件控制的音量调节器后,在不同的混音通道中进行级别(level)调制。然后被送到输入混音器中进行声音的合成。混音器上的电子开关能够控制哪些通道中有信号与混音器相连。有些声卡仅仅同意连接一个混音通道作为录音的音源,而有些声卡则同意对混音通道做随意的连接。经过输入混音器处理后的信号仍然为模拟信号。它们将被送到A/D转换器进行数字化处理。

输出混音器的工作原理与输入混音器类似,相同也有多个信号源与混音器相连。并且事先都经过了增益调节。当输出混音器对全部的模拟信号进行了混合之后,通常还会有一个总控增益调节器来控制输出声音的大小,此外另一些音调控制器来调节输出声音的音调。经过输出混音器处理后的信号也是模拟信号,它们终于会被送给喇叭或者其他的模拟输出设备。

对混音器的编程包含如何设置增益控制器的级别。以及如何在不同的音源间进行切换。这些操作通常来讲是不连续的,并且不会像录音或者放音那样须要占用大量的计算机资源。

因为混音器的操作不符合典型的读/写操作模式,因此除了
open()和close()两个系统调用之外,大部分的操作都是通过ioctl()系统调用来完毕的。与/dev/dsp不同,/dev/mixer同意多个应用程序同一时候訪问。而且混音器的设置值会一直保持到相应的设备文件被关闭为止。

DSP也称为编解码器,实现录音(录音)和放音(播放)。其相应的设备文件是/dev/dsp或/dev/sound/dsp。OSS声卡驱动程序提供的 /dev/dsp是用于数字採样和数字录音的设备文件。向该设备写数据即意味着激活声卡上的D/A转换器进行放音,而向该设备读数据则意味着激活声卡上的
A/D转换器进行录音。

在从DSP设备读取数据时,从声卡输入的模拟信号经过A/D转换器变成数字採样后的样本,保存在声卡驱动程序的内核缓冲区中,当应用程序通过 read()系统调用从声卡读取数据时,保存在内核缓冲区中的数字採样结果将被拷贝到应用程序所指定的用户缓冲区中。须要指出的是。声卡採样频率是由内核中的驱动程序所决定的,而不取决于应用程序从声卡读取数据的速度。假设应用程序读取数据的速度过慢,以致低于声卡的採样频率,那么多余的数据将会被丢弃(即overflow)。假设读取数据的速度过快,以致高于声卡的採样频率。那么声卡驱动程序将会堵塞那些请求数据的应用程序。直到新的数据到来为止。

在向DSP设备写入数据时。数字信号会经过D/A转换器变成模拟信号。然后产生出声音。应用程序写入数据的速度应该至少等于声卡的採样频率,过慢会产生声音暂停或者停顿的现象(即underflow)。假设用户写入过快的话,它会被内核中的声卡驱动程序堵塞,直到硬件有能力处理新的数据为止。

与其他设备有所不同,声卡通常不须要支持非堵塞(non-blocking)的I/O操作。

即便内核OSS驱动提供了非堵塞的I/O支持,用户空间也不宜採用。

不管是从声卡读取数据,或是向声卡写入数据,其实都具有特定的格式(format)。如无符号8位、单声道、8KHz採样率,假设默认值无法达到要求,能够通过ioctl()系统调用来改变它们。通常说来,在应用程序中打开设备文件/dev/dsp之后。接下去就应该为其设置恰当的格式。然后才干从声卡读取或者写入数据。

3.2 mixer接口

int register_sound_mixer(structfile_operations *fops, int dev);

上述函数用于注冊1个混音器,第1个參数fops即是文件操作接口,第2个參数dev是设备编号,假设填入-1,则系统自己主动分配1个设备编号。

mixer 是 1个典型的字符设备,因此编码的主要工作是实现file_operations中的open()、ioctl()等函数。

mixer接口file_operations中的最重要函数是ioctl()。它实现混音器的不同IO控制命令。

3.3 DSP接口

int register_sound_dsp(structfile_operations *fops, int dev);

上述函数与register_sound_mixer()类似,它用于注冊1个dsp设备,第1个參数fops即是文件操作接口,第2个參数dev是设备编号,假设填入-1。则系统自己主动分配1个设备编号。

dsp也是1个典型的字符设备。因此编码的主要工作是实现file_operations中的read()、write()、ioctl()等函数。

dsp接口file_operations中的read()和write()函数很重要。read()函数从音频控制器中获取录音数据到缓冲区并复制到用户空间,write()函数从用户空间拷贝音频数据到内核空间缓冲区并终于发送到音频控制器。

dsp接口file_operations中的ioctl()函数处理对採样率、量化精度、DMA缓冲区块大小等參数设置IO控制命令的处理。

在数据从缓冲区复制到音频控制器的过程中,一般会使用DMA,DMA对声卡而言很重要。比如,在放音时。驱动设置完DMA控制器的源数据地址(内存中 DMA缓冲区)、目的地址(音频控制器FIFO)和DMA的数据长度,DMA控制器会自己主动发送缓冲区的数据填充FIFO。直到发送完对应的数据长度后才中断一次。

在OSS驱动中。建立存放音频数据的环形缓冲区(ring buffer)一般是值得推荐的方法。

此外,在OSS驱动中,通常会将1个较大的DMA缓冲区分成若干个大小同样的块(这些块也被称为“段”,即
fragment
),驱动程序使用DMA每次在声音缓冲区和声卡之间搬移一个fragment。在用户空间。能够使用ioctl()系统调用来调整块的大小和个数。

除了read()、write()和ioctl()外,dsp接口的poll()函数通常也须要被实现,以向用户反馈眼下是否能读写DMA缓冲区。

在OSS驱动初始化过程中,会调用register_sound_dsp()和register_sound_mixer()注冊dsp和mixer设备。在模块卸载的时候。会调用unregister_sound_dsp(audio_dev_dsp)和unregister_sound_mixer(audio_dev_mixer)。

Linux OSS驱动结构例如以下图所看到的:

3.4 OSS用户空间编程

1、DSP编程

DSP接口的操作一般包含例如以下几个步骤:


打开设备文件/dev/dsp

採用何种模式对声卡进行操作也必须在打开设备时指定,对于不支持全双工的声卡来说,应该使用仅仅读或者仅仅写的方式打开,仅仅有那些支持全双工的声卡,才干以读写的方式打开,这还依赖于驱动程序的详细实现。Linux同意应用程序多次打开或者关闭与声卡相应的设备文件,从而可以非常方便地在放音状态和录音状态之间进行切换。


假设有须要,设置缓冲区大小

执行在Linux内核中的声卡驱动程序专门维护了一个缓冲区,其大小会影响到放音和录音时的效果,使用ioctl()系统调用能够对它的尺寸进行恰当的设置。调节驱动程序中缓冲区大小的操作不是必须的,假设没有特殊的要求,一般採用默认的缓冲区大小也就能够了。

假设想设置缓冲区的大小。则通常应紧跟在设备文件打开之后,这是由于对声卡的其他操作有可能会导致驱动程序无法再改动其缓冲区的大小。


设置声道(channel)数量

依据硬件设备和驱动程序的详细情况。能够设置为单声道或者立体声。


设置採样格式和採样频率

採样格式包含AFMT_U8(无符号8位)、AFMT_S8(有符号8位)、AFMT_U16_LE(小端模式,无符号16位)、 AFMT_U16_BE(大端模式,无符号16位)、AFMT_MPEG、AFMT_AC3等。使用SNDCTL_DSP_SETFMT IO控制命令能够设置採样格式。

对于大多数声卡来说。其支持的採样频率范围一般为5kHz到44.1kHz或者48kHz。但并不意味着该范围内的全部连续频率都会被硬件支持,在 Linux下进行音频编程时最经常使用到的几种採样频率是11025Hz、16000Hz、22050Hz、32000Hz 和44100Hz。使用SNDCTL_DSP_SPEED IO控制命令能够设置採样频率。


读写/dev/dsp实现播放或录音

2. mixer编程

声卡上的混音器由多个混音通道组成,它们能够通过驱动程序提供的设备文件/dev/mixer进行编程。

对声卡的输入增益和输出增益进行调节是混音器的一个主要作用,眼下大部分声卡採用的是8位或者16位的增益控制器,声卡驱动程序会将它们转换成百分比的形式。也就是说不管是输入增益还是输出增益。其取值范围都是从0~100。

Linux音频驱动简述的更多相关文章

  1. Linux音频驱动-ALSA概述

    概述 ALSA(Advanced Linux Sound Architecture)是linux上主流的音频结构,在没有出现ALSA架构之前,一直使用的是OSS(Open Sound System)音 ...

  2. Linux音频驱动学习之:(1)ASOC分析

    一.音频架构概述 (1)ALSA是Advanced Linux Sound Architecture 的缩写,目前已经成为了linux的主流音频体系结构,想了解更多的关于ALSA的这一开源项目的信息和 ...

  3. 小白自制Linux开发板 八. Linux音频驱动配置

    不知不觉小白自制开发板系列已经到第八篇了,本篇要配置的是音频驱动,也算是硬件部分的最后一片了,积攒的文章也差不多全放完了,后续更新可能会放缓,还请见谅. 对于F1C200s是自带了多媒体处理功能的,所 ...

  4. Linux音频驱动学习之:(2)移植wm8976声卡驱动(linux-3.4.2)

    1.wm8976驱动程序: /* * wm8976.h -- WM8976 Soc Audio driver * * This program is free software; you can re ...

  5. linux 音频驱动

    转:https://wenku.baidu.com/view/7394e16d7e21af45b307a8dc.html?pn=51 linux_sound_alsa_ALSA体系SOC子系统中数据流 ...

  6. linux音频alsa-uda134x驱动文档阅读之一转自http://blog.csdn.net/wantianpei/article/details/7817293

    前言 目前,linux系统常用的音频驱动有两种形式:alsa oss alsa:现在是linux下音频驱动的主要形式,与简单的oss兼容.oss:过去的形式而我们板子上的uda1341用的就是alsa ...

  7. 嵌入式驱动开发之---Linux ALSA音频驱动(一)

    本文的部分内容参考来自DroidPhone的博客(http://blog.csdn.net/droidphone/article/details/6271122),关于ALSA写得很不错的文章,只是少 ...

  8. 基于Linux ALSA音频驱动的wav文件解析及播放程序 2012

    本设计思路:先打开一个普通wav音频文件,从定义的文件头前面的44个字节中,取出文件头的定义消息,置于一个文件头的结构体中.然后打开alsa音频驱动,从文件头结构体取出采样精度,声道数,采样频率三个重 ...

  9. Linux MMC 驱动子系统简述(源码剖析)

    1. Linux MMC 驱动子系统 块设备是Linux系统中的基础外设之一,而 MMC/SD 存储设备是一种典型的块设备.Linux内核设计了 MMC子系统,用于管理 MMC/SD 设备. MMC ...

随机推荐

  1. Median_of_Two_Sorted_Arrays(理论支持和算法总结)

    可以将这个题目推广到更naive的情况,找两个排序数组中的第K个最大值(第K个最小值). 1.直接 merge 两个数组,然后求中位数(第K个最大值或者第K个最小值),能过,不过复杂度是 O(n + ...

  2. java中的三元运算符

    格式: 关系表达式 ? 表达式1:表达式2 public class OperatorDemo { public static void main(String[] args){ int a = 10 ...

  3. python运行原理/python解释器

    先Mark一下这个主题,内容待添加... 参考文章: [1]http://www.cnblogs.com/restran/p/4903056.html [2]https://blog.hakril.n ...

  4. NET/ASP.NET MVC Controller 控制器(一:深入解析控制器运行原理)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC Controller 控制器的入口(Controller的执行流程) 3.ASP.NETMVC Controller 控制器的入口(Controll ...

  5. POJ 3259 Wormholes【最短路/SPFA判断负环模板】

    农夫约翰在探索他的许多农场,发现了一些惊人的虫洞.虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径 ...

  6. html不识别<br/>,后台返回<br/>,前端不换行解决办法

    今天编写页面,后台直接返回带有html格式的字符串,包含<br/>,前端以为要展示<br/>,将其解析为<br/>页面不换行 解决办法 后台将<br/> ...

  7. scrapy抓取拉勾网职位信息(一)——scrapy初识及lagou爬虫项目建立

    本次以scrapy抓取拉勾网职位信息作为scrapy学习的一个实战演练 python版本:3.7.1 框架:scrapy(pip直接安装可能会报错,如果是vc++环境不满足,建议直接安装一个visua ...

  8. Bzoj4753/洛谷P4432 [JSOI2016]最佳团体(0/1分数规划+树形DP)

    题面 Bzoj 洛谷 题解 这种求比值最大就是\(0/1\)分数规划的一般模型. 这里用二分法来求解最大比值,接着考虑如何\(check\),这里很明显可以想到用树形背包\(check\),但是时间复 ...

  9. 洛谷——P2082 区间覆盖(加强版)

    P2082 区间覆盖(加强版) 题目描述 已知有N个区间,每个区间的范围是[si,ti],请求出区间覆盖后的总长. 输入输出格式 输入格式: N s1 t1 s2 t2 …… sn tn 输出格式: ...

  10. 主数据及其管理MDM

    什么是主数据 企业数据的管理包含主数据,元数据,交易数据. 主数据是描述企业核心实体的基础数据,比如客户.用户.产品.员工等. 它是具有高业务价值的.可以在企业内跨越各个业务部门被重复使用的数据,并且 ...