前言

本篇是依据内核扩展理论的学习,首要结构运用IOAudioFamily。此部分现已被苹果抛弃,在新的macOS中现已正常情况现已无法运用。最新系统音频的驱动的开发运用AudioDriverKit,这个是dext系统扩展的形式,这里藏着后续学习。可是音频驱动的原理基本没变,所以曾经内核扩展的理论还是值得学习。

一、数字音频和PCM

咱们目前一切电子设备听到的声音本质上都是由数字信号模仿的。所以听到的声波便是由数字信号进行模仿的,由核算机系统进行存储和保护。数字音频的中的音频数据首要是经过PCM(Pulse Code Modulation, 脉冲编码调制 )从模仿声波信号中获取到的。PCM以固定时刻间隔对模仿声波进行采样和丈量,每秒的丈量数就称为采样率。例如你或许看到44.1kHz 、48kHz 相似的参数,这个便是指每秒采样的次数(采样率),48kHz 意味着每秒进行48000次声波信号丈量。每次丈量称为采样。采样是丈量声波信号的振幅,然后量化为具体的数字标度,该标度规模称为位深度或采样深度。比方目前很多采样位深度是16位,那么每次采样的或许值规模便是 -32768 ~ 32767.采样率和采样宽度越高,表明声波信号丈量越精确。

  • PCM的采样数据依据通道数进行交错存储。例如2通道的采样,一对左/右便是一个采样组,每个采样都是16位(意味着每个采样占2字节存储)。如果有8个通道(如HDMI)则每个采样组便是(1~8)。大部分数字音频系统都是要求这样的音频数据。硬件播映的时候也要以这种数据方法,如果是MP3这种紧缩了的音频数据,在硬件播映前也要进行解压还原成前面的数据格局。
  • PCM采样数据存储核算。例如44.1kHz的采样率,2通道,这就代表着每秒44100个采样组,采样深度是16位,那么每秒的数据量就为44100X(16/8)X2 = 176400字节。采样深度还或许是 8、20、24或32 。别的采样存储可所以无符号数或有符号数,还有或许是浮点数(Core Audio便是运用32位浮点)。常用PCM格局如下图:

MacOS 音频驱动开发一:理论篇(内核扩展)

二、音频设备音频驱动

音频设备音频驱动中心概率采样缓存区:采样缓存区一般是驱动程序分配的一个内存空间,用来存储PCM采样数据。关于音频播映(输出),音频播映设备会接连直接访问(DMA)该缓存区而不需要CPU调度,而且按照固定时刻间隔发送中止,使驱动程序知道当时设备读取的方位。这是十分必要的,能够保证新生成的音频数据能够写入到正确方位,而且不需要和设备进行交互。一段时刻后,设备播映了一些采样数据,驱动程序会删除现已播映的采样数据,这时如果没有新的数据写入设备就会坚持静音。音频输入就恰好相反,音频设备将采样数据写入缓存区,一起会发出一个中止,这样驱动程序能够知道正确的数据读取方位。一些音频设备也能够有多个输入输出,每个输入输出都会有自己独立的采样缓存区。

三、Core Audio和HAL

Core Audio:这个是macOS处理音频的一个最重要结构,需要独自一篇学习。本篇首要针对内核扩展学习,core audio首要是用于用户空间应用程序处理音频相关。

MacOS 音频驱动开发一:理论篇(内核扩展)
core audio是音频HAL(hardware abstraction layer,硬件笼统层)的中心。 HAL像是一个中间层,把Core Audio内部的framework,应用程序,音频设备,驱动程序连接起来。

  • 曾经 OS9,曾经应用程序能够直接写入驱动程序采样缓存区中,因而在这曾经只能处理单个应用程序的音频输出。
  • 当下 OSX和iOS,有了HAL,应用程序不能直接和驱动程序进行交互,而是和HAL进行交互(首要也便是和Core Audio进行交互),Core Audio会把一切的应用程序和多线程的音频放入一个缓存区,应用程序能够挑选任意HAL支撑的音频格局存储,Core Audio会先把缓存区数据转换为32位浮点格局的数据,然后交给驱动程序,驱动程序担任将32位浮点格局数据转换为音频硬件支撑的格局进行播映。音频输入也是如此
  • Core Audio中包括一些十分重要的结构:
    • Audio Toolbox
    • Audio Unit

四、I/O Kit音频支撑

在内核中首要是IOAudioFamily处理音频(经过此内核扩展的形式苹果现已不支撑)。咱们开发内核扩展音频驱动首要便是用它。概念及功用相对比较简单。首要是和硬件进行数据传输,以及一些基本功用,例如静音,操控音量及其他可装备的属性。下图为IOAudioFamily的结构,其中IOAudioDevice,IOAudioEngine比较重要。

MacOS 音频驱动开发一:理论篇(内核扩展)

  • IOAudioDevice: 它是音频驱动程序的功用中心,和硬件的交互功用一般都放在这里,比方条件音量,初始化硬件设备等。它不担任音频数据I/O(这个由 IOAudioEngine担任)
  • IOAudioEngine:音频驱动程序首要完成I/O部分(也是首要运用DMA的部分)。一个音频或许存在多个独立输入和输出。IOAudioEngine至少分配一个IOAudioStream。这是一个笼统类。
  • IOAudioStream:表明采样缓存区。采样缓冲区有一个与其相关的方向,可所以输人或输出。IOAudiostream还包括描述它所支撑格局的元数据,如采样的数宇格局、采样率、支撑的通道数。该类并不是笼统的,能够直接实例化。该类不为采样缓存区自身分配内存,有必要奉告它缓冲区的方位。它担任将采样缓冲区提供给用户空间用户。该音频流还保护一个内部混合缓冲区,将多个源的音频混合成一个流.
  • IOAudioControl:表明设备的可调参数,如输人音量、输出音量和静音。IOAudioControl类无法直接运用,但能够将其子类化,创建自定义的操控。IOAudioControl的3个子类为IOAudiolevelControlIOAudioselectorControl 和IOAudioTogg1eControl。一个操控或许归于设备自身、引擎或IOAudioPort.
  • IOAudioPort:表明逻辑端口或物理端口,如音频输出或耳麦输出。并不要求音频驱动程序运用该类。
  • Core Audio结构经过IOAudioEngineUserClient与 IOAudioEngine进行通讯,从而能够与引擎 的采样缓冲区交互,以播映或捕获音频。
  • IOAudiocontrolUserClient作为IOAudiocontrol实例的用户客户端,能够进行操作。这是 应用程序(如System Preferences)操控音量或静音的方法。