Android音頻(1)——ALSA聲卡驅動


一、ALSA基礎知識

1. ALSA(Advanced Linux Sound Architecture)目前已經成為了linux的主流音頻體系結構,ALSA開源項目網址:http://www.alsa-project.org/。
另一個音頻驅動框架是OSS(open sound system),收費,已經廢棄。

2.在內核設備驅動層,ALSA提供了alsa-driver,同時在應用層,ALSA提供了alsa-lib,應用程序只要調用alsa-lib提供的API,即可以完成對底層音頻硬件的控制。

3.PCM(Pulse-code modulation)是脈沖編碼調制,PCM信號的兩個重要指標是采樣頻率和量化精度,目前,CD音頻的采樣頻率通常為44100Hz,量化精度是16bit。
播放音樂時,應用程序從存儲介質中讀取音頻數據(MP3、WMA、AAC...),經過解碼后,最終送到音頻驅動程序中的就是PCM數據;在錄音時,音頻驅動不停地把采樣所得的PCM數據送回給應用程序,由應用程序完成壓縮、存儲等任務。所以,音頻驅動的兩大核心任務就是:
  playback:如何把用戶空間的應用程序發過來的PCM數據,轉化為人耳可以辨別的模擬音頻
  capture:把mic拾取到得模擬信號,經過采樣、量化,轉換為PCM信號送回給用戶空間的應用程序

4.采集兩路數據稱為雙通道,wav格式的文件就是原始的采集聲音數據的文件,壓縮后可為mp3文件。

5.音頻驅動入口文件(注冊主設備號的文件)
alsa_sound_init //sound\core\sound.c
  register_chrdev(116, "alsa", &snd_fops) //snd_fops中只有open()

音頻系統創建的所有設備文件都以struct snd_minor的形式存儲在全局數據snd_minors[]中,snd_fops.open()根據次設備號起中轉功能。

6.ALSA發展歷程:ALSA ---> ASoC --->DAPM,ASoC和DAPM將在后續博客講。

7.相關概念
HiFi:High-Fidelity的縮寫,翻譯為“高保真”,其定義是:與原來的聲音高度相似的重放聲音。
PCM: Pulse-code modulation,中文譯名是脈沖編碼調制。
DAI: Digital Audio Interface
MIDI:Music Instrument Digital Interface


二、Control設備的創建

1. Control接口主要讓用戶空間的應用程序(alsa-lib)可以訪問和控制音頻codec芯片中的多路開關,滑動控件等。對於Mixer(混音)來說,Control接口顯得尤為重要,從ALSA 0.9.x版本開始,所有的mixer工作都是通過control接口的API來實現的。使用snd_kcontrol_new結構來定義一個Control項,根據codec的芯片手冊進行構造snd_kcontrol_new。

2.設置cidec配置的統一的接口就是snd_kcontrol,一個snd_kcontrol表示一個功能(可能是一個寄存器的某些位),每個sndkcontrol中有自己的讀寫函數。一個聲卡有多個kcontrol,一個kcontrol對應一個功能,比如:音量,開關錄音。kcontrol中有函數來設置功能。snd_kcontrol對應的是功能,其寄存器配置由codec驅動負責。

3.kcontrol創建過程示例

struct snd_kcontrol_new wm8960_snd_controls[] //wm8960.c
snd_soc_add_controls(codec, wm8960_snd_controls, ARRAY_SIZE(wm8960_snd_controls));
    snd_ctl_add(card, snd_soc_cnew(control, codec, control->name, codec->name_prefix));
        //將snd_kcontrol_new結構轉換成snd_kcontrol結構
        snd_soc_cnew(control, codec, control->name, codec->name_prefix)
        //獲取一個snd_kcontrol結構
        kcontrol = snd_ctl_new1(&template, data);
        //然后將這些snd_kcontrol結構串接在snd_card.controls域中。
        list_add_tail(&kcontrol->list, &card->controls);

 

二、聲卡的創建

1. 使用struct snd_card表示,其是一個父設備,下面掛載着control pcm節點分別使用snd_device結構表示。snd_card可以說是整個ALSA音頻驅動最頂層的一個結構,整個聲卡的軟件邏輯結構開始於該結構,幾乎所有與聲音相關的邏輯設備都是在snd_card的管理之下,聲卡驅動的第一個動作通常就是創建一個snd_card結構體。

2. 聲卡的創建過程

snd_card_create // sound/core/init.c
    //創建聲卡的控制接口
    snd_ctl_create(card); // sound/core/control.c

//在聲卡注冊的時候會調用所有組件的dev_register回調來創建對應的設備節點:
snd_card_register(struct snd_card *card);//sound/core/init.c
    snd_device_register_all(card)
        list_for_each_entry(dev, &card->devices, list)
            dev->ops->dev_register(dev) //注冊所有的屬於此Card的設備節點
            //對應control節點
            snd_device_ops.dev_register = snd_ctl_dev_register,
                snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, &snd_ctl_f_ops, /*name=*/"controlC0")
            //對應pcm節點
            .dev_register =    snd_pcm_dev_register,
                 snd_register_device_for_dev(&snd_pcm_f_ops[0:p/1:c]);

聲卡設備/dev/snd/controlCX的file_operations是snd_ctl_f_ops //sound/core/control.c
聲卡設備/dev/snd/pcmCXDXp的file_operations是snd_pcm_f_ops[0], /dev/snd/pcmCXDXc的file_operations是snd_pcm_f_ops[1] //pcm_native.c

4. 一個pcm就是一個邏輯device,它里面有兩個通道,一個是playback通道,對應/dev/pcmC0D0p節點,另一個是capture通道,對應/dev/pcmC0D0c節點.

5. 創建聲卡的功能部件(邏輯設備),例如PCM,Mixer,MIDI等的函數如下

PCM —— snd_pcm_new()
    snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)
RAWMIDI —— snd_rawmidi_new()
    snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops)
CONTROL —— snd_ctl_create()
    snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
TIMER —— snd_timer_new()
    snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
INFO —— snd_card_proc_new()
    snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)
JACK —— snd_jack_new()
    snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);

 

參考:
Linux ALSA聲卡驅動之一:ALSA架構簡介:https://blog.csdn.net/DroidPhone/article/details/6271122
Linux ALSA聲卡驅動之二:聲卡的創建:https://blog.csdn.net/droidphone/article/details/6289712
Linux ALSA聲卡驅動之三:PCM設備的創建:https://blog.csdn.net/droidphone/article/details/6308006
Linux ALSA聲卡驅動之四:Control設備的創建 :https://blog.csdn.net/gjy938815/article/details/9209457

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM