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,
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章