0%

1. 函数指针

函数指针就是指向函数地址的指针

1
2
3
4
5
6
7
8
9
10
int Sum(int a, int b) {
return a + b;
}

typedef int(*SumFunc)(int x, int y);

// --------

SumFunc sum = Sum;
std::cout << sum(1, 2) << std::endl;

2. 函数对象

重载了 operator() 的类对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SumClass {
public:
SumClass(int padding): padding(padding){}

int operator()(int a, int b) {
return a + b + padding;
}

private:
int padding;
};

// ---------------------

SumClass sumObj(3);
std::cout << sumObj(1, 2) << std::endl;
Read more »

本系列的 第一篇 中介绍到了 AudioUnit 中和系统硬件交互的 IO Unit, 以及如何使用它进行音频的采集和播放. 本文是该系列的第二篇, 将会介绍 AudioUnit 中另外 四类 非常重要的 AudioUnit: MixingEffect UnitConverter Unit 以及 Generator Unit.

1. Mixing Unit

Mixing unit 在实际场景中非常的实用, 特别我们需要对多路音频做处理或者播放. 比如对于音频制作 app 来做, 通常要支持混入 N 多种乐器的声音和片段, 比如 吉他、钢琴、贝斯、人声、和声等等. 这个时候使用 Mixing unit 把这些 input bus 混成一路 output 交给 IO Unit 播放, 就是一个很必要且自然的结果.

Mixing Unit 是一个种类, 苹果内部提供了三个子类型:

1
2
3
4
5
CF_ENUM(UInt32) {
kAudioUnitSubType_MultiChannelMixing = 'mcmx',
kAudioUnitSubType_MatrixMixing = 'mxmx',
kAudioUnitSubType_SpatialMixing = '3dem',
};

1.1 MultiChannelMixing

MultiChannelMixing 是一个 多输入、单输出 的结构, 特点是:

  1. 支持任意多的 input bus, 每个 input 都可以有任意多的 channel(声道) 数
  2. 只有一路输出 ouput bus, 这一路 output bus 也可以有任意多的 channel 数

把这些 input bus 的声音混和, 从 output bus 输出, 每一路 input bus 可以独立设置数据源、音频格式、音量、mute 等, 这个是 Mixing 通用特点, 下同.

下面我们看一下它的结构, 相比 IO Unit 这个理解起来就比较简单了.

MixingNode

MultilChannelMixing 是 多输入、单输出 的结构, 可以自由配置 input bus 的数量, 配置完之后, 一个配置为 N 输入的 bus number 从 0 开始 到 N-1. Output bus 的个数只有一个, bus number 固定为 0.

每个 input bus 可以设置独立的 RenderCallback 或者连接前序的 AudioUnit 提供数据, 可以设置独立的音频格式参数, 以及控制当前 input 的音量和 mute 状态等等.

Read more »

Apple 平台上如果涉及到音频采集, 很难避开 AudioUnit 这个工具库, AudioUnit 是 Audio Toolbox 下的一套有年头的 C API, 功能相对也比较强大, 虽然苹果最近几年推出并逐渐在其基础之后完善了一套 AVAudioUnit 的 OC/Swift 的 API, 但 AudioUnit 依然有很广泛的使用, 而且了解这套 C API 也对理解 AVAudioUnit 内部的实现和使用有很大的帮助.

其实里面的概念并不是特别复杂, 但是因为文档比较老旧, 概念也比较绕, 上手并不易. 我此前做唱歌和直播 app 相关的工作, 对 AudioUnit 使用的也比较多, 积累了一些经验, 希望能够最大程度地把一些通用的概念和使用方法分享出来. 接下来将带大家剖析 AudioUnit 的内部原理和丰富多样的使用方式, 如果你在做涉及到声音采集和处理的工作, 希望能带大家深入浅出地摸透 AudioUnit.

关于 AudioUnit 的文章是一个系列, 我希望能够把之前的经验结合一些实际的场景来介绍, 大概分为一下四个部分:

  1. 熟悉 IO Unit 结构和运行机制, 使用它来进行录制和播放
  2. 熟悉其他类型的 AudioUnit, 比如 Mixer, Effect, Converter 等
  3. 使用 AUGraph 串联起来 AudioUnit, 以及常用的使用模式
  4. 熟悉使用 AVAudioUnit 进行音频采集和播放

本文中我们先来看第一部分.

1. AudioUnit 介绍

如下图, 可见 iOS 上所有的音频基础都是基于 AudioUnit 的, 比如 AudioToolbox、Media Player, AV Foundation 等都是在 AudioUnit 上做的封装. AudioUnit 本身处理效率非常高, 实时性也很强, 支持 VoIP 常见下进行回声消除、降噪等处理.

Image

Read more »

1. 函数指针

函数指针就是指向函数地址的指针

1
2
3
4
5
6
7
8
9
10
int Sum(int a, int b) {
return a + b;
}

typedef int(*SumFunc)(int x, int y);

// --------

SumFunc sum = Sum;
std::cout << sum(1, 2) << std::endl;

2. 函数对象

重载了 operator() 的类对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class SumClass {
public:
SumClass(int padding): padding(padding){}

int operator()(int a, int b) {
return a + b + padding;
}

private:
int padding;
};

// ---------------------

SumClass sumObj(3);
std::cout << sumObj(1, 2) << std::endl;
Read more »

低延迟编码对于很多视频app来说都很重要,特别是对实时音视频场景。苹果在 WWDC 2021 在 VideoToolbox 里推出了一种新的低延迟编码模式。低延迟编码模式的主要目的是为实时通讯场景优化现有的编码流程。

低延迟视频编码有以下的特点,从而对一个实时视频通讯app进行优化。

  1. 处理效率高,最小化端到端的延迟
  2. 新增两种 profile: CBP & CHP,增强互操作性
  3. 引入时域伸缩编码(Temporal Scalability),当会话中有多个参与者的时候,提供高效的编码流程
  4. 支持设置最大帧量化参数(Max Frame QP),展示最好的视频质量
  5. 引入长期参考帧 LTR,提供一个可靠的机制从网络丢包错误中恢复通讯

1.低延迟视频编码一览

下图是苹果平台上视频编码管线的简图:

Image

Read more »

REF: WWDC 2021 - Evaluate videos whith the Advanced Video Quality Tool

AVQTAdvanced Video Quality Tool 的缩写,是苹果在 WWDC 21 上推出的一款评估视频感知质量的工具。


一、背景介绍(非WWDC内容)

1.1 视频质量评估的现状

在正式开始之前,我想跟大家科普几个概念和行业现状,这些对理解本次的内容很有帮助。

视频质量评估是个老话题了,主流的分为下面几类:

  1. 主观评测,也就是人工评估,准确率高,但成本大,难规模化
  2. 客观评测,纯依靠算法,比如PSNR(Peak Signal-to-Noise Ratio峰值信噪比),SSIM(Structural SIMilarity 结构相似性),准确率低,成本小,容易规模化
  3. 感知质量评测,代表是Netflix 的VMAF,VMAF 是基于机器学习算法,根据人工的识别结果训练模型,目的是要模拟真人评测,结果上达到接近人工评估的准确度,这也是“感知”一词的含义。优点是准确率高,也容易规模化。我们今天要聊的 AVQT 也属于此类。

还有一种分类是有源评估无源评估,有源评估顾名思义,需要有参考源,比如有一个未压缩的超清Raw视频,它作为参考源,然后在进行处理编码之后,变成一个低分辨率、低码率的的视频,这个作为评估的对象,对比参考源视频,打出分数。感知质量评测的工具都属于有源评估范畴,即需要参考源来进行评估打分。

Read more »

Xcode Cloud 是什么?

Xcode Cloud 是一个搭建在苹果的开发工具链之上的 CI/CD 系统,和苹果的 Xcode、TestFlight 以及 App Store Connect 整个开发工具和生态进行打通。Xcode Cloud 使用 Git 作为项目的代码管理工具,通过 CI/CD,帮助开发者打造更高质量、更稳定的 app。从 Xcode 13 版本开始支持,目前在 beta 阶段,免费限量内测申请,2022年对所有人开放,具体价格待公布。

Xcode Cloud 能做什么?

  1. 自动构建和运行测试
  2. 自动在模拟器里运行测试程序
  3. 接收 Xcode Cloud 返回的构建结果通知,提前发现问题
  4. 通过 TestFlight 分发新版本给测试用户
  5. 创建供苹果审核的新版本
  6. 使用 Xcode 和苹果的云基础设施协同开发
Read more »

什么是 Karabiner-Elements ?

Karabiner-Elements (下面我们简称为Karabiner)官网对自己的描述是 “A powerful and stable keyboard customizer for macOS.”,我使用下来的感受是 Karabiner-Elements 是 macOS 平台上一款非常强大的键位映射工具,没有吹嘘的成分,买家秀和卖家秀是一样的。

这个介绍我会分为两个部分:

  • part1 介绍 Karabiner 的核心功能,以及我自己使用 Karabiner 帮助我高效使用键盘的一个思路,不涉及具体的配置
  • part2 根据实例详细介绍使用 Karabiner 高级映射的配置和高级用法,满足一些高级自定义的需求

下面我尽量使用通俗易懂的语言来表达,简单来划分 Karabiner 核心功能的话,Karabiner 可以分为 简单修改Simple modifications) 和 复杂修改Complex modifications),我更倾向于称之为 简单映射高级映射

Read more »

avformat_find_stream_info() 函数的作用

先来看一下 avformat_find_stream_info() 的头文件里的注释对该函数的介绍,本文我们基于 FFmpeg n4.2 版本的源码分析。

1
2
3
4
5
6
7
8
9
10
/**
* Read packets of a media file to get stream information. This
* is useful for file formats with no headers such as MPEG. This
* function also computes the real framerate in case of MPEG-2 repeat
* frame mode.
* The logical file position is not changed by this function;
* examined packets may be buffered for later processing.
* ...
*/
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

注释里说这个方法通过读取媒体文件中若干个 packet 来获取流信息,对于 MPEG 这种没有 header 的文件格式比较有用,也可以计算像 MPEG-2 这种支持 repeat mode 的真实帧率。(MPEG-2 支持对于大量静止的画面设置 repeat mode,重复的帧不用编码和存储,可以减少体积)

Read more »

作为程序员,和命令行打交道很频繁,设置一个赏心悦目的命行行 prompt 或者 Vim 的 status line 主题就很有必要了,不过一般这些漂亮的主题都会用到一些 icon 字符,这些 icon 字符一般的字体里是没有的,今天我们就来聊聊一些带有 icon 字符的字体。

为了有个直观的认识,我们来看一下设置命令行 prompt 特殊主题前后的对比:
prompt_theme

Read more »