zoukankan      html  css  js  c++  java
  • 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 //soundcoresound.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

  • 相关阅读:
    JZ5 替换空格
    数学分析 H 1 复习要点(部分)
    算法贪心
    Python之位运算
    sorted复杂排序cmp_to_key
    算法位运算
    Python3新特性总结 持续更新
    算法树
    H5 ios端微信浏览器下底部工具固定方法
    Eclipse 安装windows10环境
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10917545.html
Copyright © 2011-2022 走看看