• IOS音频架构之Audio Unit


            在前面的章节部分我们已经对IOS音频结构有了一个清晰的认识,知道Audio Unit是位于整个音频结构的最底层,这一层非常多API已经開始和硬件打交道了。所以比較复杂,有了前面的基础再来看这个部分就比較的easy了。

    先来看看Audio Unit的结构图:

    结构图非常easy了。就不做过多的描写叙述了。

    重点说下中间那部分DSP。由于曾经读研的时候学的是DSP嵌入式驱动开发算法移植,所以对这部分比較熟悉。就和大家摆摆龙门阵。DSP全名是digital signal processing 数字信号处理。

    音频信号经过设备採样之后都变成了数字信号。所以採用专门的信号处理芯片来处理效率会非常的高。DSP是个大家族,常见的有TI公司,AD公司。每一个公司下有非常多系列。每一个系列下又有非常多种类。这是一个专门的学科,假设大家有兴趣能够花点时间研究研究,这里就不说了。

    以下我们还是来看看从软件层面上怎样使用这个东东:

    (1)Audio Unit 初始化參数设置

    这里能够设置音频流的各种參数,比方採样频率、量化位数、通道个数、每包中帧的个数等等。

    status=AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat,

                                    kAudioUnitScope_Input,

                                    kOutputBus, &audioFormat, sizeof(audioFormat));

    这里是为了设置音频回调方法。我们在这个回调方法中。将全部的须要播放的音频信号一帧帧传递给硬件设备。

        status=AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback,

                                    kAudioUnitScope_Global, kOutputBus, &callbackStruct, sizeof(callbackStruct));

    这里又多出一个属性设置。我们对Audio Session属性设置,能够设置硬件DSP每次处理音频数据的最小个数。音频处理周期越短。CPU使用越多。可是优点是音频时间间隔较短。用于音视频同步都是很有优点的。

    AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration,

                                                sizeof(preferredBufferSize),

                                                &preferredBufferSize)

    最后启动Aduio Unit

        status=AudioUnitInitialize(audioUnit);

         (2)音频数据解析

    音频设备我们已经初始化好了。以下我们就来看看怎么吧音频数据拿到。能够分两个部分。ffmpeg部分,以及AudioFile IOS处理两个方面。

    FFmpeg我们会专门拿出几个部分。在IOS架构音视频专栏中具体解说。我们先来看看用AduioFile怎么吧数据拿出来。

           事实上使用起来很easy:

    result=AudioFileReadPackets(audioFile, false, &numBytesRead, NULL, 0, &packetReads, audioData);

    使用这种方法就能够吧音频数据解析出来。数据都放在audioData中。

    (3)回调方法中处理音频数据

    在ffmpeg中音频数据装载比較复杂,音频ffmpeg音频处理是以包为单位来进行处理。所以处理的音频数据不一定满足,或者说是大部分情况都不满足DSP对音频数据长度处理的需求。所以这里就要在逻辑上作一定的转换。

    具体请參阅专栏中FFmpeg部分。这里看看我们读取本地文件怎样处理的:

    static OSStatus playbackCallback(void *inRefCon,AudioUnitRenderActionFlags *ioActionFlags,

                                      const AudioTimeStamp *inTimeStamp,

                                      UInt32 inBusNumber,

                                      UInt32 inNumberFrames,

                                      AudioBufferList *ioData){

        记得我们上面已经把音频数据拿到audioData中。(在读取之前包的大小设定为DSP音频处理数据长度),所以每次取一包数据放到ioData中。

    }

    另外另一点须要补充,这里硬件处理音频数据的长度必须是2的N次方。为啥呢?由于DSP在处理一些如:FFT、蝶形运算时。必须是以2为基的。(假设不太明确。相见 数字信号处理这本书)。所以我们长见到的数据长度多为512、1024、2048、4096、8192等.


  • 相关阅读:
    drf项目部署到腾讯云
    ruby的DIR.pwd
    ruby+selenium-webdriver测试
    ruby
    ruby类对象和对象
    ruby的实例变量
    ruby在类中访问@,类外访问调用方法
    ruby中=>是什么意思
    ruby
    css content属性
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6937668.html
Copyright © 2020-2023  润新知