linux alsa djr·alsa中文版
大家好,今天来为大家解答linux alsa这个问题的一些问题点,包括djr·alsa中文版也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~
请教Linux下ALSA声道切换
解各参数含义及些基本概念
本度(sample):本记录音频数据基本单位见8位16位
通道数(channel):该参数1表示单声道2则立体声
桢(frame):桢记录声音单元其度本度与通道数乘积
采率(rate):每秒钟采数该数针桢言
周期(period):音频设备处理所需要桢数于音频设备数据访问及音频数据存储都单位
交错模式(interleaved):种音频数据记录式交错模式数据连续桢形式存放即首先记录完桢1左声道本右声道本(假设立体声格式)再始桢2记录非交错模式首先记录周期内所桢左声道本再记录右声道本数据连续通道式存储数情况我需要使用交错模式
period(周期):硬件断间间隔间表示输入延
声卡接口指针指示声卡硬件缓存区前读写位置要接口运行指针循环指向缓存区某位置
frame size= sizeof(one sample)* nChannels
alsa配置缓存(buffer)周期(size)runtime帧(frames)形式存储
period_bytes= frames_to_bytes(runtime, runtime->period_size);
bytes_to_frames()
The period and buffer sizes are not dependent on the sample format because they are measured in frames; you do not need to change them.
ALSA声音编程介绍
ALSA表示高级Linux声音体系结构(Advanced Linux Sound Architecture)由系列内核驱应用程序编译接口(API)及支持Linux声音实用程序组篇文章我简单介绍ALSA项目基本框架及软件组主要集介绍PCM接口编程包括您自实践程序示例
您使用ALSA原能新并唯用声音API您想完低级声音操作便能够化控制声音并化提高性能或者您使用其声音API没特性ALSA选择您已经写音频程序能想要ALSA声卡驱添加本支持您音频兴趣想播放音频文件高级API更选择比SDL,OpenAL及些桌面环境提供工具集另外您能ALSA支持Linux环境使用ALSA
ALSA历史
ALSA项目发起起Linux声卡驱(OSS/Free drivers)没积极维护并且落于新声卡技术Jaroslav Kysela早先写声卡驱并由始ALSA项目随便更发者加入发队伍更声卡支持API结构重组
Linux内核2.5发程ALSA合并官源码树发布内核2.6ALSA已经内建稳定内核版本并广泛使用
数字音频基础
声音由变化气压组麦克风转换器转换电形式模/数(ADC)转换器模拟电压转换离散本值声音固定间间隔采采速率称采率本输数/模(DAC)转换器比扩音器转换原模拟信号
本位表示本影响声音转换数字信号精确程度素另主要素采率奈奎斯特(Nyquist)理论要离散系统奈奎斯特频率高于采信号高频率或带宽避免混叠现象
ALSA基础
ALSA由许声卡声卡驱程序组同提供称libasoundAPI库应用程序发者应该使用libasound内核ALSA接口libasound提供高级并且编程便编程接口并且提供设备逻辑命名功能发者甚至需要知道类似设备文件低层接口相反OSS/Free驱内核系统调用级编程要求发者提供设备文件名并且利用ioctrl实现相应功能向兼容ALSA提供内核模块模拟OSS前许OSS基础发应用程序需要任何改ALSA运行另外libaoss库模拟OSS需要内核模块
ALSA包含插件功能使用插件扩展新声卡驱包括完全用软件实现虚拟声卡ALSA提供系列基于命令行工具集比混音器(mixer)音频文件播放器(aplay)及控制特定声卡特定属性工具
ALSA体系结构
ALSA API解几主要接口:
1控制接口:提供管理声卡注册请求用设备通用功能
2 PCM接口:管理数字音频放(playback)录音(capture)接口本文续总结重点放接口发数字音频程序用接口
3 Raw MIDI接口:支持MIDI(Musical Instrument Digital Interface),标准电乐器些API提供声卡MIDI总线访问原始接口基于MIDI事件工作由程序员负责管理协议及间处理
4定器(Timer)接口:同步音频事件提供声卡间处理硬件访问
5序器(Sequencer)接口
6混音器(Mixer)接口
设备命名
API库使用逻辑设备名设备文件设备名字真实硬件名字插件名字硬件名字使用hw:i,j格式其i卡号j块声卡设备号第声音设备hw:0,0.别名默认引用第块声音设备并且本文示例真用插件使用另外唯名字比plughw:,表示插件插件提供硬件设备访问提供像采率转换软件特性硬件本身并支持特性
声音缓存数据传输
每声卡都硬件缓存区保存记录本缓存区足够满声卡产断内核声卡驱使用直接内存(DMA)访问通道本传送内存应用程序缓存区类似于放任何应用程序使用DMA自缓存区数据传送声卡硬件缓存区
硬件缓存区环缓存说数据达缓存区末尾重新缓存区起始位置ALSA维护指针指向硬件缓存及应用程序缓存区数据操作前位置内核外部看我应用程序缓存区兴趣所本文讨论应用程序缓存区
应用程序缓存区通ALSA库函数调用控制缓存区传输操作能导致接受延迟我称延(latency)解决问题ALSA缓存区拆系列周期(period)(OSS/Free叫片断fragments).ALSAperiod单元传送数据
周期(period)存储些帧(frames)每帧包含间点所抓取本于立体声设备帧包含两信道本图1展示解程:缓存区解周期帧本图包含些假定数值图左右信道信息交替存储帧内称交错(interleaved)模式非交错模式信道所本数据存储另外信道数据
Over and Under Run
声卡数据总连续硬件缓存区应用程序缓存区间传输例外录音例应用程序读取数据够快循环缓存区新数据覆盖种数据丢失称overrun.放例应用程序写入数据缓存区速度够快缓存区"饿死"错误称"underrun"ALSA文档两种情形统称"XRUN"适设计应用程序化XRUN并且恢复
典型声音程序
使用PCM程序通类似面伪代码:
打放或录音接口
设置硬件参数(访问模式数据格式信道数采率等等)
while数据要处理:
读PCM数据(录音)
或写PCM数据(放)
关闭接口
我文看些工作代码我建议您Linux系统测试运行些代码查看输并尝试修改推荐代码本文相关所实例清单FTP获取:ftp.ssc.com/pub/lj/listings/issue126/6735.tgz
Listing 1. Display Some PCM Types and Formats
#include asoundlib.h>
int main(){
int val;
printf("ALSA library version:%s/n",
SND_LIB_VERSION_STR);
printf("/nPCM stream types:/n");
for(val= 0; val<= SND_PCM_STREAM_LAST; val++)
printf("%s/n",
snd_pcm_stream_name((snd_pcm_stream_t)val));
printf("/nPCM access types:/n");
for(val= 0; val<= SND_PCM_ACCESS_LAST; val++)
printf("%s/n",
snd_pcm_access_name((snd_pcm_access_t)val));
printf("/nPCM formats:/n");
for(val= 0; val<= SND_PCM_FORMAT_LAST; val++)
if(snd_pcm_format_name((snd_pcm_format_t)val)
!= NULL)
printf("%s(%s)/n",
snd_pcm_format_name((snd_pcm_format_t)val),
snd_pcm_format_description(
(snd_pcm_format_t)val));
printf("/nPCM subformats:/n");
for(val= 0; val<= SND_PCM_SUBFORMAT_LAST;
val++)
printf("%s(%s)/n",
snd_pcm_subformat_name((
snd_pcm_subformat_t)val),
snd_pcm_subformat_description((
snd_pcm_subformat_t)val));
printf("/nPCM states:/n");
for(val= 0; val<= SND_PCM_STATE_LAST; val++)
printf("%s/n",
snd_pcm_state_name((snd_pcm_state_t)val));
return 0;
}
清单显示些ALSA使用PCM数据类型参数首先需要做包括文件些文件包含所库函数声明其显示ALSA库版本
程序剩部迭代些PCM数据类型流类型始ALSA每迭代值提供符号量名并且提供功能函数显示某特定值描述字符串看ALSA支持许格式我1.0.15版本支持达36种格式
程序必须链接alsalib库通编译需要加-lasound选项些alsa库函数使用dlopen函数及浮点操作所您能需要加-ldl,-lm选项
面该程序Makefile:
CC=gcc
TARGET=test
SRC=$(wildcard*.c)
OBJECT=${SRC:.c=.o}
INCLUDES=-I/usr/include/alsa
LDFLAGS=-lasound
all:$(TARGET)
$(OBJECT):$(SRC)
$(CC)-c$(INCLUDES)$<
$(TARGET):$(OBJECT)
$(CC)-o$@$<$(LDFLAGS)
.PHONY:clean
clean:
@rm-rf$(OBJECT)$(TARGET)*~
Listing 2. Opening PCM Device and Setting Parameters
/*
This example opens the default PCM device, sets
some parameters, and then displays the value
of most of the hardware parameters. It does not
perform any sound playback or recording.
*/
/* Use the newer ALSA API*/
#define ALSA_PCM_NEW_HW_PARAMS_API
/* All of the ALSA library API is defined
* in this header*/
#include asoundlib.h>
int main(){
int rc;
snd_pcm_t*handle;
snd_pcm_hw_params_t*params;
unsigned int val, val2;
int dir;
snd_pcm_uframes_t frames;
/* Open PCM device for playback.*/
rc= snd_pcm_open(&handle,"default",
SND_PCM_STREAM_PLAYBACK, 0);
if(rc< 0){
fprintf(stderr,
"unable to open pcm device:%s/n",
snd_strerror(rc));
exit(1);
}
/* Allocate a hardware parameters object.*/
snd_pcm_hw_params_alloca(?ms);
/* Fill it in with default values.*/
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters.*/
/* Interleaved mode*/
snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format*/
snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
/* Two channels(stereo)*/
snd_pcm_hw_params_set_channels(handle, params, 2);
/* 44100 bits/second sampling rate(CD quality)*/
val= 44100;
snd_pcm_hw_params_set_rate_near(handle,
params,&val,&dir);
/* Write the parameters to the driver*/
rc= snd_pcm_hw_params(handle, params);
if(rc< 0){
fprintf(stderr,
"unable to set hw parameters:%s/n",
snd_strerror(rc));
exit(1);
}
/* Display information about the PCM interface*/
printf("PCM handle name='%s'/n",
snd_pcm_name(handle));
printf("PCM state=%s/n",
snd_pcm_state_name(snd_pcm_state(handle)));
snd_pcm_hw_params_get_access(params,
(snd_pcm_access_t*)&val);
printf("access type=%s/n",
snd_pcm_access_name((snd_pcm_access_t)val));
snd_pcm_hw_params_get_format(params,&val);
printf("format='%s'(%s)/n",
snd_pcm_format_name((snd_pcm_format_t)val),
snd_pcm_format_description(
(snd_pcm_format_t)val));
snd_pcm_hw_params_get_subformat(params,
(snd_pcm_subformat_t*)&val);
printf("subformat='%s'(%s)/n",
snd_pcm_subformat_name((snd_pcm_subformat_t)val),
snd_pcm_subformat_description(
(snd_pcm_subformat_t)val));
snd_pcm_hw_params_get_channels(params,&val);
printf("channels=%d/n", val);
snd_pcm_hw_params_get_rate(params,&val,&dir);
printf("rate=%d bps/n", val);
snd_pcm_hw_params_get_period_time(params,
&val,&dir);
printf("period time=%d us/n", val);
snd_pcm_hw_params_get_period_size(params,
&frames,&dir);
printf("period size=%d frames/n",(int)frames);
snd_pcm_hw_params_get_buffer_time(params,
&val,&dir);
printf("buffer time=%d us/n", val);
snd_pcm_hw_params_get_buffer_size(params,
(snd_pcm_uframes_t*)&val);
printf("buffer size=%d frames/n", val);
snd_pcm_hw_params_get_periods(params,&val,&dir);
printf("periods per buffer=%d frames/n", val);
snd_pcm_hw_params_get_rate_numden(params,
&val,&val2);
printf("exact rate=%d/%d bps/n", val, val2);
val= snd_pcm_hw_params_get_sbits(params);
printf("significant bits=%d/n", val);
snd_pcm_hw_params_get_tick_time(params,
&val,&dir);
printf("tick time=%d us/n", val);
val= snd_pcm_hw_params_is_batch(params);
printf("is batch=%d/n", val);
val= snd_pcm_hw_params_is_block_transfer(params);
printf("is block transfer=%d/n", val);
val= snd_pcm_hw_params_is_double(params);
printf("is double=%d/n", val);
val= snd_pcm_hw_params_is_half_duplex(params);
printf("is half duplex=%d/n", val);
val= snd_pcm_hw_params_is_joint_duplex(params);
printf("is joint duplex=%d/n", val);
val= snd_pcm_hw_params_can_overrange(params);
printf("can overrange=%d/n", val);
val= snd_pcm_hw_params_can_mmap_sample_resolution(params);
printf("can mmap=%d/n", val);
val= snd_pcm_hw_params_can_pause(params);
printf("can pause=%d/n", val);
val= snd_pcm_hw_params_can_resume(params);
printf("can resume=%d/n", val);
val= snd_pcm_hw_params_can_sync_start(params);
printf("can sync start=%d/n", val);
snd_pcm_close(handle);
return 0;
}
Linux的声卡驱动中ALSA与OSS的区别和简单流程介
在声卡的驱动中一种是OSS(开放声音系统),一种是ALSA(先进Linux声音架构)。OSS是一个商业声卡驱动程序,需要花钱购买。一般我们现在使用的是ALSA的声音架构。
Advanced Linux Sound Architecture的简称为 ALSA,译成中文的意思是 Linux高级声音体系,ALSA不仅仅是包括对声卡的支持和驱动;
它的特征如下:
1、对所有音频接口的高效支持,从普通用户的声卡到专业级别多路音频设备;
2、声卡驱动完全模块化设计;
3、SMP and thread-safe design.
4、开发库(alsa-lib)为程序设计提供了简单、方便,并且拥有有高级的效果和功能;
5、支持旧版本的OSS API结口,能为大多数的OSS应用程序提供兼容;OSS是一个商业性的驱动,OSS有一个简装本的代码已经移入内核和ALSA,其中alsa-oss就是;OSS公司据说目前已经并不存在了;我们没有必要用OSS公司提供的商业版本;用ALSA和OSS简装版足够;
如何查看硬件芯片;
在Linux操作系统中,所有的硬件都是以芯片组来区分的,品牌并不是最重要的;硬件最重要的标识是芯片组;所以您在讨论区求助的时候,只说硬件品牌,而不提供芯片组,大家是帮助不了您的,切记;
我们查看硬件的芯片组是的命令是 lspci-v或者是dmesg,由于dmesg输出的信息不太多,不够直观;所以经常用的还是lspci-v;也可以用lshal获取;最方便的还是lspci-v;初学者还是用 lspci-v更好一点;
代码:
[root@localhost beinan]# lspci-v
我们运行lspci-v后,如果查看声卡芯片组,发会现有类似下面的一段;
[root@localhost beinan]# lspci-v
Multimedia audio controller: Intel Corporation 82801DB/DBL/DBM(ICH4/ICH4-L/ICH4-M)
AC'97 Audio Controller(rev 03)
Subsystem: Hewlett-Packard Company: Unknown device 3080
2.6.11-1.1369_FC4 i686 i686 i386
上面的表示的是系统的内核版本,处理器架构等;lsmod查看已经加载的内核模块;
如果一个设备在内核的编译中是以模块方式加载的,主要是通过lsmod来查看;
[root@localhost beinan]# lsmod
可能初学Linux的弟兄会问,内核的module存放在哪里,我们能不能自己来手工加载模块;内核的模块放在/lib/modules/内核的版本/kernel/,比如在Fedora 4.0中,我们可以看到如下的:
[root@localhost beinan]# ls/lib/modules/2.6.11-1.1369_FC4/kernel/
arch/crypto/drivers/ fs/lib/ net/ sound/其中,sound就是声卡模块存放目录,大多数的硬件驱动放在 drivers目录,fs是文件系统模块的目录;net是与网络有关的存放目录,比如一些网络协议支持的模块、防火墙支持的模块等;arch是cpu方面......
如果我们想自己加载模块,就到这些目录中查看相应模块的信息,然后用 modprobe来加载;
[root@localhost beinan]# modinfo snd-intel8x0
查看一个模块的信息,我们用 modinfo来查看,所要查看的模块不要带.ko或者.o之类的;比如查看到类似下面的信息;
description: Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455
通过这个我们足可以知道这是Intel集成声卡,通过lspci-v得到的声卡信息,感觉他们很相近;所以就能尝试用这个模块来驱动;
[root@localhost beinan]# modprobe snd-intel8x0
用 modprobe加载了模块,然后我们通过 lsmod就能看到了;对于声卡模块是这么加载的,其它设备的驱动模块也是如此。
Linux应用开发【第八章】ALSA应用开发
音频信号是一种连续变化的模拟信号,但计算机只能处理和记录二进制的数字信号,由自然音源得到的音频信号必须经过一定的变换,成为数字音频信号之后,才能送到计算机中作进一步的处理。
数字音频系统通过将声波的波型转换成一系列二进制数据,来实现对原始声音的重现,实现这一步骤的设备常被称为(A/D)。A/D转换器以每秒钟上万次的速率对声波进行采样,每个采样点都记录下了原始模拟声波在某一时刻的状态,通常称之为样本(sample),而每一秒钟所采样的数目则称为采样频率,通过将一串连续的样本连接起来,就可以在计算机中描述一段声音了。对于采样过程中的每一个样本来说,数字音频系统会分配一定存储位来记录声波的振幅,一般称之为采样分辨率或者采样精度,采样精度越高,声音还原时就会越细腻。
数字音频涉及到的概念非常多,对于在Linux下进行音频编程的程序员来说,最重要的是7406解声音数字化的两个关键步骤:采样和量化。
采样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度样本的次数。采样频率的选择应该遵循奈奎斯特(Harry Nyquist)采样理论:如果对某一模拟信号进行采样,则采样后可还原的最高信号频率只有采样频率的一半,或者说只要采样频率高于输入信号最高频率的两倍,就能从采样信号系列重构原始信号。
量化位数是对模拟音频信号的幅度进行数字化,它决定了模拟信号数字化以后的动态范围,常用的有8位、12位和16位。量化位越高,信号的动态范围越大,数字化后的音频信号就越可能接近原始信号,但所需要的存储空间也越大。
ALSA全称是Advanced Linux Sound Architecture,中文音译是Linux高级声音体系。ALSA是Linux内核2.6后续版本中支持音频系统的标准接口程序,由ALSA库、内核驱动和相关测试开发工具组成,更好的管理Linux中音频系统。
本小节将介绍ALSA的架构。
ALSA是Linux系统中为声卡提供驱动的内核组件。它提供了专门的库函数来简化相应应用程序的编写。相较于OSS的编程接口,ALSA的函数库更加便于使用。
对应用程序而言,ALSA无疑是一个更佳的选择,因为它具有更加友好的编程接口,并且完全兼容于OSS。
ALSA系统包括7个子项目:
ALSA声卡驱动与用户空间体系结构交互如下图所示:
移植ALSA主要是移植alsa-Ub和alsa-utils。
ALSA Util是纯应用层的软件,相当于ALSA设备的测试程序,ALSA-Lib则是支持应用API的中间层程序,ALSA-Util中的应用程序中会调用到ALSA-Lib中的接口来操作到我们的音频编解码芯片的寄存器,而lib中接口就是依赖于最底层驱动代码,因此移植ALSA程序的顺序就是先后移植Driver,Lib,Util。
ALSA首先需要在ALSA的官网上下载官网 alsa-project.org下载alsa-lib和alsa-utils。
ALSA Lib移植不需要修改源码,只需要重新编译库代码以支持自己的平台。
在上述命令中./configure配置的几个重要的配置选项解释如下:
ALSA Util可以生成用于播放,录制,配置音频的应用可执行文件,测试驱动代码时用处很大,编译过程如下:
ALSA库和测试工具的移植就是将相应库文件和可执行文件放在目标板上,以下文件必须被拷贝至对应位置:
(1)ALSA Lib文件,放在/lib/中。
(2)配置文件放在/usr/local/share中,与编译时指定的目录相同。
(3)测试应用文件,ALSA Util能产生aplay、amixer、arecord,我们可以把这些可执行文件放在/usr/sbin中。
(4)内核目录中保证有/dev/snd/目录,这个目录下存放controlC0,pcmC0D0,/usr/sbintimer,timer这些设备文件,如果这些设备文件已经在/dev目录下,可手动拷贝到/snd目录中。
在LINUX系统中,每个设备文件都是文件。音频设备也是一样,它的设备文件被放在/dev/snd目录下,我们来看下这些设备文件:
(1)controlC0:音频控制设备文件,例如通道选择,混音,麦克风的控制等;
(2)pcmC0D0c:声卡0设备0的录音设备,c表示capter;
(3)pcmC0D0p:声卡0设备0的播音设备,p表示play;
(4)timer:定时器设置。
本小节将着重讲解tinyalsa工具使用,tinyalsa是alsa-lib的一个简化版。它提供了pcm和control的基本接口;没有太多太复杂的操作、功能。可以按需使用接口。
使用方法:
举例:
与amixer作用类似,用于操作mixer control。
使用方法:
举例:
aplay是命令行的ALSA声卡驱动的播放工具,用于播放功能。使用方法:
举例:
arecord是命令行的ALSA声卡驱动的录音工具,用于录音功能。使用方法:
举例:
从代码角度体现了alsa-lib和alsa-driver及hardwared的交互关系。用户层的alsa-lib通过操作alsa-driver创建的设备文件/dev/snd/pcmC0D0p等对内核层进行访问。内核层的alsa-drivier驱动再经由sound core对硬件声卡芯片进行访问。
为了方便操作访问,alsa-lib中封装了相关接口,通过pcmCXDXp/pcmCXDXc节点(/dev/snd/pcmCXDXx)去实现播放、录音功能。
主要涉及到的接口:
详细pcm接口说明请查阅:
alsa-project.org/alsa-d...