Бинауральный рендеринг аудио Используя расположение виртуальной камеры внутри сцены

Отследите главную ориентацию путем объединения данных, полученных от IMU, и затем управляйте направлением прибытия источника звука путем применения функций моделирования восприятия звука (HRTF).

В типичной настройке виртуальной реальности датчик IMU присоединен к наушникам пользователя или гарнитуре VR так, чтобы воспринятое положение источника звука было относительно визуальной подсказки, независимой от главных перемещений. Например, если звук воспринят как прибывающий из монитора, это остается тот путь, даже если пользователь поворачивает голову стороне.

Необходимое оборудование

  • Uno Arduino

  • Invensense MPU-9250

Аппаратная связь

Во-первых, соедините Invensense MPU-9250 с платой Arduino. Для получения дополнительной информации смотрите, что Оценка Ориентации Использует Инерционное Cочетание датчиков и MPU-9250.

Создайте объект датчика и фильтр IMU

Создайте arduino объект.

a = arduino;

Создайте объект датчика Invensense MPU-9250.

imu = mpu9250(a);

Создайте и установите частоту дискретизации Фильтра Калмана.

Fs = imu.SampleRate;
imufilt = imufilter('SampleRate',Fs);

Загрузите набор данных АРИ HRTF

Когда звук перемещается от точки в пространстве до ваших ушей, можно локализовать его на основе межслухового времени и различий в уровне (ITD и ILD). Они зависимый частотой ITD и ILD's могут быть измерены и представлены как пара импульсных характеристик для любого данного исходного вертикального изменения и азимута. Набор данных АРИ HRTF содержит 1 550 пар импульсных характеристик, которые охватывают азимуты более чем 360 градусов и вертикальные изменения от-30 до 80 градусов. Вы используете эти импульсные характеристики, чтобы отфильтровать источник звука так, чтобы он был воспринят как прибывающий из положения, определенного ориентацией датчика. Если датчик присоединен к устройству на голове пользователя, звук воспринят как прибывающий из одного фиксированного места несмотря на главные перемещения.

Во-первых, загрузите набор данных HRTF.

ARIDataset = load('ReferenceHRTF.mat');

Затем получите соответствующие данные HRTF из набора данных и поместите его в полезный формат для нашей обработки.

hrtfData = double(ARIDataset.hrtfData);
hrtfData = permute(hrtfData,[2,3,1]);

Получите связанные исходные положения. Углы должны быть в той же области значений как датчик. Преобразуйте азимуты от [0,360] до [-180 180].

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

Загрузите монофоническую запись

Загрузите запись ambisonic вертолета. Сохраните только первый канал, который соответствует всенаправленной записи. Передискретизируйте его к 48 кГц для совместимости с набором данных HRTF.

[heli,originalSampleRate] = audioread('Heli_16ch_ACN_SN3D.wav');
heli = 12*heli(:,1); % keep only one channel

sampleRate = 48e3;
heli = resample(heli,sampleRate,originalSampleRate);

Загрузите аудиоданные в SignalSource объект. Установите SamplesPerFrame к 0.1 секунды.

sigsrc = dsp.SignalSource(heli, ...
    'SamplesPerFrame',sampleRate/10, ...
    'SignalEndAction','Cyclic repetition');

Настройте аудио устройство

Создайте audioDeviceWriter с той же частотой дискретизации как звуковой сигнал.

deviceWriter = audioDeviceWriter('SampleRate',sampleRate);

Создайте КИХ-Фильтры для коэффициентов HRTF

Создайте пару КИХ-фильтров, чтобы выполнить бинауральную фильтрацию HRTF.

FIR = cell(1,2);
FIR{1} = dsp.FIRFilter('NumeratorSource','Input port');
FIR{2} = dsp.FIRFilter('NumeratorSource','Input port');

Инициализируйте средство просмотра ориентации

Создайте объект выполнить визуализацию в реальном времени для ориентации датчика IMU. Вызовите фильтр IMU однажды и отобразите начальную ориентацию.

orientationScope = HelperOrientationViewer;
data = read(imu);

qimu = imufilt(data.Acceleration,data.AngularVelocity);
orientationScope(qimu);

Цикл обработки аудиоданных

Выполните цикл обработки в течение 30 секунд. Этот цикл выполняет следующие шаги:

  1. Считайте данные из датчика IMU.

  2. Объедините данные о датчике IMU, чтобы оценить ориентацию датчика. Визуализируйте текущую ориентацию.

  3. Преобразуйте ориентацию от представления кватерниона до тангажа и рыскания в Углах Эйлера.

  4. Используйте interpolateHRTF получить пару HRTFs в желаемом положении.

  5. Считайте систему координат аудио из источника сигнала.

  6. Примените HRTFs к моно записи и проигрывайте сигнал стерео. Это лучше всего испытано с помощью наушников.

imuOverruns = 0;
audioUnderruns = 0;
audioFiltered = zeros(sigsrc.SamplesPerFrame,2);
tic
while toc < 30

    % Read from the IMU sensor.
    [data,overrun] = read(imu);
    if overrun > 0
        imuOverruns = imuOverruns + overrun;
    end
    
    % Fuse IMU sensor data to estimate the orientation of the sensor.
    qimu = imufilt(data.Acceleration,data.AngularVelocity); 
    orientationScope(qimu);
    
    % Convert the orientation from a quaternion representation to pitch and yaw in Euler angles.
    ypr = eulerd(qimu,'zyx','frame');
    yaw = ypr(end,1);
    pitch = ypr(end,2);
    desiredPosition = [yaw,pitch];
    
    % Obtain a pair of HRTFs at the desired position.
    interpolatedIR = squeeze(interpolateHRTF(hrtfData,sourcePosition,desiredPosition));
    
    % Read audio from file   
    audioIn = sigsrc();
             
    % Apply HRTFs
    audioFiltered(:,1) = FIR{1}(audioIn, interpolatedIR(1,:)); % Left
    audioFiltered(:,2) = FIR{2}(audioIn, interpolatedIR(2,:)); % Right    
    audioUnderruns = audioUnderruns + deviceWriter(squeeze(audioFiltered)); 
end

Очистка

Высвободите средства, включая звуковое устройство.

release(sigsrc)
release(deviceWriter)
clear imu a