Logo

Contents:

  • Introduction
  • User Guide
    • Signal Basics
    • Frequency Scales
    • Basic Signal Modifications
    • Resampling
    • Trimming Signals
    • Crossfading Signals
    • Generating Noise
    • Levels and Statistics
    • Coherence and Correlation
    • Filtering
    • Time-Frequency Methods
    • Convolution
    • Head-Related Transfer Functions
      • Loading a SOFA file
      • Building a set manually
      • Looking up and interpolating directions
      • Rendering a source
      • Working in the frequency domain
    • Loading and Saving Audio Files
    • Playback
    • Stimulus visualization
  • API reference
audiotoolbox
  • User Guide
  • Head-Related Transfer Functions
  • View page source

Head-Related Transfer Functions

A head-related transfer function (HRTF), or its time-domain counterpart the head-related impulse response (HRIR), describes how a sound arriving from a given direction is filtered by the head, torso, and outer ears before it reaches the eardrums. Convolving a mono source with the left/right HRIR for a direction places that source at the corresponding position in a binaural (two-channel) signal.

The audiotoolbox.HRIRSet class holds a set of HRIRs measured over many directions and provides direction lookup, interpolation, and rendering. The impulse responses are stored as a regular audiotoolbox.Signal of shape (n_taps, n_directions, 2) (the last axis being the left and right ear), while the measured directions are kept in a separate position table.

Loading a SOFA file

SOFA (Spatially Oriented Format for Acoustics) is the standard interchange format for HRTFs. audiotoolbox.HRIRSet.from_sofa() reads such files using the optional sofar package, which you can install with:

pip install audiotoolbox[hrtf]
>>> import audiotoolbox as audio
>>> hrir_set = audio.HRIRSet.from_sofa('subject_003.sofa')
>>> hrir_set.n_directions
1250
>>> hrir_set.fs
44100

The measured directions are available as the azimuth and elevation attributes (in degrees, following the SOFA convention where azimuth increases counter-clockwise and elevation is measured from the horizontal plane).

Building a set manually

An HRIRSet can also be constructed directly from a Signal and a table of source positions given as (azimuth, elevation[, distance]).

>>> import numpy as np
>>> positions = np.array([[0, 0], [90, 0], [180, 0], [270, 0]])
>>> hrirs = audio.Signal((4, 2), 128 / 48000, 48000)  # 4 directions, L/R
>>> hrir_set = audio.HRIRSet(hrirs, positions)
>>> hrir_set.n_directions
4

Looking up and interpolating directions

audiotoolbox.HRIRSet.nearest() returns the HRIR of the closest measured direction as a two-channel Signal, while audiotoolbox.HRIRSet.interpolate() synthesizes an HRIR for an arbitrary direction. For a fully three-dimensional measurement grid the three directions surrounding the query are combined using barycentric weights on the sphere; for a planar grid (such as a horizontal ring) the two adjacent directions are interpolated instead. Directions outside the measured region fall back to the nearest measurement.

>>> hrir = hrir_set.interpolate(45, 0)
>>> hrir.shape
(128, 2)

Rendering a source

audiotoolbox.HRIRSet.render() spatializes a mono signal by convolving it with the (left, right) HRIR for the requested direction. The input signal is left untouched and a new two-channel signal is returned.

>>> source = audio.Signal(1, 1, 48000).add_noise()
>>> binaural = hrir_set.render(source, azimuth=45, elevation=0)
>>> binaural.n_channels
2

Set interpolate=False to use the nearest measured HRIR instead of an interpolated one.

Working in the frequency domain

audiotoolbox.HRIRSet.to_hrtf() returns the frequency-domain transfer functions as a audiotoolbox.FrequencyDomainSignal. As with audiotoolbox.Signal.to_freqdomain(), this is not done in place; a new object is returned.

>>> hrtf = hrir_set.to_hrtf()
>>> hrtf.n_samples
128
Previous Next

© Copyright 2021, Jörg Encke.

Built with Sphinx using a theme provided by Read the Docs.