libear — Recommendation ITU-R BS.2127 core library¶
libear is a C++14 library to render ADM content according to [bs2127]. It is not a complete application, but provides components to calculate gains and apply them to audio, for embedding into applications which need to render ADM content.
Rendering of ADM content is performed by two distinct processes:
Calculating gains to apply to the input audio samples, as described in Calculating Gains.
Applying those gains to the input audio samples to produce output audio samples, as described in DSP.
To get started, check out the Installation instructions.
Support¶
DirectSpeakers, Objects and HOA typeDefinitions are supported, though the following parameters/features are currently not implemented:
Objects:
Cartesian positions, or
cartesian == true
divergence
zoneExclusion
channelLock
screenRef
screenEdgeLock
DirectSpeakers:
Cartesian positions
screenEdgeLock
All types:
M-SC
andM+SC
loudspeakers with azimuths wider than 25 degrees
libear aims to be a complete renderer implementation; these deficiencies will be addressed in future releases.
libear does not include functionality to read BW64 files or parse ADM XML data; for that functionality we recommend using libbw64 and libadm.
License¶
Copyright 2019 The libear Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Installation¶
Dependencies¶
compiler with C++14 support
Boost header libraries (version 1.57 or later)
Boost.Optional
Boost.Variant
CMake build system (version 3.5 or later)
Installation¶
To manually install the library you have to recursively clone the git repository and then use the CMake build system to build and install it.
git clone --recursive https://github.com/ebu/libear.git
cd libear
mkdir build && cd build
cmake ..
make
make install
Use from CMake Projects¶
As the library uses CMake as a build system it is really easy to set up and use if your project does too. Assuming you have installed the library, the following code shows a complete CMake example to compile a program which uses the libear.
cmake_minimum_required(VERSION 3.5)
project(libear_example VERSION 1.0.0 LANGUAGES CXX)
find_package(ear REQUIRED)
add_executable(example example.cpp)
target_link_libraries(example PRIVATE ear)
Use as a Subproject¶
If you prefer not to install the library on your system you can also use the library as a CMake subproject. Just add the folder containing the repository to your project (for example, by using a git submodule) and you can use the ear target:
cmake_minimum_required(VERSION 3.5)
project(libear_example VERSION 1.0.0 LANGUAGES CXX)
add_subdirectory(submodules/libear)
add_executable(example example.cpp)
target_link_libraries(example PRIVATE ear)
Note
If libear
is used as a CMake subproject the default values of the
options
EAR_UNIT_TESTS
EAR_EXAMPLES
EAR_PACKAGE_AND_INSTALL
are automatically set to FALSE
.
Calculating Gains¶
To calculate gains for an ADM item, the ADM metadata is transferred into a
TypeMetadata
struct for that type, which is passed to the ::calculate
method of a GainCalculator
object instantiated with the desired loudspeaker
layout in order to calculate the gains. Both types are dependant on the ADM
typeDefinition
, and are described below.
TypeMetadata
structures (and sub-structures) for each type are defined in
File metadata.hpp, while GainCalculator
classes are defined in
File ear.hpp.
The mapping between ADM metadata and TypeMetadata
structures must be
performed by the user of the library. The basic mapping is given in the
documentation for each TypeMetadata
structure (linked below), but for more
details see [bs2127] section 5.2.
Errors may be returned by throwing exceptions during GainCalculator
constructor or ::calculate
calls, while warnings may be returned from
::calculate
through the warning_cb
parameter; see Error Handling
for details.
For information on loudspeaker layouts, see Loudspeaker Layouts.
DirectSpeakers¶
DirectSpeakers metadata is represented by the
DirectSpeakersTypeMetadata
, and gains are calculated by
GainCalculatorDirectSpeakers
.
Objects¶
Objects metadata is represented by the
ObjectsTypeMetadata
, and gains are calculated by
GainCalculatorObjects
.
Two gain vectors are produced by GainCalculatorObjects::calculate()
,
directGains
and diffuseGains
. To apply these, see Rendering Objects.
HOA¶
HOA metadata is represented by the
HOATypeMetadata
, and a decode matrix is calculated by
GainCalculatorHOA
.
DSP¶
This library does not provide complete DSP paths to render ADM content, but does contain some components which can be used to do so. DSP components are defined in Namespace ear::dsp.
FFT interface¶
BlockConvolver
objects use a user-provided FFT implementation. These
are provided by implementing FFTImpl<float>
(and therefore FFTPlan<float>
and FFTWorkBuf
) for the FFT library you wish to use, and
passing an instance to BlockConvolver::Context::Context()
.
An implementation for KISS FFT is provided by default, and may be obtained by
calling get_fft_kiss()
. The implementation of this (in
src/fft_kiss.cpp
) may be a useful example to show how the FFT interface
should be implemented.
Rendering DirectSpeakers¶
The gains calculated for DirectSpeakers
channels using the
GainCalculatorDirectSpeakers
should be applied directly to the input
audio channel to produce the output audio channels. DirectSpeakers
metadata
should not be dynamic (there should be a single audioBlockFormat
in each
audioChannelFormat
), so gains should not be interpolated inside blocks, though
should be interpolated if metadata is changed by the user.
This may be applied using
the GainInterpolator
with
LinearInterpVector
.
Rendering Objects¶
The audio processing for Objects content is defined in [bs2127] section 7.1. The structure used is as in Fig. 1.

Signal processing for m Objects with n output channels¶
This can be built from the following components:
GainInterpolator
withLinearInterpVector
to interpolate and apply the gains to the incoming audio (the interp blocks in Fig. 1).DelayBuffer<float>
withdecorrelatorCompensationDelay()
samples delay to compensate for the decorrelator delays.BlockConvolver
objects with filters calculated usingdesignDecorrelators()
to decorrelate the signals.VariableBlockSizeAdapter<float>
to allow the use ofBlockConvolver
objects with variable-size sample blocks. This could be used to wrap just theBlockConvolver::process()
calls, or the whole processing chain (recommended). If only the block convolvers are adapted, then the compensation delay will need to be increased byVariableBlockSizeAdapter::get_delay()
samples.
Rendering HOA¶
As with DirectSpeakers
, HOA
metadata should not be dynamic, so the calculated matrices can be applied directly to the input audio.
The decode matrices calculated for HOA
channels using the
GainCalculatorHOA
should be applied directly to the input audio
channels to produce the output audio channels. As with DirectSpeakers
,
HOA
metadata should not be dynamic (there should be a single
audioBlockFormat
in each audioChannelFormat
), so gains should not be
interpolated inside blocks, though should be interpolated if metadata is
changed by the user.
This may be applied using
the GainInterpolator
with
LinearInterpMatrix
.
Loudspeaker Layouts¶
An output loudspeaker layout is represented by Layout
, which contains
a name, a list of Channel
objects, and the reference Screen
.
Loudspeaker layouts specified in [bs2051] are supported, including
positions within the ranges specified. The function getLayout()
is
therefore provided to obtain a Layout
object given the layout name,
e.g. 4+5+0
.
When using layouts with non-nominal positions, the
Channel::polarPositionNominal()
must match the position specified in Table
1 in [bs2051], and the Channel::polarPosition()
must meet the
specified constraints, including azimuth/elevation ranges and symmetry
requirements.
Non-standard loudspeaker layouts may be used, however their behaviour may change in future versions of the library. Loudspeaker layouts must be similar to those in [bs2051], with 1, 2 or 3 layers and an optional T+000 or UH+180 loudspeaker. Using this functionality requires some understanding of the internals of the renderer, particularly section 6.1.3.1 of [bs2127].
Metadata Conversion¶
Functions are provided for converting Objects metadata between polar and Cartesian formats according to [bs2127] section 10.
See the EAR reference documentation for more general information.
To convert positions only, use pointCartToPolar()
and pointPolarToCart()
.
To convert positions and extent parameters, use extentCartToPolar()
and extentPolarToCart()
.
To convert whole block formats, use toPolar()
and toCartesian()
.
Error Handling¶
Two classes of error are produced by the library: exceptions and warnings.
Exceptions¶
Exceptions are thrown by the library for severe errors which prevent the requested operation from being completed. All errors thrown by the library are defined in File exceptions.hpp
Notably, this library does not yet implement all features of [bs2127];
when such a feature is used, a not_implemented
will be thrown.
Warnings¶
Warnings are issued in less severe cases, where the requested operation could still be completed. Warnings are generally issued for user-facing problems, such as errors in metadata, and so should be visible to the user.
Warnings are returned from the library through the warnings_cb
argument to
::calculate
methods on GainCalculator
objects (for example
GainCalculatorObjects::calculate()
). Each time a warning is issued, the
provided callback will be called with a Warning
structure, containing
the type and message of the warning. By default, default_warning_cb
is
used for this argument, which will print warnings to stderr.
Warning structures are defines in File warnings.hpp.
API Reference¶
Class Hierarchy¶
-
- Namespace ear
- Namespace ear::conversion
- Struct ExtentParams
- Namespace ear::dsp
- Namespace ear::dsp::block_convolver
- Class BlockConvolver
- Class Context
- Class Filter
- Template Struct InterpType
- Struct LinearInterpMatrix
- Struct LinearInterpSingle
- Struct LinearInterpVector
- Class DelayBuffer
- Template Class GainInterpolator
- Template Class PtrAdapterT
- Class VariableBlockSizeAdapter
- Namespace ear::dsp::block_convolver
- Struct CartesianExclusionZone
- Struct CartesianObjectDivergence
- Struct CartesianPosition
- Struct CartesianScreen
- Struct CartesianSpeakerPosition
- Struct ChannelFrequency
- Struct ChannelLock
- Struct DirectSpeakersTypeMetadata
- Struct HOATypeMetadata
- Struct ObjectsTypeMetadata
- Struct PolarExclusionZone
- Struct PolarObjectDivergence
- Struct PolarPosition
- Struct PolarScreen
- Struct PolarSpeakerPosition
- Struct ScreenEdgeLock
- Struct Warning
- Struct ZoneExclusion
- Class adm_error
- Class Channel
- Template Class FFTImpl
- Template Class FFTPlan
- Class FFTWorkBuf
- Class GainCalculatorDirectSpeakers
- Class GainCalculatorHOA
- Class GainCalculatorObjects
- Class internal_error
- Class invalid_argument
- Class Layout
- Class not_implemented
- Class unknown_layout
- Namespace ear::conversion
- Namespace ear
File Hierarchy¶
-
- Directory ear
- Directory dsp
- File block_convolver.hpp
- File delay_buffer.hpp
- File dsp.hpp
- File gain_interpolator.hpp
- File ptr_adapter.hpp
- File variable_block_size.hpp
- File bs2051.hpp
- File common_types.hpp
- File conversion.hpp
- File decorrelate.hpp
- File ear.hpp
- File exceptions.hpp
- File fft.hpp
- File gain_calculators.hpp
- File layout.hpp
- File metadata.hpp
- File screen.hpp
- File warnings.hpp
- Directory dsp
- Directory ear
Full API¶
Namespaces¶
Namespace ear::dsp::block_convolver¶
Classes and Structs¶
Struct CartesianScreen¶
Defined in File screen.hpp
Struct ExtentParams¶
Defined in File conversion.hpp
Struct DirectSpeakersTypeMetadata¶
Defined in File metadata.hpp
-
struct ear::DirectSpeakersTypeMetadata¶
Public Members
-
std::vector<std::string> speakerLabels = {}¶
contents of the
speakerLabel
tags in thisaudioBlockFormat
, in the order given in the AXML
-
SpeakerPosition position = PolarSpeakerPosition()¶
contents of the
position
elements
-
ChannelFrequency channelFrequency = {}¶
frequency
information contained in theaudioChannelFormat
-
boost::optional<std::string> audioPackFormatID = boost::none¶
audioPackFormatID
of theaudioPackFormat
directly referencing this channel, for exampleAP_00010002
-
std::vector<std::string> speakerLabels = {}¶
Template Struct InterpType¶
Defined in File gain_interpolator.hpp
-
template<typename PointT>
struct ear::dsp::InterpType¶ Base type for interpolation types.
Public Types
Public Static Functions
-
static inline bool constant_interp(const Point &a, const Point &b)¶
Are the two points the same (and therefore constant/no interpolation should be used between them)?
-
static void apply_interp(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, SampleIndex block_start, SampleIndex start, SampleIndex end, const Point &start_point, const Point &end_point)¶
Apply interpolated gains to
in
, writing toout
.For example, if an interpolation curve goes from x to y between sample 5 and 15, these calls would occur for the first and second 10-sample blocks:
apply_interp(in_a, out_a, 5, 10, 0, 5, 15, x, y); apply_interp(in_b, out_b, 0, 5, 10, 5, 15, x, y);
- Parameters
in – input samples
out – output samples
range_start – offset in
in
andout
to start processingrange_end – offset in
in
andout
to end processingblock_start – start sample index of this block, i.e. in[0][0]
start – start sample index of interpolation curve
end – end sample index of interpolation curve
start_point – gain values at
start
end_point – gain values at
end
-
static void apply_constant(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, const Point &point)¶
Apply constnt gain gains to
in
, writing toout
.- Parameters
in – input samples
out – output samples
range_start – offset in
in
andout
to start processingrange_end – offset in
in
andout
to end processingpoint – gain values to apply
-
static inline bool constant_interp(const Point &a, const Point &b)¶
Struct LinearInterpMatrix¶
Defined in File gain_interpolator.hpp
public ear::dsp::InterpType< std::vector< std::vector< float > > >
(Template Struct InterpType)
-
struct ear::dsp::LinearInterpMatrix : public ear::dsp::InterpType<std::vector<std::vector<float>>>¶
Linear interpolation with multiple input and output channels, with a matrix of coefficients for use in GainInterpolator.
Points contain one vector of per-output gains per input channel.
Public Static Functions
-
static inline void apply_interp(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, SampleIndex block_start, SampleIndex start, SampleIndex end, const Point &start_point, const Point &end_point)¶
-
static inline void apply_constant(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, const Point &point)¶
-
static inline void apply_interp(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, SampleIndex block_start, SampleIndex start, SampleIndex end, const Point &start_point, const Point &end_point)¶
Struct LinearInterpSingle¶
Defined in File gain_interpolator.hpp
public ear::dsp::InterpType< float >
(Template Struct InterpType)
-
struct ear::dsp::LinearInterpSingle : public ear::dsp::InterpType<float>¶
Linear interpolation of a single channel for use in GainInterpolator.
Public Static Functions
-
static inline void apply_interp(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, SampleIndex block_start, SampleIndex start, SampleIndex end, const Point &start_point, const Point &end_point)¶
-
static inline void apply_constant(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, const Point &point)¶
-
static inline void apply_interp(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, SampleIndex block_start, SampleIndex start, SampleIndex end, const Point &start_point, const Point &end_point)¶
Struct LinearInterpVector¶
Defined in File gain_interpolator.hpp
public ear::dsp::InterpType< std::vector< float > >
(Template Struct InterpType)
-
struct ear::dsp::LinearInterpVector : public ear::dsp::InterpType<std::vector<float>>¶
Linear interpolation with one channel in and multiple out for use in GainInterpolator.
Public Static Functions
-
static inline void apply_interp(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, SampleIndex block_start, SampleIndex start, SampleIndex end, const Point &start_point, const Point &end_point)¶
-
static inline void apply_constant(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, const Point &point)¶
-
static inline void apply_interp(const float *const *in, float *const *out, SampleIndex range_start, SampleIndex range_end, SampleIndex block_start, SampleIndex start, SampleIndex end, const Point &start_point, const Point &end_point)¶
Struct HOATypeMetadata¶
Defined in File metadata.hpp
-
struct ear::HOATypeMetadata¶
Representation of all audioChannelFormats in a HOA audioPackFormat.
orders and degrees must be the same length and must be in the same order as the channels being rendered, such that the
i
th input channel has orderorders[i]
and degreedegrees[i]
.normalization
,nfcRefDist
andscreenRef
may be defined in anaudioBlockFormat
and/oraudioPackFormat
; see the rules in [bs2127] section 5.2.7.3 for details.Public Members
-
std::vector<int> orders¶
value of the
order
element in theaudioBlockFormat
element of each channel
-
std::vector<int> degrees¶
value of the
degree
element in theaudioBlockFormat
element of each channel
-
std::string normalization = std::string("SN3D")¶
-
double nfcRefDist = 0.0¶
-
bool screenRef = false¶
-
Screen referenceScreen = getDefaultScreen()¶
screen specification from the
audioProgrammeReferenceScreen
element of theaudioProgramme
being rendered
-
std::vector<int> orders¶
Struct ObjectsTypeMetadata¶
Defined in File metadata.hpp
-
struct ear::ObjectsTypeMetadata¶
Public Members
-
double width = 0.0¶
-
double height = 0.0¶
-
double depth = 0.0¶
-
bool cartesian = false¶
value of the
cartesian
flag; should be the same type as used in position, objectDivergence and zoneExclusion, otherwise expect warnings.
-
double gain = 1.0¶
-
double diffuse = 0.0¶
-
ChannelLock channelLock = {}¶
-
ObjectDivergence objectDivergence = {}¶
-
ZoneExclusion zoneExclusion = {}¶
-
bool screenRef = false¶
-
Screen referenceScreen = getDefaultScreen()¶
screen specification from the
audioProgrammeReferenceScreen
element of theaudioProgramme
being rendered
-
double width = 0.0¶
Struct PolarScreen¶
Defined in File screen.hpp
Struct PolarSpeakerPosition¶
Defined in File metadata.hpp
-
struct ear::PolarSpeakerPosition¶
Public Functions
-
inline PolarSpeakerPosition(double az = 0.0, double el = 0.0, double dist = 1.0)¶
Public Members
-
double azimuth¶
-
boost::optional<double> azimuthMin¶
-
boost::optional<double> azimuthMax¶
-
double elevation¶
-
boost::optional<double> elevationMin¶
-
boost::optional<double> elevationMax¶
-
double distance¶
-
boost::optional<double> distanceMin¶
-
boost::optional<double> distanceMax¶
-
ScreenEdgeLock screenEdgeLock¶
-
inline PolarSpeakerPosition(double az = 0.0, double el = 0.0, double dist = 1.0)¶
Struct ScreenEdgeLock¶
Defined in File metadata.hpp
Struct Warning¶
Defined in File warnings.hpp
-
struct ear::Warning¶
A warning message, containing a code and a corresponding message.
The code does not need to be shown when displaying warnings; the message should contain all the information required, the code is just to allow implementations to take action on warnings without matching against the messages.
Public Types
-
enum Code¶
Values:
-
enumerator FREQ_SPEAKERLABEL_LFE_MISMATCH¶
LFE indication from frequency element does not match speakerLabel.
-
enumerator FREQ_NOT_LFE¶
frequency indication present but does not indicate an LFE channel
-
enumerator FREQ_IGNORED¶
frequency information is not implemented; ignoring
-
enumerator HOA_SCREENREF_NOT_IMPLEMENTED¶
screenRef for HOA is not implemented; ignoring
-
enumerator HOA_NFCREFDIST_NOT_IMPLEMENTED¶
nfcRefDist is not implemented; ignoring
-
enumerator FREQ_SPEAKERLABEL_LFE_MISMATCH¶
-
enum Code¶
Struct ZoneExclusion¶
Defined in File metadata.hpp
-
struct ear::ZoneExclusion¶
Public Members
-
std::vector<ExclusionZone> zones¶
-
std::vector<ExclusionZone> zones¶
Class adm_error¶
Defined in File exceptions.hpp
-
class ear::adm_error : public invalid_argument¶
thrown if invalid ADM metadata is encountered
Public Functions
-
inline explicit adm_error(const std::string &what)¶
-
inline explicit adm_error(const std::string &what)¶
Class Channel¶
Defined in File layout.hpp
-
class ear::Channel¶
Representation of a channel, with a name, real and nominal positions, allowed azimuth and elevation ranges, and an lfe flag.
Public Functions
-
Channel() = default¶
-
Channel(const std::string &name, PolarPosition polarPosition, boost::optional<PolarPosition> polarPositionNominal = boost::none, boost::optional<std::pair<double, double>> azimuthRange = boost::none, boost::optional<std::pair<double, double>> elevationRange = boost::none, bool isLfe = false)¶
- Parameters
name – Channel name.
polarPosition – real speaker location
polarPositionNominal – nominal speaker location, defaults to polar_position
azimuthRange – azimuth range in degrees; allowed range is interpreted as starting at azimuthRange[0], moving anticlockwise to azimuthRange[1]; defaults to the azimuth of polar_nominal_position.
elevationRange – elevation range in degrees; allowed range is interpreted as starting at elevationRange.first, moving up to elevationRange.second defaults to the elevation of polar_nominal_position.
isLfe – flag to indicate an LFE channel
-
std::string name() const¶
-
PolarPosition polarPosition() const¶
-
PolarPosition polarPositionNominal() const¶
-
std::pair<double, double> azimuthRange() const¶
-
std::pair<double, double> elevationRange() const¶
-
bool isLfe() const¶
-
void name(const std::string &name)¶
-
void polarPosition(PolarPosition polarPosition)¶
-
void polarPositionNominal(const boost::optional<PolarPosition> &polarPositionNominal)¶
-
void azimuthRange(const boost::optional<std::pair<double, double>> &azimuthRange)¶
-
void elevationRange(const boost::optional<std::pair<double, double>> &elevationRange)¶
-
void isLfe(bool isLfe)¶
-
void checkPosition(std::function<void(const std::string&)> callback) const¶
-
Channel() = default¶
Class BlockConvolver¶
Defined in File block_convolver.hpp
-
class ear::dsp::block_convolver::BlockConvolver¶
BlockConvolver implements partitioned overlap-add convolution with a fixed block size, with efficient fading between filters.
Public Functions
-
BlockConvolver(const Context &ctx, size_t num_blocks)¶
Create a BlockConvolver given the block size and number of blocks.
- Parameters
ctx – Context required for transformations.
num_blocks – Maximum number of blocks of any filter used.
-
BlockConvolver(const Context &ctx, const Filter &filter, size_t num_blocks = 0)¶
Create a BlockConvolver given the block size and number of blocks.
If filter == nullptr, num_blocks must be specified.
- Parameters
ctx – Context required for transformations.
filter – Initial filter to be used, or nullptr for no filter.
num_blocks – Maximum number of blocks of any filter used; using 0 will take the number of blocks from the passed filter.
-
void process(const float *in, float *out)¶
Pass a block of audio through the filter.
- Parameters
in – Input samples of length block_size
out – Output samples of length block_size
-
void crossfade_filter(const Filter &filter)¶
Crossfade to a new filter during the next block.
This is equivalent to:
Creating a new convolver.
Passing the next block of samples through the old and new convolvers, with the input to the old faded down across the block, and the input to the new faded up across the block. All subsequent blocks are passed through the new filter.
Mixing the output of the old and new filters for the next num_blocks blocks.
-
void fade_down()¶
Crossfade to a zero-valued filter.
-
void unset_filter()¶
Switch to a zero-valued filter at the start of the next block.
-
BlockConvolver(const Context &ctx, size_t num_blocks)¶
Class Context¶
Defined in File block_convolver.hpp
-
class ear::dsp::block_convolver::Context¶
Static data required to perform convolution of a particular block size; may be shared between any number of BlockConvolver and Filter instances.
Class Filter¶
Defined in File block_convolver.hpp
-
class ear::dsp::block_convolver::Filter¶
A filter response which may be shared between many BlockConvolver instances.
This stores the pre-transformed filter blocks.
Class DelayBuffer¶
Defined in File delay_buffer.hpp
-
class ear::dsp::DelayBuffer¶
A multi-channel delay buffer.
Public Functions
-
DelayBuffer(size_t nchannels, size_t nsamples)¶
- Parameters
nchannels – number of input and output channels
nsamples – length of the delay
-
void process(size_t nsamples, const float *const *input, float *const *output)¶
Process an arbitrary number of samples.
input
andoutput
havenchannels
channels andnsamples
samples.
-
int get_delay() const¶
Get the delay in samples.
-
DelayBuffer(size_t nchannels, size_t nsamples)¶
Template Class GainInterpolator¶
Defined in File gain_interpolator.hpp
-
template<typename InterpType>
class ear::dsp::GainInterpolator¶ Gain interpolator, templated over an interpolation type which defines the type of interpolation (linear, cosine etc.), the type of the values to interpolate between (floats, vectors, matrices), and therefore restrictions on the input and output channel sizes.
An interpolation curve is defined by the points in interp_points. Each of these is a pair of the sample index and the gain values at that time. These must be sorted in time order. Duplicate times can be used to specify steps.
See LinearInterpSingle, LinearInterpVector and LinearInterpMatrix for possible interpolation types. See InterpType for the interface that interpolation types define.
Public Functions
-
inline void process(SampleIndex block_start, size_t nsamples, const float *const *in, float *const *out)¶
Process n samples.
- Parameters
block_start – the index of the first sample relative to the sample indices in interp_points
nsamples – number of samples in
in
andout
in – input samples with a number of channels compatible with the interpolation type and points used
out – output samples with a number of channels compatible with the interpolation type and points used
Public Members
-
std::vector<std::pair<SampleIndex, typename InterpType::Point>> interp_points¶
-
inline void process(SampleIndex block_start, size_t nsamples, const float *const *in, float *const *out)¶
Template Class PtrAdapterT¶
Defined in File ptr_adapter.hpp
-
template<typename PtrT = float*>
class ear::dsp::PtrAdapterT¶ Adapter from Eigen matrix expressions (and possibly other things) to float**.
Public Functions
-
inline PtrAdapterT(size_t nchannels)¶
-
template<typename T>
inline void set_eigen(T &&mat, size_t offset = 0)¶ Point each pointer at a column of Eigen Matrix expression
matrix
, with an offset ofoffset
.
-
PtrAdapterT(const PtrAdapterT&) = delete¶
-
PtrAdapterT &operator=(const PtrAdapterT&) = delete¶
-
inline PtrAdapterT(size_t nchannels)¶
Class VariableBlockSizeAdapter¶
Defined in File variable_block_size.hpp
-
class ear::dsp::VariableBlockSizeAdapter¶
Adapt something that processes fixed-size blocks of samples into one that processes variable sized blocks by adding some delay.
This can be used with e.g. BlockConvolver to process arbitrary block lengths. This isn’t built into the BlockConvolver, because it’s not always necessary, and because this introduces some delay; if we adapt multiple components with this then we can save some delay compared to having it built into each component.
Public Types
-
using ProcessFunc = void(const float *const *in, float *const *out)¶
Public Functions
-
VariableBlockSizeAdapter(size_t block_size, size_t num_channels_in, size_t num_channels_out, std::function<ProcessFunc> process_func)¶
- Parameters
block_size – number of samples accepted by
process_func
num_channels_in – number of input channels
num_channels_out – number of output channels
process_func – function to call to process block_size samples
-
void process(size_t nsamples, const float *const *in, float *const *out)¶
Process nsamples samples.
-
int get_delay() const¶
The delay introduced by the variable block size processing, not accounting for any delay introduced by the inner process.
-
using ProcessFunc = void(const float *const *in, float *const *out)¶
Template Class FFTImpl¶
Defined in File fft.hpp
Template Class FFTPlan¶
Defined in File fft.hpp
-
template<typename Real>
class ear::FFTPlan¶ Plan for performing an FFT of a particular size/layout/type; allocated by calling FFTImpl::plan.
This is not mutated when transform_* are called, so one plan may be shared between threads.
Public Functions
-
virtual void transform_forward(Real *input, Complex *output, FFTWorkBuf &workbuf) const = 0¶
Execute an r2c forwards transform.
- Parameters
input – n_fft input samples
output – n_fft/2+1 output samples containing the first half of the complex frequency components without any packing.
workbuf – temporary buffers allocated with alloc_workbuf
-
virtual void transform_reverse(Complex *input, Real *output, FFTWorkBuf &workbuf) const = 0¶
Execute an c2r inverse transform.
- Parameters
input – n_fft/2+1 input samples, in the same format as given by transform_forward
output – n_fft output samples
workbuf – temporary buffers allocated with alloc_workbuf
-
virtual std::unique_ptr<FFTWorkBuf> alloc_workbuf() const = 0¶
allocate temporary buffers to be used with transform_*
-
virtual void transform_forward(Real *input, Complex *output, FFTWorkBuf &workbuf) const = 0¶
Class FFTWorkBuf¶
Defined in File fft.hpp
-
class FFTWorkBuf¶
temporary buffers needed to perform an FFT; allocated by calling FFTPlan::alloc_workbuf.
As this contains data which is mutated by the transform functions, this must not be shared between threads.
Class GainCalculatorDirectSpeakers¶
Defined in File gain_calculators.hpp
-
class ear::GainCalculatorDirectSpeakers¶
Gain calculator for typeDefinition == “DirectSpeakers”.
Public Functions
-
GainCalculatorDirectSpeakers(const Layout &layout, std::map<std::string, std::string> additionalSubstitutions = {})¶
-
template<typename T>
void calculate(const DirectSpeakersTypeMetadata &metadata, std::vector<T> &gains, const WarningCB &warning_cb = default_warning_cb)¶ Calculate gains for metadata.
gains
contains per-loudspeaker gains to render this channel.
-
GainCalculatorDirectSpeakers(const Layout &layout, std::map<std::string, std::string> additionalSubstitutions = {})¶
Class GainCalculatorHOA¶
Defined in File gain_calculators.hpp
-
class ear::GainCalculatorHOA¶
Gain calculator for typeDefinition == “HOA”.
Public Functions
-
template<typename T>
void calculate(const HOATypeMetadata &metadata, std::vector<std::vector<T>> &gains, const WarningCB &warning_cb = default_warning_cb)¶ Calculate a decode matrix for metadata.
Gains contains one vector of per-loudspeaker gains per input channel, and must be the right size before calling.
-
template<typename T>
Class GainCalculatorObjects¶
Defined in File gain_calculators.hpp
-
class ear::GainCalculatorObjects¶
Gain calculator for typeDefinition == “Objects”.
Public Functions
-
template<typename T>
void calculate(const ObjectsTypeMetadata &metadata, std::vector<T> &directGains, std::vector<T> &diffuseGains, const WarningCB &warning_cb = default_warning_cb)¶ Calculate gains for metadata.
directGains
anddiffuseGains
contains per-loudspeaker gains to render this channel.To apply these gains:
directGains
are applied to this channel, and summed with other objects into a n-channel direct busdiffuseGains
are applied to this channel, and summed with other objects into a n-channel diffuse buseach channel in the diffuse bus is processed with the corresponding FIR filter given by designDecorrelators()
each channel in the direct bus is delayed by decorrelatorCompensationDelay() samples to compensate for the delay through the decorrelation filters
the output of the decorrelation filters and delays are mixed together to form the output
-
template<typename T>
Class internal_error¶
Defined in File exceptions.hpp
-
class ear::internal_error : public runtime_error¶
thrown for errors inside the library, which should not have occurred given any inputs.
This can be caused by an error in the library itself (please report it!) or something going wrong while building the library. This is thrown by ear_assert.
Public Functions
-
inline explicit internal_error(const std::string &what)¶
-
inline explicit internal_error(const std::string &what)¶
Class invalid_argument¶
Defined in File exceptions.hpp
-
class ear::invalid_argument : public invalid_argument¶
thrown if other invariants on parameters are not met
Public Functions
-
inline explicit invalid_argument(const std::string &what)¶
-
inline explicit invalid_argument(const std::string &what)¶
Class Layout¶
Defined in File layout.hpp
-
class ear::Layout¶
Representation of a loudspeaker layout, with a name and a list of channels.
Public Functions
-
Layout(std::string name = "", std::vector<Channel> channels = std::vector<Channel>(), boost::optional<Screen> screen = getDefaultScreen())¶
-
std::string name() const¶
-
void name(std::string name)¶
-
std::vector<bool> isLfe() const¶
-
std::vector<std::string> channelNames() const¶
-
void checkPositions(std::function<void(const std::string&)> callback) const¶
-
boost::optional<int> indexForName(const std::string &name) const¶
-
std::vector<PolarPosition> positions() const¶
-
std::vector<PolarPosition> nominalPositions() const¶
-
Layout(std::string name = "", std::vector<Channel> channels = std::vector<Channel>(), boost::optional<Screen> screen = getDefaultScreen())¶
Class not_implemented¶
Defined in File exceptions.hpp
Class unknown_layout¶
Defined in File exceptions.hpp
-
class ear::unknown_layout : public invalid_argument¶
thrown if an unknown loudspeaker layout is requested
Public Functions
-
inline explicit unknown_layout(const std::string &what)¶
-
inline explicit unknown_layout(const std::string &what)¶
Functions¶
Function ear::conversion::extentCartToPolar¶
Defined in File conversion.hpp
-
std::pair<PolarPosition, ExtentParams> ear::conversion::extentCartToPolar(const CartesianPosition &pos, const ExtentParams &extent)¶
convert a Cartesian position and extent parameters to polar
This corresponds to
ear.core.objectbased.conversion.extent_cart_to_polar()
.
Function ear::conversion::extentPolarToCart¶
Defined in File conversion.hpp
-
std::pair<CartesianPosition, ExtentParams> ear::conversion::extentPolarToCart(const PolarPosition &pos, const ExtentParams &extent)¶
convert a polar position and extent parameters to Cartesian
This corresponds to
ear.core.objectbased.conversion.extent_polar_to_cart()
.
Function ear::conversion::pointCartToPolar¶
Defined in File conversion.hpp
-
PolarPosition ear::conversion::pointCartToPolar(const CartesianPosition &pos)¶
convert a Cartesian position to polar
This corresponds to
ear.core.objectbased.conversion.point_cart_to_polar()
.
Function ear::conversion::pointPolarToCart¶
Defined in File conversion.hpp
-
CartesianPosition ear::conversion::pointPolarToCart(const PolarPosition &pos)¶
convert a polar position to Cartesian
This corresponds to
ear.core.objectbased.conversion.point_polar_to_cart()
.
Function ear::conversion::toCartesian¶
Defined in File conversion.hpp
-
void ear::conversion::toCartesian(ObjectsTypeMetadata &otm)¶
in-place conversion of Objects metadata to Cartesian
The cartesian flag is ignored, and the type of the position is used to determine whether the metadata is Cartesian or polar. If the metadata is polar, then the position and extent parameters are converted to Cartesian, and the cartesian flag is set.
This corresponds to
ear.core.objectbased.conversion.to_cartesian()
.
Function ear::conversion::toPolar¶
Defined in File conversion.hpp
-
void ear::conversion::toPolar(ObjectsTypeMetadata &otm)¶
in-place conversion of Objects metadata to polar
The cartesian flag is ignored, and the type of the position is used to determine whether the metadata is Cartesian or polar. If the metadata is Cartesian, then the position and extent parameters are converted to polar, and the cartesian flag is cleared.
This corresponds to
ear.core.objectbased.conversion.to_polar()
.
Function ear::decorrelatorCompensationDelay¶
Defined in File decorrelate.hpp
Template Function ear::designDecorrelators¶
Defined in File decorrelate.hpp
Function ear::getDefaultScreen¶
Defined in File screen.hpp
Function ear::getLayout¶
Defined in File bs2051.hpp
Function ear::loadLayouts¶
Defined in File bs2051.hpp
Variables¶
Variable ear::default_warning_cb¶
Defined in File warnings.hpp
Typedefs¶
Typedef ear::dsp::block_convolver::complex_t¶
Defined in File block_convolver.hpp
Typedef ear::dsp::block_convolver::real_t¶
Defined in File block_convolver.hpp
Typedef ear::dsp::PtrAdapter¶
Defined in File ptr_adapter.hpp
-
using ear::dsp::PtrAdapter = PtrAdapterT<float*>¶
Typedef ear::dsp::PtrAdapterConst¶
Defined in File ptr_adapter.hpp
-
using ear::dsp::PtrAdapterConst = PtrAdapterT<const float*>¶
Typedef ear::dsp::SampleIndex¶
Defined in File gain_interpolator.hpp
Typedef ear::ExclusionZone¶
Defined in File metadata.hpp
-
using ear::ExclusionZone = boost::variant<PolarExclusionZone, CartesianExclusionZone>¶
Typedef ear::ObjectDivergence¶
Defined in File metadata.hpp
-
using ear::ObjectDivergence = boost::variant<PolarObjectDivergence, CartesianObjectDivergence>¶
Typedef ear::Position¶
Defined in File common_types.hpp
-
using ear::Position = boost::variant<CartesianPosition, PolarPosition>¶
Typedef ear::Screen¶
Defined in File screen.hpp
-
using ear::Screen = boost::variant<PolarScreen, CartesianScreen>¶
Typedef ear::SpeakerPosition¶
Defined in File metadata.hpp
-
using ear::SpeakerPosition = boost::variant<PolarSpeakerPosition, CartesianSpeakerPosition>¶
Typedef ear::WarningCB¶
Defined in File warnings.hpp
Changelog¶
unreleased changes¶
Changed¶
Layout::screen
defaults togetDefaultScreen()
to match the EAR. Calllayout.screen(boost::none)
to get the old behaviour.added xsimd submodule and updated eigen to 3.4.0; this required changing the eigen remote, so you may need to run
git submodule sync
as well as the usualgit submodule update --init --recursive
0.9.0¶
Initial release.
Bibliography¶
- bs2127
Recommendation ITU-R BS.2127-0 : Audio Definition Model renderer for advanced sound systems. URL: https://www.itu.int/rec/R-REC-BS.2127.
- bs2051
Recommendation ITU-R BS.2051-2 : Advanced sound system for programme production. URL: https://www.itu.int/rec/R-REC-BS.2051.