环绕声编码/解码和双耳化库
libspatialaudio 是一个开源跨平台的C++库,用于环绕声编码和解码、滤波和双耳渲染。 它旨在多种环境中渲染高阶环绕声(HOA)和VR/3D音频样本,从耳机到传统扬声器。 其双耳渲染可用于经典的5.1/7.1空间声道以及环绕声输入。
最初它是Aristotel Digenis的ambisonic-lib的一个分支。这个版本的开发是为了支持高阶环绕声HOA,并支持遵循Google空间音频规范的ACN/SN3D环绕声音频流: https://github.com/google/spatial-media/blob/master/docs/spatial-audio-rfc.md 以及IETF编解码器环绕声规范 https://tools.ietf.org/html/draft-ietf-codec-ambisonics
该库允许您对3阶以内的HOA环绕声音频流进行编码、解码、旋转和缩放。它可以输出到标准和自定义扬声器阵列。为了通过耳机播放,双耳化器应用HRTF(可以是SOFA文件或包含的MIT HRTF)来提供空间双耳渲染效果。双耳化还可用于渲染多声道流(5.1、7.1等)。
库的核心部分是CBFormat对象,它作为B-Format的缓冲区。还有其他几个对象,每个都有特定任务,如环绕声的编码、解码和处理。所有这些对象在某个时候都会处理CBFormat对象。
特性
编码器(CAmbisonicEncoder):
简单的3D 3阶编码器,无距离提示。
带距离的编码器(CAmbisonicEncoderDist):
与简单编码器相同,但增加了以下功能:
- 距离级别模拟
- 分数延迟线
- 内部效果(W-平移)
解码器(CAmbisonicDecoder):
简单的3D 3阶解码器,具有:
- 预设和自定义扬声器阵列
- 改善5.1扬声器集渲染的解码器
处理器(CAmbisonicProcessor):
最高3阶3D偏航/滚动/俯仰音场
最高3阶心理声学优化架滤波器,用于2D和3D播放
双耳化器(CAmbisonicBinauralizer):
最高3阶3D解码到耳机
可选对称头部解码器以减少卷积次数
缩放器(CAmbisonicZoomer):
最高1阶3D前后主导控制音场
已实现算法概述
心理声学优化架滤波器
实现为线性相位FIR架滤波器,确保在低频和高频范围分别进行基本和最大rE解码。有关原因详见[1],高阶数学理论详见[2]。
两种解码器类型之间的过渡频率取决于被解码的阶数,随环绕声阶数增加而增加。
频率由[3]给出:
f_lim = 声速*M / (4*R*(M+1)*sin(PI / (2*M+2)))
其中声速 = 343 m/s,R = 0.09 m(大约是人头半径),M = 环绕声阶数。
2D: g_m = cos(pi*m/(2M + 2))
3D: g_m = legendre(m, cos(137.9*(PI/180)/(M+1.51)))
其中m = floor(sqrt(通道数)),legendre(m,x)是对x值求值的m阶勒让德多项式。
双耳解码
双耳解码器根据阶数使用两种不同的虚拟扬声器阵列:
- 1阶:立方体扬声器阵列
- 2阶和3阶:十二面体 为了将卷积次数保持在最小限度,头部相关传递函数(HRTF)被分解为球谐函数。这为每个Ambisonics通道提供了一对HRTF滤波器。 这种方法的优势在于,无论使用多少虚拟扬声器,卷积次数都仅限于Ambisonic通道的数量。
对称头部双耳解码器
双耳解码器可以将双耳解码所需的卷积次数减半。
Ambisonic输入通道与左耳对应的HRTF通道进行卷积。左耳信号是这些卷积通道的总和。为了生成右耳信号,通过将几个卷积通道乘以-1来实现声场的左右反射。然后将这些相加产生右耳信号。
如何使用它?
以下示例代码展示了将正弦波编码为Ambisonic声场,然后通过四声道扬声器设置解码该声场的过程。
// 生成单声道测试信号
float sinewave[512];
for(int ni = 0; ni < 512; ni++)
sinewave[ni] = (float)sin((ni / 128.f) * (M_PI * 2));
// CBFormat作为一阶3D,512个样本
CBFormat myBFormat;
// Ambisonic编码器,也是三阶3D
CAmbisonicEncoder myEncoder;
myEncoder.Configure(1, true, 0);
// 设置测试信号在声场中的位置
PolarPoint position;
position.fAzimuth = 0;
position.fElevation = 0;
position.fDistance = 5;
myEncoder.SetPosition(position);
myEncoder.Refresh();
// 将测试信号编码到BFormat缓冲区
myEncoder.Process(sinewave, 512, &myBFormat);
// Ambisonic解码器,也是一阶3D,用于5.0设置
CAmbisonicDecoder myDecoder;
myDecoder.Configure(1, true, kAmblib_50, 5);
// 为扬声器馈送分配缓冲区
float** ppfSpeakerFeeds = new float*[5];
for(int niSpeaker = 0; niSpeaker < 5; niSpeaker++)
ppfSpeakerFeeds[niSpeaker] = new float[512];
// 解码以获取扬声器馈送
myDecoder.Process(&myBFormat, 512, ppfSpeakerFeeds);
// 释放扬声器馈送缓冲区
for(int niSpeaker = 0; niSpeaker < 5; niSpeaker++)
delete [] ppfSpeakerFeeds[niSpeaker];
delete [] ppfSpeakerFeeds;
参考文献
[1] M. A. Gerzon, "实用全方位声:全球声音的再现,"音频工程师学会会议,1980年,第1-12页。
[2] J. Daniel, "声场表示,应用于多媒体环境中复杂声音场景的传输和再现,"巴黎大学,2000年。
[4] F. Zotter 和 M. Frank, "全方位Ambisonic平移和解码,"音频工程师学会杂志,第60卷,第10期,第807-820页,2012年。