В этом примере показано, как декодировать амбизоническое аудио в бинауральное аудио с помощью виртуальных громкоговорителей. Виртуальный громкоговоритель является источником звука, расположенным на поверхности сферы, при этом прослушиватель расположен в центре сферы. Каждый виртуальный громкоговоритель имеет связанную с ним пару связанных с головой передаточных функций (HRTF): один для левого уха и один для правого уха. Виртуальные местоположения громкоговорителя вместе с амбизоническим порядком используются для вычисления матрицы амбизонического декодера. Выходы декодера фильтруются HRTF, соответствующими положению виртуального громкоговорителя. Сигналы от левых HRTF суммируются и подаются на левое ухо. Сигналы от правых HRTF суммируются и подаются на правое ухо. Здесь показан блок схема аудио потока сигналов.
ARIDataset = load('ReferenceHRTF.mat');
Получите данные HRTF в необходимой размерности: [NumOfSourceMeasurements x 2 x LengthOfSamples]
hrtfData = ARIDataset.hrtfData; sourcePosition = ARIDataset.sourcePosition(:,[1,2]);
Базы данных HRTF ARI, используемые в этом примере, основаны на работе Исследовательского института акустики. Данные HRTF и исходное положение в ReferenceHRTF.mat
являются от ARI NH2 субъекта.
Базы данных HRTF Acoustics Research Institute, Austrian Academy of Sciences имеют лицензию Creative Commons Attribution-ShareAlike 3.0 Unported License: https://creativecommons.org/licenses/by-sa/3.0/.
Теперь, когда HRTF Dataset загружен, определите, какие точки выбрать для виртуальных громкоговорителей. В этом примере выбираются случайные точки, распределенные на поверхности сферы, и выбираются точки набора данных HRTF, ближайшие к выбранным точкам.
Выберите случайные точки из сферического распределения
Сравнение сферы с точками из набора данных HRTF
Выберите точки с самым коротким расстоянием между ними
% Create a sphere with a distribution of points nPoints = 24; % number of points to pick rng(0); % seed randcom number generator sphereAZ = 360*rand(1,nPoints); sphereEL = rad2deg(acos(2*rand(1,nPoints)-1))-90; pickedSphere = [sphereAZ' sphereEL']; % Compare distributed points on the sphere to points from the HRTF dataset pick = zeros(1, nPoints); d = zeros(size(pickedSphere,1), size(sourcePosition,1)); for ii = 1:size(pickedSphere,1) for jj = 1:size(sourcePosition,1) % Calculate arc length d(ii,jj) = acos( ... sind(pickedSphere(ii,2))*sind(sourcePosition(jj,2)) + ... cosd(pickedSphere(ii,2))*cosd(sourcePosition(jj,2)) * ... cosd(pickedSphere(ii,1) - sourcePosition(jj,1))); end [~,Idx] = sort(d(ii,:)); % Sort points pick(ii) = Idx(1); % Pick the closest point end
Задайте желаемый амбизонический порядок и желаемые положения источников виртуальных громкоговорителей в качестве входов к audioexample.ambisonics.ambidecodemtrx
вспомогательная функция. Функция возвращает матрицу декодера ambisonics.
order = 7; devices = sourcePosition(pick,:)'; dmtrx = audioexample.ambisonics.ambidecodemtrx(order, devices);
Создайте массив конечных импульсных характеристик для выполнения бинауральной фильтрации HRTF на основе положения виртуальных громкоговорителей.
FIR = cell(size(pickedSphere)); for ii = 1:length(pick) FIR{ii,1} = dsp.FrequencyDomainFIRFilter(hrtfData(:,pick(ii),1)'); FIR{ii,2} = dsp.FrequencyDomainFIRFilter(hrtfData(:,pick(ii),2)'); end
Загрузите ambisonic audio файла звука вертолета и преобразуйте его в 48 кГц для совместимости с набором данных HRTF. Задайте амбизонический формат аудио файла.
Создайте аудио файла, дискретизированный с частотой 48 кГц для совместимости с набором данных HRTF.
desiredFs = 48e3; [audio,fs] = audioread('Heli_16ch_ACN_SN3D.wav'); audio = resample(audio,desiredFs,fs); audiowrite('Heli_16ch_ACN_SN3D_48.wav',audio,desiredFs);
Задайте амбизонический формат аудио файла. Настройте объекты вход и audio output.
format = 'acn-sn3d'; samplesPerFrame = 2048; fileReader = dsp.AudioFileReader('Heli_16ch_ACN_SN3D_48.wav', ... 'SamplesPerFrame',samplesPerFrame); deviceWriter = audioDeviceWriter('SampleRate',desiredFs); audioFiltered = zeros(samplesPerFrame,size(FIR,1),2);
while ~isDone(fileReader) audioAmbi = fileReader(); audioDecoded = audioexample.ambisonics.ambidecode(audioAmbi, dmtrx, format); for ii = 1:size(FIR,1) audioFiltered(:,ii,1) = step(FIR{ii,1}, audioDecoded(:,ii)); % Left audioFiltered(:,ii,2) = step(FIR{ii,2}, audioDecoded(:,ii)); % Right end audioOut = 10*squeeze(sum(audioFiltered,2)); % Sum at each ear numUnderrun = deviceWriter(audioOut); end % Release resources release(fileReader) release(deviceWriter)
Пример генерации плагинов Ambisonic
[1] Kronlachner, M. (2014). Пространственные преобразования для изменения амбизонических записей (магистерская диссертация).
[2] Нуистерниг, Маркус. и др. A 3D Ambisonic Based Binaural Sound Reproduction System (неопр.) (недоступная ссылка). Представлено на 24-й Международной конференции AES: Multicannel Audio, The New Reality, Альберта, июнь 2003 года.