主要内容

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

通过融合从IMU接收的数据,然后通过应用头部相关传输函数(HRTF)来控制声源的到达方向进行轨道前导。

在典型的虚拟现实设置中,IMU传感器附加到用户的耳机或VR耳机,使得声源的感知位置与无关的视觉提示相对于头部运动。例如,如果声音被视为来自显示器的声音,即使用户将头部转向侧面,它也仍然这样。

需要硬件

  • Arduino Uno.

  • Invensense MPU-9250

硬件连接

首先,将Invensense MPU-9250连接到Arduino板。有关更多详细信息,请参阅使用惯性传感器融合和MPU-9250估算取向

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

创建一个arduino.目的。

a = arduino;

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

IMU = MPU9250(a);

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

fs = imu.samplerate;imufilt = imufilter('采样率',fs);

加载ARI HRTF数据集

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

首先,加载HRTF数据集。

ARIDATASET = LOAD('roidhrtf.mat');

然后,从DataSet获取相关的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;

负载单声道记录

加载直升机的舒大录制。仅保持第一通道,该通道对应于全向录制。将其重新示一为48 kHz以与HRTF数据集兼容。

[Heli,OriginalSamplerge] = audioread('heli_16ch_acn_sn3d.wav');heli = 12 * heli(:,1);%只保留一个频道Samplere = 48E3;Heli =重组(Heli,Sampleate,OricinalSamplerate);

将音频数据加载到一个submanceource.目的。设定SamplesPerframe.0.1秒。

sigsrc = dsp.signalsource(heli,......'samplesperframe',samplerge / 10,......'seriperencaction''循环重复');

设置音频设备

创建一个audiodevicewriter.具有与音频信号相同的采样率。

devicewriter = audiodevicewriter('采样率',采样率);

为HRTF系数创建FIR滤波器

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

FIR = CELL(1,2);fir {1} = dsp.firfilter('numeratorsource''输入端口');fir {2} = dsp.firfilter('numeratorsource''输入端口');

初始化方向查看器

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

RientationScope = HelperorientationViewer;数据=读取(IMU);qimu = imufilt(data.acceleration,data.angularvelocity);方向升(Qimu);

音频处理循环

执行处理循环30秒。此循环执行以下步骤:

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

  2. 熔断IMU传感器数据以估计传感器的方向。可视化当前方向。

  3. 将方向从四元数表示转换为欧伦角的音高和偏航。

  4. 采用Interpolatehrtf.在所需位置获得一对HRTF。

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

  6. 将HRTFS应用于单声道录制并播放立体声信号。这是使用耳机的最佳经验丰富。

imuoverruns = 0;Audiounderruns = 0;audiofiltered = zeros(sigsrc.samplesperframe,2);Tic.尽管toc <30%从IMU传感器读取。[数据,overrun] =读取(IMU);如果overrun> 0 imuoverruns = imuoverruns +超支;结尾%熔断IMU传感器数据以估计传感器的方向。qimu = imufilt(data.acceleration,data.angularvelocity);方向升(Qimu);%将四元数表示转换为沥青和偏航的圆形角度。ypr = eulerd(qimu,'Zyx''框架');yaw = ypr(结束,1);间距= ypr(结束,2);joordPosition = [偏航,音高];%在所需位置获得一对HRTF。Interpolatedir =挤压(InterpolateHrtf(HRTFDATA,SourcePosition,LoishPosition));%读取文件的音频AudioIn = Sigsrc();%申请HRTFS.audiofiltered(:,1)= FIR {1}(AudioIn,InterpolateIr(1,:));% 剩下audiofiltered(:,2)= FIR {2}(AudioIn,InterpolateIr(2,:));% 对audiounderruns = audiounderruns + devicewriter(挤压(audiofiltered));结尾

清理

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

释放(SIGSRC)释放(DeviceWriter)清除IMU.一种