Linux音频驱动(1)
Linux下的声卡驱动主要有OSS和ALSA。
OOS(Open Sound System),官网:www.opensound.com
ALSA(Advanced Linux Sound Architecture),官网:www.alsa-project.com
OSS架构与实现
OSS设备是字符设备,主设备号是14,次设备号由各个设备单独定义。
设备文件:
/dev/sndstat
只读文件,作用仅限于汇报当前声卡状态。提供给最终用户检测声卡的。
/dev/dsp
用于数字采样(sampling)和数字录音(recording)的设备文件。写数据就是放音,读数据就是录音。这个设备可能有多个,如/dev/dsp1等。
dsp设备主要是用来进行A/D,D/A转换的。可以已读写的方式打开,比如IP电话。
dsp设备驱动要考虑内核缓冲区和用户缓冲区的速度匹配,主要是采样频率(由内核决定)和应用程序的读写速度间的匹配,速度差异会导致声音数据不一致或者IO阻塞。
默认:8位无符号数据,单声道,8KHz采样率。
/dev/audio
类似于/dev/dsp,出于对兼容性的考虑,兼容于Sun工作站上的音频设备,使用的是mu-law编码方式,甚用。对于应用程序来说,同一时刻只能使用/dev/dsp或/dev/audio中的一种,因为它们是相同硬件的不同软件接口。
/dev/mixer
应用程序对混音器的软件接口。混音器电路通常由两个部分组成:input mixer和ouput mixer。
混音器位于dsp之后,和喇叭之类的设备直接相连。混音器输出的都是模拟信号,不管是对dsp进行输出,还是对喇叭进行输出。
对混音器的编程包括如何设置增益控制器的级别,以及如何在不同的音源间进行切换。通常这些操作是不连续的,而且不会像录音或者放音那样占用大量计算机资源。因此,混音器除了open和close外,大部分操作都是通过ioctl系统调用来完成。与/dev/dsp不同,/dev/mixer允许多个应用程序同时访问,并且混音器的设置值会一直保持到对应的设备文件被关闭为止。
为了简化应用程序的设计,Linux上的声卡驱动程序大多支持将混音器的ioctl操作直接应用到声音设备上,也就是说,如果已经打开了/dev/dsp,那么就不用打开/dev/mixer来对混音器进行操作,而是可以直接用打开/dev/dsp时得到的文件标志符来设置混音器。
/dev/sequencer
用来对声卡内建的波表合成器进行操作,或者对MIDI总线上的乐器进行控制。
相关文件:(kernel中)
include/linux/soundcard.h
include/linux/sound.h
sound/sound_core.h
模块入口见sound_core.h:
主要实现
subsys_initcall(init_soundcore);
module_exit(cleanup_soundcore);
static int __init init_soundcore(void)
{
int rc;
rc = init_oss_soundcore();
if (rc)
return rc;
sound_class = class_create(THIS_MODULE, "sound");
if (IS_ERR(sound_class)) {
cleanup_oss_soundcore();
return PTR_ERR(sound_class);
}
sound_class->devnode = sound_devnode;
return 0;
}
static int __init init_oss_soundcore(void)
{
if (preclaim_oss &&
register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops) == -1) {
printk(KERN_ERR "soundcore: sound device already in use.\n");
return -EBUSY;
}
return 0;
}
static void __exit cleanup_soundcore(void)
{
cleanup_oss_soundcore();
class_destroy(sound_class);
}
static void cleanup_oss_soundcore(void)
{
/* We have nothing to really do here - we know the lists must be
empty */
unregister_chrdev(SOUND_MAJOR, "sound");
}
static const struct file_operations soundcore_fops =
{
/* We must have an owner or the module locking fails */
.owner = THIS_MODULE,
.open = soundcore_open,
};
OOS(Open Sound System),官网:www.opensound.com
ALSA(Advanced Linux Sound Architecture),官网:www.alsa-project.com
OSS架构与实现
OSS设备是字符设备,主设备号是14,次设备号由各个设备单独定义。
设备文件:
/dev/sndstat
只读文件,作用仅限于汇报当前声卡状态。提供给最终用户检测声卡的。
/dev/dsp
用于数字采样(sampling)和数字录音(recording)的设备文件。写数据就是放音,读数据就是录音。这个设备可能有多个,如/dev/dsp1等。
dsp设备主要是用来进行A/D,D/A转换的。可以已读写的方式打开,比如IP电话。
dsp设备驱动要考虑内核缓冲区和用户缓冲区的速度匹配,主要是采样频率(由内核决定)和应用程序的读写速度间的匹配,速度差异会导致声音数据不一致或者IO阻塞。
默认:8位无符号数据,单声道,8KHz采样率。
/dev/audio
类似于/dev/dsp,出于对兼容性的考虑,兼容于Sun工作站上的音频设备,使用的是mu-law编码方式,甚用。对于应用程序来说,同一时刻只能使用/dev/dsp或/dev/audio中的一种,因为它们是相同硬件的不同软件接口。
/dev/mixer
应用程序对混音器的软件接口。混音器电路通常由两个部分组成:input mixer和ouput mixer。
混音器位于dsp之后,和喇叭之类的设备直接相连。混音器输出的都是模拟信号,不管是对dsp进行输出,还是对喇叭进行输出。
对混音器的编程包括如何设置增益控制器的级别,以及如何在不同的音源间进行切换。通常这些操作是不连续的,而且不会像录音或者放音那样占用大量计算机资源。因此,混音器除了open和close外,大部分操作都是通过ioctl系统调用来完成。与/dev/dsp不同,/dev/mixer允许多个应用程序同时访问,并且混音器的设置值会一直保持到对应的设备文件被关闭为止。
为了简化应用程序的设计,Linux上的声卡驱动程序大多支持将混音器的ioctl操作直接应用到声音设备上,也就是说,如果已经打开了/dev/dsp,那么就不用打开/dev/mixer来对混音器进行操作,而是可以直接用打开/dev/dsp时得到的文件标志符来设置混音器。
/dev/sequencer
用来对声卡内建的波表合成器进行操作,或者对MIDI总线上的乐器进行控制。
相关文件:(kernel中)
include/linux/soundcard.h
include/linux/sound.h
sound/sound_core.h
模块入口见sound_core.h:
主要实现
subsys_initcall(init_soundcore);
module_exit(cleanup_soundcore);
static int __init init_soundcore(void)
{
int rc;
rc = init_oss_soundcore();
if (rc)
return rc;
sound_class = class_create(THIS_MODULE, "sound");
if (IS_ERR(sound_class)) {
cleanup_oss_soundcore();
return PTR_ERR(sound_class);
}
sound_class->devnode = sound_devnode;
return 0;
}
static int __init init_oss_soundcore(void)
{
if (preclaim_oss &&
register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops) == -1) {
printk(KERN_ERR "soundcore: sound device already in use.\n");
return -EBUSY;
}
return 0;
}
static void __exit cleanup_soundcore(void)
{
cleanup_oss_soundcore();
class_destroy(sound_class);
}
static void cleanup_oss_soundcore(void)
{
/* We have nothing to really do here - we know the lists must be
empty */
unregister_chrdev(SOUND_MAJOR, "sound");
}
static const struct file_operations soundcore_fops =
{
/* We must have an owner or the module locking fails */
.owner = THIS_MODULE,
.open = soundcore_open,
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.