通过融合从IMU接收的数据来跟踪头部方向,然后通过应用头部相关传递函数(HRTF)来控制声源的到达方向。
在典型的虚拟现实设置中,IMU传感器连接到用户的耳机或VR耳机上,以便声源的感知位置相对于独立于头部运动的视觉线索。例如,如果声音被感知到来自显示器,即使用户把头转向一侧,它也会保持这种方式。
Arduino Uno
Invensense微处理器- 9250
首先,将Invensense mcu -9250连接到Arduino板。详情请参见基于惯性传感器融合和MPU-9250的方向估计。
创建一个arduino
对象。
A = arduino;
创建Invensense mcu -9250传感器对象。
Imu = mpu9250(a);
创建并设置卡尔曼滤波器的采样率。
Fs = imu.SampleRate;Imufilt = imufilter(“SampleRate”Fs);
当声音从空间中的一点传播到你的耳朵时,你可以根据耳间时间和声级差(ITD和ILD)来定位它。这些频率相关的过渡段和间质间隙可以被测量并表示为一对脉冲响应,对于任何给定的源仰角和方位角。ARI HRTF数据集包含1550对脉冲响应,它们的方位跨度超过360度,海拔高度从-30度到80度。您使用这些脉冲响应来过滤声源,以便它被感知为来自由传感器方向决定的位置。如果将传感器连接到用户头上的设备上,尽管头部移动,声音仍被感知到来自一个固定的地方。
首先,加载HRTF数据集。
aridatset = load(“ReferenceHRTF.mat”);
然后,从数据集中获取相关的HRTF数据,并将其转换为便于我们处理的有用格式。
hrtfData = double(aridatset .hrtfData);hrtfData = permute(hrtfData,[2,3,1]);
获取相关的源位置。角度应与传感器在同一范围内。将方位角从[0,360]转换为[-180,180]。
sourcePosition = aridatset .sourcePosition(:,[1,2]);sourcePosition(:,1) = sourcePosition(:,1) - 180;
装上一架直升机的双音速录像。只保留第一个通道,它对应于全向录音。为了与HRTF数据集兼容,将其重新采样到48 kHz。
[heli,originalSampleRate] = audioread(“Heli_16ch_ACN_SN3D.wav”);直升机= 12*直升机(:,1);只保留一个频道sampleRate = 48e3;heli = resample(heli,sampleRate,originalSampleRate);
加载音频数据到SignalSource
对象。设置SamplesPerFrame
来0.1
秒。
Sigsrc = dsp。SignalSource(heli,...“SamplesPerFrame”sampleRate / 10...“SignalEndAction”,循环重复的);
创建一个audioDeviceWriter
用与音频信号相同的采样率。
deviceWriter = audioDeviceWriter(“SampleRate”, sampleRate);
创建一对FIR滤波器来执行双耳HRTF滤波。
FIR = cell(1,2);FIR{1} = dsp。FIRFilter (“NumeratorSource”,输入端口的);FIR{2} = dsp。FIRFilter (“NumeratorSource”,输入端口的);
创建一个对象以执行IMU传感器方向的实时可视化。调用一次IMU过滤器并显示初始方向。
orientationScope = HelperOrientationViewer;数据=读取(imu);qimu = imufilt(data.Acceleration,data.AngularVelocity);orientationScope (qimu);
执行处理循环30秒。这个循环执行以下步骤:
从IMU传感器读取数据。
融合IMU传感器数据,估计传感器方向。可视化当前的方向。
将方向从四元数表示转换为欧拉角的俯仰和偏航。
使用interpolateHRTF
以获得一对在所需位置的hrtf。
从信号源读取一帧音频。
应用hrtf到单声道录音并播放立体声信号。使用耳机是最好的体验。
imuOverruns = 0;audioUnderruns = 0;audioFiltered = 0 (sigsrc.SamplesPerFrame,2);抽搐而Toc < 30%从IMU传感器读取。[data, overflow] = read(imu);如果imuOverruns = imuOverruns +溢出;结束融合IMU传感器数据,估计传感器方向。qimu = imufilt(data.Acceleration,data.AngularVelocity);orientationScope (qimu);将方向从四元数表示转换为欧拉角的俯仰和偏航。Ypr =欧拉(齐木,“zyx股票”,“帧”);偏航= ypr(end,1);Pitch = ypr(end,2);desiredPosition =[偏航,俯仰];在需要的位置获得一对hrtf。interpolatedIR = squeeze(interpolateHRTF(hrtfData,sourcePosition,desiredPosition));从文件中读取音频audioIn = sigsrc();应用hrtfaudioFiltered(:,1) = FIR{1}(audioIn, interpolatedIR(1,:));%左audioFiltered(:,2) = FIR{2}(audioIn, interpolatedIR(2,:));%对吧audioUnderruns = audioUnderruns + deviceWriter(squeeze(audioFiltered));结束
释放资源,包括声音设备。
释放(sigsrc)释放(deviceWriter)清除imu一个