This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

Ambisonic Binaural Decoding

This example shows how to decode ambisonic audio into binaural audio using virtual loudspeakers. A virtual loudspeaker is a sound source positioned on the surface of a sphere, with the listener located at the center of the sphere. Each virtual loudspeaker has a pair of Head-Related Transfer Functions (HRTF) associated with it: one for the left ear and one for the right ear. The virtual loudspeaker locations along with the ambisonic order are used to calculate the ambisonic decoder matrix. The output of the decoder is filtered by the HRTFs corresponding to the virtual loudspeaker position. The signals from the left HRTFs are summed together and fed to the left ear and the signals from the right HRTFs are summed together and fed to the right ear. A block diagram of the audio signal flow is shown here.

Load the ARI HRTF Dataset

ARIDataset = load('ReferenceHRTF.mat');
% Get the HRTF data in the required dimension of
% [NumOfSourceMeasurements x 2 x LengthOfSamples]
hrtfData = ARIDataset.hrtfData;
sourcePosition = ARIDataset.sourcePosition(:,[1,2]);

The ARI HRTF Databases used in this example is based on the work by Acoustics Research Institute The HRTF data and source position in ReferenceHRTF.mat are from ARI NH2 subject.

The HRTF Databases by Acoustics Research Institute, Austrian Academy of Sciences are licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License:

Select Points from ARI HRTF Dataset

Now that the HRTF Dataset is loaded, determine which points to pick for virtual loudspeakers. This example picks random points distributed on the surface of a sphere and selects the points of the HRTF dataset closest to the picked points.

  1. Pick random points from a spherical distribution

  2. Compare sphere to points from the HRTF dataset

  3. Pick the points with the shortest distance between them

% 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 i = 1:size(pickedSphere,1)
    for j = 1:size(sourcePosition,1)
        % Calculate arc length
        d(i,j) = acos( ...
            sind(pickedSphere(i,2))*sind(sourcePosition(j,2)) + ...
            cosd(pickedSphere(i,2))*cosd(sourcePosition(j,2)) * ...
            cosd(pickedSphere(i,1) - sourcePosition(j,1)));
    [~,Idx] = sort(d(i,:)); % Sort points
    pick(i) = Idx(1);       % Pick the closest point

Create Ambisonic Decoder

Specify a desired ambisonic order and desired virtual loudspeaker source positions as inputs to the audioexample.ambisonics.ambidecodemtrx helper function. The function returns an ambisonics decoder matrix.

order = 7;
devices = sourcePosition(pick,:)';
dmtrx = audioexample.ambisonics.ambidecodemtrx(order, devices);

Create HRTF Filters

Create an array of FIR filters to perform binaural HRTF filtering based on the position of the virtual loudspeakers.

FIR = cell(size(pickedSphere));
for i=1:length(pick)
    FIR{i,1} = dsp.FrequencyDomainFIRFilter(hrtfData(:,pick(i),1)');
    FIR{i,2} = dsp.FrequencyDomainFIRFilter(hrtfData(:,pick(i),2)');

Create Audio Input and Output Objects

Load the ambisonic audio file of helicopter sound. Specify the ambisonic format of the audio file.

Setup File Reader and Device Writer

fileName = fullfile(matlabroot, 'toolbox','audio','samples','Heli_16ch_ACN_SN3D.wav');
format = 'acn-sn3d';
samplesPerFrame = 2048;
fileReader = dsp.AudioFileReader(fileName, ...
                    'SamplesPerFrame', samplesPerFrame);
sampleRate = fileReader.SampleRate;
deviceWriter = audioDeviceWriter('SampleRate', sampleRate);
audioFiltered = zeros(samplesPerFrame, size(FIR,1), 2);

Process Audio

while ~isDone(fileReader)
    audioAmbi = fileReader();
    audioDecoded = audioexample.ambisonics.ambidecode(audioAmbi, dmtrx, format);
    for i=1:size(FIR,1)
        audioFiltered(:,i,1) = step(FIR{i,1}, audioDecoded(:,i)); % Left
        audioFiltered(:,i,2) = step(FIR{i,2}, audioDecoded(:,i)); % Right
    audioOut = 10*squeeze(sum(audioFiltered,2));   % Sum at each ear
    numUnderrun = deviceWriter(audioOut);

% Release resources

See Also

Ambisonic Plugin Generation Example


[1] Kronlachner, M. (2014). Spatial Transformations for the Alteration of Ambisonic Recordings (Master's thesis).

[2] Noisternig, Markus. et al. "A 3D Ambisonic Based Binaural Sound Reproduction System." Presented at 24th AES International Conference: Multichannel Audio, The New Reality, Alberta, June 2003.