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


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