主要内容

使用头部跟踪的双耳音频渲染

通过融合从IMU接收到的数据来跟踪头部方向,然后通过头部相关传递函数(HRTF)控制声源到达的方向。

在典型的虚拟现实设置中,IMU传感器被连接到用户的耳机或VR头戴式耳机上,因此,声源的感知位置相对于视觉线索,而不受头部运动的影响。例如,如果声音被认为是来自显示器,那么即使用户把头转向一边,它也会保持这种状态。

所需的硬件

  • Arduino Uno

  • Invensense微处理器- 9250

硬件连接

首先,将Invensense MPU-9250连接到Arduino板。有关详细信息,请参见利用惯性传感器融合和MPU-9250估计方向

创建传感器对象和IMU过滤器

创建一个arduino对象。

一个= arduino;

创建Invensense MPU-9250传感器对象。

imu = mpu9250(一个);

创建并设置卡尔曼滤波器的采样率。

Fs = imu.SampleRate;imufilt = imufilter (“SampleRate”Fs);

加载ARI HRTF数据集

当声音从空间中的某一点传到你的耳朵时,你可以根据耳际时间和水平差异(ITD和ILD)对其进行定位。这些频率相关的过渡段和ILD可以测量,并表示为任意给定源仰角和方位角的一对脉冲响应。ARI HRTF数据集包含1550对脉冲响应,它们跨越360度的方位角和从-30度到80度的仰角。你用这些脉冲响应来过滤一个声源,这样它就可以被感知到来自由传感器方向决定的位置。如果将传感器安装在用户头部的设备上,即使头部运动,声音也会被认为来自一个固定的地方。

首先,加载HRTF数据集。

ARIDataset =负载(“ReferenceHRTF.mat”);

然后,从数据集中获取相关的HRTF数据,并将其转换为用于处理的有用格式。

hrtfData =双(ARIDataset.hrtfData);hrtfData =排列(hrtfData[2、3、1]);

获取相关的源位置。角度应在与传感器相同的范围内。将方位角从[0,360]转换为[-180,180]。

sourcePosition = ARIDataset.sourcePosition (:, [1, 2]);sourcePosition(:,1) = sourcePosition(:,1) - 180;

负载单声道的记录

装上直升机的双音速录音。只保留第一个通道,它对应于一个全向记录。为与HRTF数据集兼容重新采样到48 kHz。

[直升机,originalSampleRate] = audioread (“Heli_16ch_ACN_SN3D.wav”);直升机= 12 *直升机(:1);只保留一个频道sampleRate = 48 e3;直升机=重新取样(直升机、sampleRate originalSampleRate);

将音频数据加载到SignalSource对象。设置SamplesPerFrame0.1秒。

sigsrc = dsp。SignalSource(heli,...“SamplesPerFrame”sampleRate / 10...“SignalEndAction”循环重复的);

设置音频设备

创建一个audioDeviceWriter采样率与音频信号相同。

deviceWriter = audioDeviceWriter (“SampleRate”, sampleRate);

为HRTF系数创建FIR滤波器

创建一对FIR滤波器来执行双耳HRTF滤波。

冷杉=细胞(1、2);冷杉{1}= dsp。FIRFilter (“NumeratorSource”输入端口的);冷杉{2}= dsp。FIRFilter (“NumeratorSource”输入端口的);

初始化方向查看器

创建一个对象来对IMU传感器的方向进行实时可视化。调用IMU过滤器一次并显示初始方向。

orientationScope = HelperOrientationViewer;data =阅读(imu);qimu = imufilt (data.Acceleration data.AngularVelocity);orientationScope (qimu);

音频处理循环

执行30秒的处理循环。这个循环执行以下步骤:

  1. 从IMU传感器读取数据。

  2. 融合IMU传感器数据来估计传感器的方向。可视化当前方向。

  3. 转换方向从四元数表示俯仰和偏航在欧拉角。

  4. 使用interpolateHRTF以获得所需位置上的一对hrtf。

  5. 从信号源读取一帧音频。

  6. 将hrtf应用于单声道录音并播放立体声信号。这是最好的体验使用耳机。

imuOverruns = 0;audioUnderruns = 0;audioFiltered = 0 (sigsrc.SamplesPerFrame, 2);抽搐toc < 30%从IMU传感器读取。(数据溢出)=阅读(imu);如果超支> 0 imuOverruns = imuOverruns +超支;结束融合IMU传感器数据来估计传感器的方向。qimu = imufilt (data.Acceleration data.AngularVelocity);orientationScope (qimu);%转换方向从四元数表示俯仰和偏航在欧拉角。ypr = eulerd (qimu,“zyx股票”“帧”);偏航= ypr(结束,1);距= ypr (, 2);desiredPosition =(偏航、俯仰);%在所需位置获取一对hrtf。interpolatedIR =挤压(interpolateHRTF (hrtfData, sourcePosition desiredPosition));从文件中读取音频audioIn = sigsrc ();%应用头audioFiltered(:,1) = FIR{1}(audioIn, interpolatedIR(1,:))); / / / / / / / / /%左audioFiltered(:,2) = FIR{2}(audioIn, interpolatedIR(2,:))); / /这个函数是对的%对吧audioUnderruns = audioUnderruns + deviceWriter(挤压(audifilter));结束

清理

释放资源,包括声音设备。

发布(sigsrc)发布(deviceWriter)清晰imu一个