主要内容

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

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

在典型的虚拟现实设置中,IMU传感器连接到用户的耳机或VR耳机,使得声源的感知位置相对于无关的视觉提示。例如,如果声音被视为来自监视器的声音,即使用户将头部转向侧面,它也保持这种方式。

所需的硬件

  • Arduino Uno

  • Invensense微处理器- 9250

硬件连接

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

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

创建一个arduino.对象。

a = arduino;

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

imu = mpu9250(一个);

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

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

加载ARI HRTF数据集

当声音从空间点到耳朵的点行进时,您可以根据腔室时间和级别差异(ITD和ILD)本地化它。这些频率相关的ITD和ILD可以测量并表示为任何给定的源极高和方位角的一对脉冲响应。ARI HRTF数据集包含1550对脉冲响应,其跨越360度超过-30至80度的方位角跨越方位角。您使用这些脉冲响应来过滤声源,以便从传感器方向确定的位置被感知。如果传感器连接到用户头上的装置,则声音被认为是从一个固定的地方感到被认为尽管有头部运动。

首先,加载HRTF数据集。

ARIDataset =负载('roidhrtf.mat');

然后,从数据集获取相关的HRTF数据,并将其以有用的格式用于我们的处理。

hrtfdata = double(aridataset.hrtfdata);hrtfdata = erfute(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');heli = 12 * heli(:,1);%只保留一个通道sampleRate = 48 e3;直升机=重新取样(直升机、sampleRate originalSampleRate);

将音频数据加载到赋予源对象。设置SamplesPerframe.0.1秒。

sigsrc = dsp。赋予源(heli,...“SamplesPerFrame”sampleRate / 10...'seriperencaction''循环重复');

设置音频设备

创建一个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 = zeros(sigsrc.samplesperframe,2);t尽管toc < 30%从IMU传感器读取。[数据,overrun] =读取(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 ();%申请HRTFS.audiofiltered(:,1)= FIR {1}(AudioIn,InterpolateIr(1,:));%左audioFiltered(:,2) = FIR{2}(audioIn, interpolatedIR(2,:)));%对吧audioUnderruns = audioUnderruns + deviceWriter(挤压(音频过滤));结束

清理

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

发布(sigsrc)发布(deviceWriter)清晰IMU.一个