%% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[a4paper,10pt,english]{sphinxmanual}
\ifdefined\pdfpxdimen
   \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen
\fi \sphinxpxdimen=.75bp\relax

\PassOptionsToPackage{warn}{textcomp}
\usepackage[utf8]{inputenc}
\ifdefined\DeclareUnicodeCharacter
 \ifdefined\DeclareUnicodeCharacterAsOptional
  \DeclareUnicodeCharacter{"00A0}{\nobreakspace}
  \DeclareUnicodeCharacter{"2500}{\sphinxunichar{2500}}
  \DeclareUnicodeCharacter{"2502}{\sphinxunichar{2502}}
  \DeclareUnicodeCharacter{"2514}{\sphinxunichar{2514}}
  \DeclareUnicodeCharacter{"251C}{\sphinxunichar{251C}}
  \DeclareUnicodeCharacter{"2572}{\textbackslash}
 \else
  \DeclareUnicodeCharacter{00A0}{\nobreakspace}
  \DeclareUnicodeCharacter{2500}{\sphinxunichar{2500}}
  \DeclareUnicodeCharacter{2502}{\sphinxunichar{2502}}
  \DeclareUnicodeCharacter{2514}{\sphinxunichar{2514}}
  \DeclareUnicodeCharacter{251C}{\sphinxunichar{251C}}
  \DeclareUnicodeCharacter{2572}{\textbackslash}
 \fi
\fi
\usepackage{cmap}
\usepackage[T1]{fontenc}
\usepackage{amsmath,amssymb,amstext}
\usepackage{babel}
\usepackage{times}
\usepackage[Bjarne]{fncychap}
\usepackage{sphinx}

\usepackage{geometry}

% Include hyperref last.
\usepackage{hyperref}
% Fix anchor placement for figures with captions.
\usepackage{hypcap}% it must be loaded after hyperref.
% Set up styles of URL: it should be placed after hyperref.
\urlstyle{same}
\addto\captionsenglish{\renewcommand{\contentsname}{Contents}}

\addto\captionsenglish{\renewcommand{\figurename}{Fig.}}
\addto\captionsenglish{\renewcommand{\tablename}{Table}}
\addto\captionsenglish{\renewcommand{\literalblockname}{Listing}}

\addto\captionsenglish{\renewcommand{\literalblockcontinuedname}{continued from previous page}}
\addto\captionsenglish{\renewcommand{\literalblockcontinuesname}{continues on next page}}

\addto\extrasenglish{\def\pageautorefname{page}}

\setcounter{tocdepth}{1}



\title{VISR User documentation}
\date{Feb 06, 2019}
\release{}
\author{The S3A project team}
\newcommand{\sphinxlogo}{\vbox{}}
\renewcommand{\releasename}{}
\makeindex

\begin{document}

\maketitle
\sphinxtableofcontents
\phantomsection\label{\detokenize{index::doc}}



\chapter{About}
\label{\detokenize{about:about}}\label{\detokenize{about::doc}}
The VISR framework is a collection of software for audio processing that forms the backbone for most of the technology created in S3A. In this extensible software framework, complex audio algorithms can be formed by interconnecting existing building blocks, termed components.

It can be used either interactively in the Python language, in custom applications (for instance in written C++, or integrated into other applications, for instance as DAW plugins or Max/MSP externals). While the VISR provides several renderers and building blocks for spatial and object-based audio, it is nonetheless a generic audio processing framework that can be used in other applications, for example array processing or hearing aid prototypes. The Python integration makes the system accessible, and enables easy algorithm development and prototyping.


\chapter{Getting started with the VISR framework}
\label{\detokenize{getting-started:getting-started-with-the-visr-framework}}\label{\detokenize{getting-started::doc}}
Welcome to the user guide of the VISR user documentation.

\begin{sphinxadmonition}{important}{Important:}
This document is work in progress. Please check the online documentation regularly for updates.
\end{sphinxadmonition}

To get an overview of the VISR framework, we suggest reading Chapter {\hyperref[\detokenize{visr-python-tutorial:visr-python-tutorial}]{\sphinxcrossref{\DUrole{std,std-ref}{VISR tutorial using Python}}}}, which provides a tutorial-style overview based on the paper \phantomsection\label{\detokenize{getting-started:id1}}{\hyperref[\detokenize{references:franck-et-al2018-an-open-software-rendering-framework-for-audio-reproduction-and-reproducible-research}]{\sphinxcrossref{{[}FF18{]}}}}.

Detailed installation instructions are provided in Chapter {\hyperref[\detokenize{getting-visr:getting-visr}]{\sphinxcrossref{\DUrole{std,std-ref}{Getting VISR}}}}.

The standalone command-line applications contained in the VISR distribution are detailed in Chapter {\hyperref[\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers}]{\sphinxcrossref{\DUrole{std,std-ref}{Using standalone applications}}}}.

The support for object-based audio in VISR is outlined in Chapter {\hyperref[\detokenize{object-based-audio-with-visr:visr-object-based-audio}]{\sphinxcrossref{\DUrole{std,std-ref}{Object-Based Audio with VISR}}}}. This includes the audio object representation, but also the object-based renderers contained in the default VISR distribution.

The processing components contained in the default component libraries are documented in Chapter {\hyperref[\detokenize{rcl_component_documentation:visr-default-component-library-reference}]{\sphinxcrossref{\DUrole{std,std-ref}{The default component library}}}}.

The Binaural synthesis toolkit is introduced in Chapter {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst}]{\sphinxcrossref{\DUrole{std,std-ref}{The Binaural Synthesis Toolkit}}}}, consisting of a {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-tutorial}]{\sphinxcrossref{\DUrole{std,std-ref}{tutorial-style description}}}} based on \phantomsection\label{\detokenize{getting-started:id2}}{\hyperref[\detokenize{references:franck-et-al2018-an-open-realtime-binaural-synthesis-toolkit-for-audio-research}]{\sphinxcrossref{{[}FCPF18{]}}}} and a {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-component-reference}]{\sphinxcrossref{\DUrole{std,std-ref}{component reference}}}}.


\section{Python integration}
\label{\detokenize{getting-started:python-integration}}\label{\detokenize{getting-started:overview-python-integration}}
Although the core of the VISR is written in C++ and there are uses of the VISR framework that do not require Python,
the Python integration plays a central role in this user documentation.
The main reason for that is accessibility. With Python, the VISR framework can be explored and extended interactively, and most interfaces are more intuitive than their C++ counterparts.

The main uses of the VISR framework without Python are the standalone applications explained in  {\hyperref[\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers}]{\sphinxcrossref{\DUrole{std,std-ref}{Using standalone applications}}}}, and the integration of VISR components and infrastructure in user-defined applications, plugins, or externals.

Because of this strong emphasis on the Python integration, it is important to install a VISR distribution built for thecorrect Python version, and to perform the Python-specific configuration steps. This is detailed in Section {\hyperref[\detokenize{installation:visr-installation-setting-up-python}]{\sphinxcrossref{\DUrole{std,std-ref}{Setting up Python}}}}.


\chapter{VISR tutorial using Python}
\label{\detokenize{visr-python-tutorial:visr-tutorial-using-python}}\label{\detokenize{visr-python-tutorial:visr-python-tutorial}}\label{\detokenize{visr-python-tutorial::doc}}
\begin{sphinxadmonition}{note}{Note:}
This tutorial is an extended version of the paper: Andreas Franck and Filippo Maria Fazi. VISR \textendash{} a versatile open software framework for audio signal processing. In Proc. Audio Eng. Soc. 2018 Int. Conf. Spatial Reproduction. Tokyo, Japan, August 2018. \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=19628}
\end{sphinxadmonition}

Software plays an increasingly important role in spatial and object-based audio.
Realtime and interactive rendering is often needed to subjectively evaluate and demonstrate algorithms, requiring significant implementation effort and often impeding the reproducibility of scientific research.
In this paper we present the VISR (Versatile Interactive Scene Renderer) \textendash{} a modular, open-source software framework for audio processing.
VISR enables systematic reuse of DSP functionality, rapid prototyping in C++ or Python, and integration into the typical workflow of audio research and development from initial implementation and offline objective evaluation to subjective testing.
This paper provides a practical, example-based introduction to the VISR framework.
This is demonstrated with an interconnected example, from algorithm design and implementation, dynamic binaural auralization, to a subjective test.


\section{Introduction}
\label{\detokenize{visr-python-tutorial:introduction}}\label{\detokenize{visr-python-tutorial:visr-tutorial-sec-introduction}}
Many areas of audio research depend heavily on software for audio processing and rendering.
This includes not only research on sound reproduction, but also basic and applied research that use audio reproduction as a tool.
Very often, this rendering must be responsive and interactive, requiring realtime-capable software tools.
Combined with the number of DSP building blocks required for most rendering approaches, this entails a significant implementation effort for many audio research tasks.
At the same time, the increasing importance of reproducible research imposes more demanding requirements on software in order to enable others to reproduce and evaluate your results or to use them in their work \phantomsection\label{\detokenize{visr-python-tutorial:id1}}{\hyperref[\detokenize{visr-python-tutorial:tut-wilson-et-al2014-best-practices-for-scientific-computing}]{\sphinxcrossref{{[}T1{]}}}}\phantomsection\label{\detokenize{visr-python-tutorial:id2}}{\hyperref[\detokenize{visr-python-tutorial:tut-cannam-figueira-plumbley2012-sound-software-towards-software-research-in-audio-and-music-research}]{\sphinxcrossref{{[}T2{]}}}}.
Software reuse is a central aspect to tackle these challenges.

Therefore we introduce the VISR (Versatile Interactive Scene Renderer), a novel portable, modular, and open-source software framework for audio processing and reproduction.
Created in the S3A project (\sphinxurl{http://www.s3a-spatialaudio.org}), e.g., \phantomsection\label{\detokenize{visr-python-tutorial:id3}}{\hyperref[\detokenize{visr-python-tutorial:tut-coleman-et-al2018-an-audio-visual-system-for-object-based-audio}]{\sphinxcrossref{{[}T3{]}}}}, with focus on multichannel spatial and object-based audio, it is nonetheless a generic, application-agnostic framework.
It consists of a set of pre-configured rendering signal flow, a library of DSP and audio processing building blocks, and supporting software to run these components in both realtime and offline environments.
As a software framework, extensibility by users is a central aspect of the VISR.
This can be done by arranging existing building blocks in new ways, incorporating new atomic functionality, or combinations thereof.

There are many existing software projects for audio processing, from DSP and sound synthesis languages as Faust \phantomsection\label{\detokenize{visr-python-tutorial:id4}}{\hyperref[\detokenize{visr-python-tutorial:tut-orlarey-fober-letz2004-syntactical-and-semantic-aspects-of-faust}]{\sphinxcrossref{{[}T4{]}}}}, CSound \phantomsection\label{\detokenize{visr-python-tutorial:id5}}{\hyperref[\detokenize{visr-python-tutorial:tut-boulanger2000-the-csound-book}]{\sphinxcrossref{{[}T5{]}}}}, and SuperCollider \phantomsection\label{\detokenize{visr-python-tutorial:id6}}{\hyperref[\detokenize{visr-python-tutorial:tut-wilson-cottle-collins2011-the-supercollider-book}]{\sphinxcrossref{{[}T6{]}}}}; libraries of spatial processing components as IRCAM’s Spat \phantomsection\label{\detokenize{visr-python-tutorial:id7}}{\hyperref[\detokenize{visr-python-tutorial:tut-carpentier-noisternig-warusfel2015-twenty-years-of-ircam-spat-looking-back-looking-forward}]{\sphinxcrossref{{[}T7{]}}}};  frameworks as CLAM \phantomsection\label{\detokenize{visr-python-tutorial:id8}}{\hyperref[\detokenize{visr-python-tutorial:tut-amatriain-arumi-garcia2008-a-platform-for-efficient-and-rapid-development-of-cross-platform-audio-applications}]{\sphinxcrossref{{[}T8{]}}}}; Matlab software as the Audio System Toolbox; or rendering applications as the SoundScape Renderer \phantomsection\label{\detokenize{visr-python-tutorial:id9}}{\hyperref[\detokenize{visr-python-tutorial:tut-geier-hohn-spors2012-an-open-source-c-framework-for-multithreaded-realtime-multichannel-applications}]{\sphinxcrossref{{[}T9{]}}}}.

Compared to these projects, we believe that the main advantages of VISR emerge as a combination of the following features:
Firstly, its relatively high level of abstraction based on a component-based, object-oriented architecture enables the creation of complex audio processing schemes with relative ease.
Secondly, the VISR is open-source and highly portable, supporting Windows, Mac OS X, and Linux including single-board computers as the Raspberry Pi, as well as integration into software environments as digital audio workstations (DAWs) or Max/MSP.
Thirdly, the use of Python as an additional implementation language significantly improves the productivity of using the framework and makes it more approachable to users that are not expert programmers.
Finally, and closely related to the Python integration, the VISR framework allows a seamless integration of audio algorithm development with interactive realtime rendering and subjective evaluation.


\section{The VISR Framework}
\label{\detokenize{visr-python-tutorial:the-visr-framework}}\label{\detokenize{visr-python-tutorial:visr-tutorial-sec-visr-framework}}
This section explains the main concepts and entities in the VISR framework.


\subsection{Component-Based Design}
\label{\detokenize{visr-python-tutorial:component-based-design}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.600\linewidth]{{visr_component_schematic1}.png}
\caption{General interface of a VISR component.}\label{\detokenize{visr-python-tutorial:id20}}\label{\detokenize{visr-python-tutorial:figure-visr-tutorial-visr-component-schematic}}\end{figure}

VISR is a software framework, which means that it enables a systematic reuse of functionalities and is designed for extension by users.
To this, all processing tasks are implemented within \sphinxstyleemphasis{components}, software entities that communicate with other components and the external environment through a defined, common interface.
Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-tutorial-visr-component-schematic}]{\sphinxcrossref{\DUrole{std,std-ref}{General interface of a VISR component.}}}} depicts the general structure of a component.
Configuration parameters are passed to the component’s constructor to customize its behavior.
The external interface of components is defined by ports, which can be connected to other components or may represent external communication.


\subsection{Audio and Parameter Ports}
\label{\detokenize{visr-python-tutorial:audio-and-parameter-ports}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-ports}}
\sphinxstyleemphasis{Ports} represent data inputs and outputs of a component.
They enable a configurable, directional flow of information between components or with the outside environment.
There are two distinct types of ports: audio and parameter ports.
Audio ports receive or create multichannel audio signals with an arbitrary, configurable number of channels (single audio signal waveforms), which is referred as the \sphinxstyleemphasis{width} of the port.
Audio ports are configured with a unique name, a width and a sample type such as \sphinxcode{\sphinxupquote{float}} or \sphinxcode{\sphinxupquote{int16}}.

Parameter ports, on the other hand, convey control and parameter information between components or from and to the external environment.
Parameter data is significantly more diverse than audio data.
For example, parameter data used in the BST includes vectors of gain or delay values, FIR or IIR filter coefficients, audio object metadata, and structures to represent the listener’s orientation.
In addition to the data type, there are also different communication semantics for parameters.
For example, data can change in each iteration of the audio processing, be updated only sporadically, or communicated through messages queues.
In VISR, these semantics are termed \sphinxstyleemphasis{communication protocols} and form an additional property of a parameter port.
The semantics described above are implemented by the communication protocols \sphinxcode{\sphinxupquote{SharedData}}, \sphinxcode{\sphinxupquote{DoubleBuffering}}, and \sphinxcode{\sphinxupquote{MessageQueue}}, respectively.

Several parameter types feature additional configuration data, such as the dimensions of a matrix parameter.
In the VISR framework, such options are passed in \sphinxcode{\sphinxupquote{ParameterConfig}} objects.
This allows extensive type checking, for instance to ensure that only matrix parameters of matching dimensions are connected.
Combining these features, a parameter port is described by these properties: a unique name, a parameter type, a communication protocol type and an optional parameter configuration object.


\subsection{Atomic Components}
\label{\detokenize{visr-python-tutorial:atomic-components}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-atomic-components}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.600\linewidth]{{visr_atomic_component1}.png}
\caption{VISR atomic component.}\label{\detokenize{visr-python-tutorial:id21}}\label{\detokenize{visr-python-tutorial:figure-visr-tutorial-visr-atomic-component}}\end{figure}

To create and reuse more complex functionality out of existing building blocks, VISR signal flows can be structured hierarchically.
To this end, there are two different kinds of components in VISR, \sphinxstyleemphasis{atomic} and \sphinxstyleemphasis{composite}.
They have the same external interface, that means that they can be used in the same way.
Fig. {\hyperref[\detokenize{visr-python-tutorial:figure-visr-tutorial-visr-atomic-component}]{\sphinxcrossref{\DUrole{std,std-ref}{VISR atomic component.}}}} schematically depicts these two types.
\sphinxstyleemphasis{Atomic components} implement processing task in program code, e.g., in C++ or Python.
They feature a constructor which may take a variety of configuration options to tailor the behaviour of the component and to initialize its state.
The operation of an atomic component is implemented in the \sphinxcode{\sphinxupquote{process()}} method.
It typically involves accessing audio input data, performing DSP operations on it and writing it to audio outputs, or receiving, manipulating, and creating parameter data.
Examples how atomic components are implemented are given in Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-example-prototyping-algorithms}]{\sphinxcrossref{\DUrole{std,std-ref}{Prototyping Atomic functionality}}}}.


\subsection{Composite Components}
\label{\detokenize{visr-python-tutorial:composite-components}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-composite-components}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.600\linewidth]{{visr_composite_component1}.png}
\caption{VISR composite component.}\label{\detokenize{visr-python-tutorial:id22}}\label{\detokenize{visr-python-tutorial:figure-visr-tutorial-visr-composite-component}}\end{figure}

In contrast, a \sphinxstyleemphasis{composite component} contains a set of interconnected components (atomic or composite) to define its behavior.
This is depicted in Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-tutorial-visr-composite-component}]{\sphinxcrossref{\DUrole{std,std-ref}{VISR composite component.}}}}.
This allows the specification of more complex signal flows in terms of existing functionality, but also the reuse of such complex signal flows.
As their atomic counterparts, they may take a rich set of constructor options.
These can control which contained components are constructed, how they are configured, and how they are connected.
It is worth noting that nested components do not impair computational efficiency because the hierarchy is flattened at initialization time and therefore not visible to the runtime engine.

Using hierarchy to structure signal flows is a powerful and central technique in the VISR framework.
As explained in more detail later, its uses include the reuse of processing functionality and enabling the use of components in different software environments.


\subsection{Standard Component Library}
\label{\detokenize{visr-python-tutorial:standard-component-library}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-rcl}}
The runtime component library (\sphinxcode{\sphinxupquote{rcl}}) of the VISR framework contains a number of
components for general-purpose DSP and object-based audio operations.
They are typically implemented in C++ and therefore relatively efficient.
The \sphinxcode{\sphinxupquote{rcl}} library includes arithmetic operations on multichannel signals, gain vectors and matrices, delay lines, FIR and IIR filtering blocks, but also network senders and receivers and components for decoding and handling of object audio metadata.


\subsection{Runtime Engine}
\label{\detokenize{visr-python-tutorial:runtime-engine}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-runtime-engine}}
A key objective of the VISR framework is to enable users to focus on their processing task \textendash{} performed in a component \textendash{} while automating tedious tasks, such as error checking, communication between components, or interfacing audio hardware, as far as possible.
The rendering runtime library (\sphinxcode{\sphinxupquote{rrl}}) serves this purpose.
Starting from a top-level component, it is only necessary to construct an object of type \sphinxcode{\sphinxupquote{AudioSignalFlow}} for this component.
All operations from consistency checking to the initialization of memory buffers and data structures for rendering is performed by this object.
The \sphinxcode{\sphinxupquote{audiointerfaces}} library provides abstractions for different audio interface APIs (such as Jack, PortAudio, or ASIO).
Realtime rendering is started by connecting the \sphinxcode{\sphinxupquote{SignalFlow}} object to an
\sphinxcode{\sphinxupquote{audiointerfaces}} object.


\subsection{Python interface}
\label{\detokenize{visr-python-tutorial:python-interface}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-python-interface}}
While the core of the VISR framework is implemented in C++, it provides a full application programming interface (API) for the Python programming language.
This is to enable users to adapt or extend signal flows more productively, using an interpreted language with a more accessible, readable syntax and enabling the use of rich libraries for numeric computing and DSP, such as NumPy and SciPy \phantomsection\label{\detokenize{visr-python-tutorial:id10}}{\hyperref[\detokenize{visr-python-tutorial:tut-oliphant2007-python-for-scientific-computing}]{\sphinxcrossref{{[}T10{]}}}}.
The Python API can be used in three principal ways:


\subsubsection{Configuring and running signal flows}
\label{\detokenize{visr-python-tutorial:configuring-and-running-signal-flows}}
Components can be created and configured from the interactive Python interpreters or script files.
This makes this task fully programmable and removes the need for external scripts to configure renders.
In the same way, audio interfaces can be configured, instantiated and started from within Python, enabling realtime rendering from within an interactive interpreter.


\subsubsection{Extending and creating signal flow}
\label{\detokenize{visr-python-tutorial:extending-and-creating-signal-flow}}
As described above, complex signal flows are typically created as composite components.
This can be done in Python by deriving a class from the base class \sphinxcode{\sphinxupquote{visr.CompositeComponent}}.
The behavior of the signal flow is defined in the class’ constructor by creating external ports, contained components, and their interconnections.
Instances of this class can be used for realtime rendering from the Python interpreter, as described above, or from a standalone application.


\subsubsection{Adding atomic functionality}
\label{\detokenize{visr-python-tutorial:adding-atomic-functionality}}
In the same way as composites, atomic components can be implemented by deriving from \sphinxcode{\sphinxupquote{visr.AtomicComponent}}.
This involves implementing the constructor set up the component and the \sphinxcode{\sphinxupquote{process()}} method that performs the run-time processing.
The resulting objects can be embedded in either Python or C++ composite components (via a helper class \sphinxcode{\sphinxupquote{PythonWrapper}}).


\subsubsection{Offline Rendering}
\label{\detokenize{visr-python-tutorial:offline-rendering}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-offline-rendering}}
By virtue of the Python integration, signal flows implemented as components are not limited to realtime rendering, but can also be executed in an offline programming environment.
Because the top-level audio and parameter ports of a component can be accessed externally, dynamic rendering features such as moving objects or head movements can be simulated in a deterministic way.
In the majority of uses, this is most conveniently performed in an interactive Python environment.
Applications of this feature range from regression tests of atomic components or complex composite signal flows, performance simulations, to offline rendering of complete sound scenes.


\subsubsection{Use in multiple software environments}
\label{\detokenize{visr-python-tutorial:use-in-multiple-software-environments}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-use-multiple-enironments}}
The VISR framework aims to ease the reuse of audio processing functionality in different software environments, for instance as plugins for digital audio workstations (DAWs) or as blocks in visual programming languages as Max/MSP.
The main goal is to make the functionality available to a larger group of users, enable them to integrate them into their workflow, and to use it as building blocks for their applications.
Moreover, providing software components that are integrated into a host environment often reduces the complexity of a audio processing system, as opposed to a standalone renderer that requires a separate binary, dedicated connections, and possibly an additional computer.

Such an integration is enabled both by architectural features of the framework and support libraries that are part of VISR.
Firstly, the modular design, in particular the component abstraction which is independent of a specific audio API or a specific model of execution, enables running VISR components within a multitude of software environments.
Secondly, the extensible parameter subsystem that makes control data input and output accessible from outside the components eases a translation to the host-specific communication mechanism.
Finally, VISR contains a set of support libraries that simplifies the translation between the VISR interfaces and the API of the host environment and reduces the necessary amount of code for wrapping a VISR component in, e.g, a VST plugin or a Max/MSP external.


\section{Application Example: Panning Algorithm Development}
\label{\detokenize{visr-python-tutorial:application-example-panning-algorithm-development}}\label{\detokenize{visr-python-tutorial:visr-tutorial-sec-application-example}}
In this section we explain the use of the VISR framework in a continued application example.
To this end we describe the prototyping and testing of a multichannel amplitude panning technique.
For expressiveness and conciseness, the examples are presented in the Python language.
However, the same functionality could also be achieved in C++ at the expense of an increased code size and a steeper learning curve.
This tutorial example displays only relevant code sections, sometimes in abridged form.
The full source code is available through \phantomsection\label{\detokenize{visr-python-tutorial:id11}}{\hyperref[\detokenize{visr-python-tutorial:tut-s3a2018-visr-download-site}]{\sphinxcrossref{{[}T11{]}}}}.


\subsection{Obtaining and installing the VISR framework}
\label{\detokenize{visr-python-tutorial:obtaining-and-installing-the-visr-framework}}
The VISR framework is available under a permissive open-source license which allows for free use and modification.
Installation packages and setup instructions are provided in section {\hyperref[\detokenize{getting-visr:getting-visr}]{\sphinxcrossref{\DUrole{std,std-ref}{Getting VISR}}}}.
To use the Python integration, Python 3 must be installed.
For Windows ans Mac OS we recommend the Anaconda distribution (\sphinxurl{https://anaconda.org/}).
Note that the installer must match the Python major and minor version number on the target system, e.g., Python 3.5.


\subsection{Creating and Adapting Signal Flows}
\label{\detokenize{visr-python-tutorial:creating-and-adapting-signal-flows}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{vbap_panner}.png}
\caption{Basic amplitude panning system for real-time rendering.}\label{\detokenize{visr-python-tutorial:id23}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-vbap-panner}}\end{figure}

The most basic way to create and adapt audio processing functionality in the VISR framework is to parameterize and connect existing building blocks.
To this end we create a new \sphinxcode{\sphinxupquote{CompositeComponent}}.
We demonstrate that by building a simple multichannel amplitude panning renderer, which is schematically depicted in Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-vbap-panner}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic amplitude panning system for real-time rendering.}}}}.
The corresponding source file is \sphinxcode{\sphinxupquote{vbap\_renderer.py}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{import} \PYG{n+nn}{visr}\PYG{o}{,} \PYG{n+nn}{pml}\PYG{o}{,} \PYG{n+nn}{rcl}
\PYG{k}{class} \PYG{n+nc}{VbapRenderer}\PYG{p}{(} \PYG{n}{visr}\PYG{o}{.}\PYG{n}{CompositeComponent} \PYG{p}{)}\PYG{p}{:}
\end{sphinxVerbatim}

This starts by importing several Python modules that provide VISR functionality, namely \sphinxcode{\sphinxupquote{visr}} for the core API, \sphinxcode{\sphinxupquote{rcl}} for the built-in component library (see Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-rcl}]{\sphinxcrossref{\DUrole{std,std-ref}{Standard Component Library}}}}) and the \sphinxcode{\sphinxupquote{pml}} for parameter data and communication protocols (Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-ports}]{\sphinxcrossref{\DUrole{std,std-ref}{Audio and Parameter Ports}}}}).
The signal flow class \sphinxcode{\sphinxupquote{VbapRenderer}} is derived from the VISR base class \sphinxcode{\sphinxupquote{visr.CompositeComponent}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(} \PYG{n}{context}\PYG{p}{,} \PYG{n}{name}\PYG{p}{,} \PYG{n}{parent}\PYG{p}{,}
              \PYG{n}{numObjects}\PYG{p}{,} \PYG{n}{lspConfig} \PYG{p}{)}\PYG{p}{:}
  \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(} \PYG{n}{context}\PYG{p}{,} \PYG{n}{name}\PYG{p}{,} \PYG{n}{parent} \PYG{p}{)}
\end{sphinxVerbatim}

As explained in Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-composite-components}]{\sphinxcrossref{\DUrole{std,std-ref}{Composite Components}}}}, the functionality of a composite component is embodied in its constructor, which defines external inputs and outputs, the contained components, and their connections.
Here, the constructor takes the standard parameters \sphinxcode{\sphinxupquote{context}} to specify audio block size and sampling rate, \sphinxcode{\sphinxupquote{name}} to assign a unique name, and \sphinxcode{\sphinxupquote{parent}} for an optional parent component (\sphinxcode{\sphinxupquote{None}} denotes a top-level flow).
The class-specific parameters \sphinxcode{\sphinxupquote{numObjects}} and \sphinxcode{\sphinxupquote{lspConfig}} customize instances of this specific class.
The call \sphinxcode{\sphinxupquote{super().\_\_init\_\_(...)}} initializes the base class object..

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioIn} \PYG{o}{=} \PYG{n}{visr}\PYG{o}{.}\PYG{n}{AudioInputFloat}\PYG{p}{(} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{in}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{numObjects} \PYG{p}{)}
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioOut} \PYG{o}{=} \PYG{n}{visr}\PYG{o}{.}\PYG{n}{AudioOutputFloat}\PYG{p}{(} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{out}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{numLsp} \PYG{p}{)}
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objectIn} \PYG{o}{=} \PYG{n}{visr}\PYG{o}{.}\PYG{n}{ParameterInput}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{objects}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}\PYG{n+nb+bp}{self}\PYG{p}{,}
    \PYG{n}{pml}\PYG{o}{.}\PYG{n}{ObjectVector}\PYG{o}{.}\PYG{n}{staticType}\PYG{p}{,}
    \PYG{n}{pml}\PYG{o}{.}\PYG{n}{DoubleBufferingProtocol}\PYG{o}{.}\PYG{n}{staticType}\PYG{p}{,}
    \PYG{n}{pml}\PYG{o}{.}\PYG{n}{EmptyParameterConfig}\PYG{p}{(}\PYG{p}{)} \PYG{p}{)}
\end{sphinxVerbatim}

Here, we define an audio input and an audio output as well as an parameter input to receive object metadata.
The simple panning renderer contains two components, \sphinxcode{\sphinxupquote{VbapGainCalculator}} and \sphinxcode{\sphinxupquote{GainMatrix}}. The former calculates a matrix of panning gains from set of object metadata, and the latter applies these gains to a set of object audio signals to form loudspeaker outputs.
These components are instantiated as members variables of the \sphinxcode{\sphinxupquote{VbapRenderer}} class.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{calculator} \PYG{o}{=} \PYG{n}{rcl}\PYG{o}{.}\PYG{n}{PanningCalculator}\PYG{p}{(}
  \PYG{n}{context}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{VbapGainCalculator}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n+nb+bp}{self}\PYG{p}{,}
  \PYG{n}{numberOfObjects}\PYG{p}{,} \PYG{n}{lspConfig} \PYG{p}{)}
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{matrix} \PYG{o}{=} \PYG{n}{rcl}\PYG{o}{.}\PYG{n}{GainMatrix}\PYG{p}{(} \PYG{n}{context}\PYG{p}{,}
  \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{GainMatrix}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{numberOfObjects}\PYG{p}{,} \PYG{n}{numLsp}
  \PYG{n}{interpolationSteps}\PYG{o}{=}\PYG{n}{context}\PYG{o}{.}\PYG{n}{period} \PYG{p}{)}
\end{sphinxVerbatim}

Finally, connection between the components’ input and output ports as well as external ports are defined by using API methods of \sphinxcode{\sphinxupquote{CompositeComponent}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioConnection}\PYG{p}{(} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioIn}\PYG{p}{,}
  \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{matrix}\PYG{o}{.}\PYG{n}{audioPort}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{in}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)} \PYG{p}{)}
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioConnection}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{matrix}\PYG{o}{.}\PYG{n}{audioPort}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{out}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioOut}\PYG{p}{)}
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{parameterConnection}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objectIn}\PYG{p}{,}
  \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{calculator}\PYG{o}{.}\PYG{n}{parameterPort}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{objectIn}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{)}
\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{parameterConnection}\PYG{p}{(}
  \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{calculator}\PYG{o}{.}\PYG{n}{parameterPort}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{gainOutput}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{)}\PYG{p}{,}
  \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{matrix}\PYG{o}{.}\PYG{n}{parameterPort}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{gainInput}\PYG{l+s+s2}{\PYGZdq{}} \PYG{p}{)}\PYG{p}{)}
\end{sphinxVerbatim}

This example shows how complex, multichannel signal flows can be readily created in VISR using high-level building blocks and sophisticated multichannel audio and data connections.

To use the \sphinxcode{\sphinxupquote{VbapRenderer}} in a realtime setting, we must provide means to receive audio object metadata, e.g., from an audio workstation.
In the VISR framework, this is best done by creating a new top-level composite component, denoted \sphinxcode{\sphinxupquote{RealtimeVbapRenderer}} in Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-vbap-panner}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic amplitude panning system for real-time rendering.}}}}, that contains the \sphinxcode{\sphinxupquote{VbapRenderer}} and means to receive and decode object metadata from network messages.
This is done by the components \sphinxcode{\sphinxupquote{UdpReceiver}} and \sphinxcode{\sphinxupquote{SceneDecoder}}, both contained in the VISR \sphinxcode{\sphinxupquote{rcl}} library.
Organizing functionality hierarchically into composite components, including moving supplemental tasks as network communication outside the core algorithm, is recurring design pattern in VISR signal flows.
As demonstrated in later sections, it fosters reuse of functionality and helps to use the same algorithm in different software environments.


\subsection{Realtime Execution and Binaural Auralization}
\label{\detokenize{visr-python-tutorial:realtime-execution-and-binaural-auralization}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-example-realtime-and-binaural}}
Components \textendash{} both composite and atomic \textendash{} can be readily used for realtime rendering, both as a standalone application or from a Python session.
We first describe the latter, interactive approach.
To run a VISR component, we first construct an object of type \sphinxcode{\sphinxupquote{rrl.AudioSignalFlow}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{import} \PYG{n+nn}{rrl}
\PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
\PYG{n}{flow} \PYG{o}{=} \PYG{n}{rrl}\PYG{o}{.}\PYG{n}{AudioSignalFlow}\PYG{p}{(} \PYG{n}{component} \PYG{p}{)}
\end{sphinxVerbatim}

It contains all information and data structures needed to execute the component’s signal flow.
During construction, it flattens hierarchical signal flows and performs consistency checks.

In a second step we create an \sphinxcode{\sphinxupquote{AudioInterface}} object representing an audio device, e.g., a sound card.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{flow} \PYG{o}{=} \PYG{n}{rrl}\PYG{o}{.}\PYG{n}{AudioSignalFlow}\PYG{p}{(} \PYG{n}{renderer} \PYG{p}{)}
\PYG{n}{aiConfig} \PYG{o}{=} \PYG{n}{ai}\PYG{o}{.}\PYG{n}{AudioInterface}\PYG{o}{.}\PYG{n}{Configuration}\PYG{p}{(}
\PYG{n}{aIfc} \PYG{o}{=} \PYG{n}{ai}\PYG{o}{.}\PYG{n}{AudioInterfaceFactory}\PYG{o}{.}\PYG{n}{create}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{PortAudio}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}
 \PYG{n}{numberOfInputs}\PYG{o}{=}\PYG{n}{numObjects}\PYG{p}{,} \PYG{n}{numberOfOutputs}\PYG{o}{=}\PYG{l+m+mi}{2}\PYG{p}{,}
 \PYG{n}{samplingFrequency}\PYG{o}{=}\PYG{n}{fs}\PYG{p}{,} \PYG{n}{period}\PYG{o}{=}\PYG{n}{bs} \PYG{p}{)}
\PYG{n}{aIfc}\PYG{o}{.}\PYG{n}{registerCallback}\PYG{p}{(} \PYG{n}{flow} \PYG{p}{)}
\PYG{n}{aIfc}\PYG{o}{.}\PYG{n}{start}\PYG{p}{(}\PYG{p}{)}
\end{sphinxVerbatim}

At the moment the \sphinxcode{\sphinxupquote{audiointerfaces}} library contains classes for two backends, namely the cross-platform PortAudio library (\sphinxurl{http://www.portaudio.com/}) and the Jack sound server (\sphinxurl{http://www.jackaudio.org/}) (Linux and Mac OS X).
Additional backends can be implemented in the future, which is supported by the \sphinxcode{\sphinxupquote{AudioInterfaceFactory}} factory interface to instantiate audio interfaces.
This method accepts also an optional \sphinxcode{\sphinxupquote{optionalConfig}} parameter to pass backend-specific options.

The second way to run a VISR signal flow is to build a standalone application, typically in C++.
This application would create an instance of the VISR component to be executed, and could use the functionality of the \sphinxcode{\sphinxupquote{audiointerfaces}} and \sphinxcode{\sphinxupquote{rrl}} libraries to perform the realtime rendering.
For top-level components implemented in Python, a simpler way exists by using the \sphinxcode{\sphinxupquote{python\_wrapper}} application that is included in the VISR distribution.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
python\PYGZus{}runner \PYGZhy{}m vbap\PYGZus{}renderer
 \PYGZhy{}c RealtimeVbapRenderer \PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}2,\PYGZsq{}../data/stereo.xml\PYGZsq{}\PYGZdq{}}
 \PYGZhy{}k \PYG{l+s+s2}{\PYGZdq{}\PYGZob{}\PYGZsq{}nwPort\PYGZsq{}: 4242\PYGZcb{}\PYGZdq{}} \PYGZhy{}D PortAudio
\end{sphinxVerbatim}

Here, \sphinxcode{\sphinxupquote{vbap\_renderer}} is the name of the Python module, \sphinxcode{\sphinxupquote{RealtimeVbapRenderer}} is the name of class name of a top-level component implemented in this module, \sphinxcode{\sphinxupquote{\$-\$D PortAudio}} denotes the audio interface to be used, while \sphinxcode{\sphinxupquote{\$-\$a}} and \sphinxcode{\sphinxupquote{\$-\$k}} are used to pass positional and keyword arguments to the component’s constructor.
For this to work, the main module (\sphinxcode{\sphinxupquote{vbap\_renderer}} in this example) and other used Python modules must be contained in the Python module search path, either by setting the \sphinxcode{\sphinxupquote{PYTHONHOME}} environment variable or by passing the path via the \sphinxcode{\sphinxupquote{\$-\$d}} option.
In this way, the \sphinxcode{\sphinxupquote{python\_runner}} utility app allows for an easy use of VISR signal flows specified in Python without requiring an interactive Python interpreter.

Because multi-loudspeaker panning algorithms require sophisticated setups, they are difficult to auralize.
The VISR framework makes it easy to couple an algorithm with tools for auralization over headphones using dynamic binaural synthesis, e.g., \phantomsection\label{\detokenize{visr-python-tutorial:id12}}{\hyperref[\detokenize{visr-python-tutorial:tut-mackensen-et-al1999-binaural-room-scanning-a-new-tool-for-acoustic-and-psychoacoustic-research}]{\sphinxcrossref{{[}T12{]}}}}\phantomsection\label{\detokenize{visr-python-tutorial:id13}}{\hyperref[\detokenize{visr-python-tutorial:tut-pike-romanov2017-an-impulse-response-dataset-for-dynamic-data-based-auralization-of-advanced-sound-systems}]{\sphinxcrossref{{[}T13{]}}}}.
The VISR framework allows for a straightforward integration of such tools.
Here we use the Binaural Synthesis Toolkit \phantomsection\label{\detokenize{visr-python-tutorial:id14}}{\hyperref[\detokenize{visr-python-tutorial:tut-franck-et-al2018-an-open-realtime-binaural-synthesis-toolkit-for-audio-research}]{\sphinxcrossref{{[}T14{]}}}}, a set of components for binaural rendering implemented in the VISR framework
The BST implements different approaches to binaural synthesis, namely dynamic HRTF-based rendering, synthesis based on Higher Order Ambisonics, and virtual loudspeaker rendering (or binaural rool scanning).
Here we use the \sphinxcode{\sphinxupquote{VirtualLoudspeakerRenderer}} component that transforms a set of loudspeaker signals into a binaural signal.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{vbap_panner_auralisation}.png}
\caption{Panning algorithm auralization.}\label{\detokenize{visr-python-tutorial:id24}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-vbap-panner-auralisation}}\end{figure}

To this end, we create a new top-level component depicted in Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-vbap-panner-auralisation}]{\sphinxcrossref{\DUrole{std,std-ref}{Panning algorithm auralization.}}}}.
It is composed of the \sphinxcode{\sphinxupquote{RealtimeVbapRenderer}} component whose loudspeaker signal output is connected to the \sphinxcode{\sphinxupquote{VirtualLoudspeakerRenderer}} instance.
The latter can also receive listener tracking information to incorporate the listener’s head orientation.
In this case, a \sphinxcode{\sphinxupquote{TrackingReceiver}} component specific to the tracking system used is instantiated and connected to the binaural module.

It is noted that the two parts could also be instantiated as separate realtime applications, and connected using a sound server as Jack.
VISR’s ability to combine the components, however, makes such applications less dependent on the capabilities of the operating system and reduces the effort to control such complex configurations.


\subsection{Prototyping Atomic functionality}
\label{\detokenize{visr-python-tutorial:prototyping-atomic-functionality}}\label{\detokenize{visr-python-tutorial:visr-tutorial-subsec-example-prototyping-algorithms}}
In addition to creating new functionality by interconnecting existing components, the VISR framework can be extended by implementing new primitive (or atomic) functionality as C++ or Python code.
This is done by creating new atomic components, which can then be used either standalone or combined with other VISR components.
In this section we demonstrate this functionality by prototyping a novel multi-loudspeaker panner \textendash{} an algorithm for calculating loudspeaker gains \textendash{} as an atomic component in Python.
The novelty of this approach is that it uses a convex optimization algorithm to compute a solution with similar properties to VBAP, but uses \(\ell_{2}\) optimality to resolve ambiguity issues of VBAP, see \phantomsection\label{\detokenize{visr-python-tutorial:id15}}{\hyperref[\detokenize{visr-python-tutorial:tut-hughes-et-al2018-dual-frequency-amplitude-panning-for-multichannel-audio-systems}]{\sphinxcrossref{{[}T15{]}}}}.
Using the VISR framework it is possible to use the rich set of libraries for technical and scientific computing available in Python, in this case the numerical optimization package \sphinxstylestrong{cvxpy} \phantomsection\label{\detokenize{visr-python-tutorial:id16}}{\hyperref[\detokenize{visr-python-tutorial:tut-diamond-boyd2016-cvxpy}]{\sphinxcrossref{{[}T16{]}}}}, for algorithm prototyping and realtime evaluation.
The source code can be found in \sphinxcode{\sphinxupquote{vbap\_l2\_panner.py}}.

An atomic component is implemented as a class derived from \sphinxcode{\sphinxupquote{visr.AtomicComponent}}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{VbapL2Panner}\PYG{p}{(} \PYG{n}{visr}\PYG{o}{.}\PYG{n}{AtomicComponent} \PYG{p}{)}\PYG{p}{:}
  \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
\end{sphinxVerbatim}

The component has a constructor similar to that of a composite component, taking the mandatory arguments \sphinxcode{\sphinxupquote{context}}, \sphinxcode{\sphinxupquote{name}} and \sphinxcode{\sphinxupquote{parent}} plus a custom set of configuration parameters.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(} \PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{context}\PYG{p}{,} \PYG{n}{name}\PYG{p}{,} \PYG{n}{parent}\PYG{p}{,}
  \PYG{n}{numObjects}\PYG{p}{,} \PYG{n}{lspConfig}\PYG{p}{,} \PYG{n}{spread} \PYG{p}{)}\PYG{p}{:}
  \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init}\PYG{p}{(} \PYG{n}{context}\PYG{p}{,} \PYG{n}{name}\PYG{p}{,} \PYG{n}{parent} \PYG{p}{)}
  \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objectIn} \PYG{o}{=} \PYG{n}{pml}\PYG{o}{.}\PYG{n}{ParameterInput}\PYG{p}{(} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{objects}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{n+nb+bp}{self}\PYG{p}{,}
    \PYG{n}{pml}\PYG{o}{.}\PYG{n}{DoubleBuffering}\PYG{o}{.}\PYG{n}{type}\PYG{p}{,} \PYG{n}{pml}\PYG{o}{.}\PYG{n}{ObjectVector}\PYG{o}{.}\PYG{n}{type}\PYG{p}{,}
    \PYG{n}{pml}\PYG{o}{.}\PYG{n}{EmptyParameterConfig}\PYG{p}{(}\PYG{p}{)} \PYG{p}{)}
  \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
  \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{L} \PYG{o}{=} \PYG{n}{lspConfig}
  \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
  \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{problem} \PYG{o}{=} \PYG{n}{cvxpy}\PYG{o}{.}\PYG{n}{Problem}\PYG{p}{(} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objective}\PYG{p}{,}
                                \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{constraints} \PYG{p}{)}
  \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
\end{sphinxVerbatim}

Like in composite components, the \sphinxcode{\sphinxupquote{\_\_init\_\_()}} method calls the constructor of the superclass and creates audio and parameter ports.
In addition, it sets up any internal data structures, for instance storing the loudspeaker positions in \sphinxcode{\sphinxupquote{self.L}} and setting up the optimization problem as \sphinxcode{\sphinxupquote{self.problem}}.
As described in Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-atomic-components}]{\sphinxcrossref{\DUrole{std,std-ref}{Atomic Components}}}}, atomic components implement their behavior in the \sphinxcode{\sphinxupquote{process()}} method.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{def} \PYG{n+nf}{process}\PYG{p}{(} \PYG{n+nb+bp}{self} \PYG{p}{)}\PYG{p}{:}
  \PYG{k}{if} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objectIn}\PYG{o}{.}\PYG{n}{protocol}\PYG{o}{.}\PYG{n}{changed}\PYG{p}{(}\PYG{p}{)}\PYG{p}{:}
    \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objectIn}\PYG{o}{.}\PYG{n}{protocol}\PYG{o}{.}\PYG{n}{resetChanged}\PYG{p}{(}\PYG{p}{)}
    \PYG{n}{objVec} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{objectIn}\PYG{o}{.}\PYG{n}{protocol}\PYG{o}{.}\PYG{n}{data}\PYG{p}{(}\PYG{p}{)}
    \PYG{n}{gains} \PYG{o}{=} \PYG{n}{np}\PYG{o}{.}\PYG{n}{array}\PYG{p}{(} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{gainOut}\PYG{o}{.}\PYG{n}{protocol}\PYG{o}{.}\PYG{n}{data}\PYG{p}{(}\PYG{p}{)} \PYG{p}{)}
    \PYG{n}{pointSources} \PYG{o}{=} \PYG{p}{[}\PYG{n}{o} \PYG{k}{for} \PYG{n}{o} \PYG{o+ow}{in} \PYG{n}{objVec}
     \PYG{k}{if} \PYG{n+nb}{isinstance}\PYG{p}{(} \PYG{n}{o}\PYG{p}{,} \PYG{n}{objectmodel}\PYG{o}{.}\PYG{n}{PointSource} \PYG{p}{)}\PYG{p}{]}\PYG{p}{]}
    \PYG{k}{for} \PYG{n}{obj} \PYG{o+ow}{in} \PYG{n}{pointSources}\PYG{p}{:}
      \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{b}\PYG{o}{.}\PYG{n}{value} \PYG{o}{=} \PYG{n}{obj}\PYG{o}{.}\PYG{n}{position}
      \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{problem}\PYG{o}{.}\PYG{n}{solve}\PYG{p}{(}\PYG{p}{)}
      \PYG{n}{gains}\PYG{p}{[}\PYG{p}{:}\PYG{p}{,}\PYG{n}{obj}\PYG{o}{.}\PYG{n}{id}\PYG{p}{]} \PYG{o}{=} \PYG{n}{normalise}\PYG{p}{(} \PYG{n}{np}\PYG{o}{.}\PYG{n}{squeeze}\PYG{p}{(}
        \PYG{n}{np}\PYG{o}{.}\PYG{n}{asarray}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{g}\PYG{o}{.}\PYG{n}{value}\PYG{p}{)} \PYG{p}{)}\PYG{p}{,} \PYG{n}{norm}\PYG{o}{=}\PYG{l+m+mi}{2} \PYG{p}{)}
\end{sphinxVerbatim}

Here, the code first gains access to the object vector input and checks if the input has changed.
In this case, both the current object vector and the output gain matrix are obtained, and the computation is performed.
This consists of calling the optimization method for each point source object and assigning the resulting gain vector to the respective row in the panning gain matrix.
The resulting component can be used in the same way as a built-in atomic component. That is, it can be executed as a standalone top-level component or in a composite flow defined in either Python or C++.

As an example for an audio-processing atomic component we show a simplified gain matrix as used in the VBAP renderers.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{GainMatrix}\PYG{p}{(} \PYG{n}{visr}\PYG{o}{.}\PYG{n}{AtomicComponent} \PYG{p}{)}\PYG{p}{:}
  \PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{context}\PYG{p}{,}\PYG{n}{name}\PYG{p}{,}\PYG{n}{parent}\PYG{p}{,}\PYG{n}{nIn}\PYG{p}{,}\PYG{n}{nOut}\PYG{p}{)}\PYG{p}{:}
   \PYG{n+nb}{super}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(} \PYG{n}{context}\PYG{p}{,} \PYG{n}{name}\PYG{p}{,} \PYG{n}{parent} \PYG{p}{)}
   \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioIn}\PYG{o}{=}\PYG{n}{visr}\PYG{o}{.}\PYG{n}{AudioInputFloat}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{in}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{nIn}\PYG{p}{)}
   \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioOut}\PYG{o}{=}\PYG{n}{visr}\PYG{o}{.}\PYG{n}{AudioOutputFloat}\PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{out}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}\PYG{n+nb+bp}{self}\PYG{p}{,}\PYG{n}{nOut}\PYG{p}{)}
   \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{mtxIn}\PYG{o}{=}\PYG{n}{visr}\PYG{o}{.}\PYG{n}{ParameterInput}\PYG{p}{(} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{gainInput}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}
     \PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{pml}\PYG{o}{.}\PYG{n}{MatrixParameterFloat}\PYG{o}{.}\PYG{n}{staticType}\PYG{p}{,}
     \PYG{n}{pml}\PYG{o}{.}\PYG{n}{SharedDataProtocol}\PYG{o}{.}\PYG{n}{staticType}\PYG{p}{,}
     \PYG{n}{pml}\PYG{o}{.}\PYG{n}{MatrixParameterConfig}\PYG{p}{(}\PYG{n}{nOut}\PYG{p}{,} \PYG{n}{nIn} \PYG{p}{)}\PYG{p}{)}
  \PYG{k}{def} \PYG{n+nf}{process}\PYG{p}{(} \PYG{n+nb+bp}{self} \PYG{p}{)}\PYG{p}{:}
   \PYG{n}{gains}  \PYG{o}{=} \PYG{n}{np}\PYG{o}{.}\PYG{n}{array}\PYG{p}{(} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{mtxIn}\PYG{o}{.}\PYG{n}{protocol}\PYG{o}{.}\PYG{n}{data}\PYG{p}{(}\PYG{p}{)} \PYG{p}{)}
   \PYG{n}{ins} \PYG{o}{=} \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioIn}\PYG{o}{.}\PYG{n}{data}\PYG{p}{(}\PYG{p}{)}
   \PYG{n+nb+bp}{self}\PYG{o}{.}\PYG{n}{audioOut}\PYG{o}{.}\PYG{n}{set}\PYG{p}{(} \PYG{n}{gains} \PYG{o}{\PYGZlt{}}\PYG{n}{at}\PYG{o}{\PYGZgt{}} \PYG{n}{ins} \PYG{p}{)}
\end{sphinxVerbatim}

It defines an audio input and an audio output with distinct widths and a parameter input to receive the gain coefficients.
The \sphinxcode{\sphinxupquote{process()}} function accesses the sample data of the audio ports as \sphinxstylestrong{NumPy} arrays and uses the matrix multiplication operator \sphinxcode{\sphinxupquote{@}} to calculate the result.
This shows how numeric and DSP functionality can be prototyped on a high level of abstraction.
But if required, the \sphinxcode{\sphinxupquote{AudioPort}} interface also enables access to individual audio channels and samples.


\subsection{Offline Testing and Objective Evaluation}
\label{\detokenize{visr-python-tutorial:offline-testing-and-objective-evaluation}}
As explained in Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-offline-rendering}]{\sphinxcrossref{\DUrole{std,std-ref}{Offline Rendering}}}}, VISR enables the offline execution and analysis of components, both C++ and Python, within an interactive Python environment
This allows for the use of the same source code for algorithm development, offline processing, and realtime rendering.
In this section we show how this feature is used to design and evaluate the panning component created in Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-example-prototyping-algorithms}]{\sphinxcrossref{\DUrole{std,std-ref}{Prototyping Atomic functionality}}}}.
The source code is contained in the file \sphinxcode{\sphinxupquote{simulate\_l2\_renderer.py}}.

The code for the offline simulation is very similar to the realtime case shown in Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-example-realtime-and-binaural}]{\sphinxcrossref{\DUrole{std,std-ref}{Realtime Execution and Binaural Auralization}}}}.
As there, the main tasks consist of configuring and creating the top-level component and the creation of an \sphinxcode{\sphinxupquote{AudioSignalFlow}} object.
But instead of instantiating and registering to an audio interface, the multichannel audio input is provided as a matrix of samples,
and another matrix is provided for the output signals.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{fs}\PYG{p}{,}\PYG{n}{inSignal}\PYG{o}{=}\PYG{n}{scipy}\PYG{o}{.}\PYG{n}{io}\PYG{o}{.}\PYG{n}{wavfile}\PYG{o}{.}\PYG{n}{read}\PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{test.wav}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}\PYG{o}{.}\PYG{n}{T}
\PYG{n}{sigLen}\PYG{o}{=}\PYG{n}{inSignal}\PYG{o}{.}\PYG{n}{shape}\PYG{p}{[}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{p}{]}
\PYG{n}{outSignal}\PYG{o}{=}\PYG{n}{np}\PYG{o}{.}\PYG{n}{zeros}\PYG{p}{(} \PYG{p}{(}\PYG{n}{numLsp}\PYG{p}{,} \PYG{n}{sigLen} \PYG{p}{)} \PYG{p}{)}
\end{sphinxVerbatim}

Parameter data is transferred to and from top-level parameter ports by retrieving their communication protocol endpoints through the AudioSignalFlow object.
In this example, the signal flow has a parameter input named \sphinxcode{\sphinxupquote{objects}} to receive object metadata.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{objectIn} \PYG{o}{=} \PYG{n}{flowparameterReceivePort}\PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{objects}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}
\end{sphinxVerbatim}

Data can be sent and received using the semantics of the port’s communication protocol.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{numBlocks} \PYG{o}{=} \PYG{n}{sigLen} \PYG{o}{/}\PYG{o}{/} \PYG{n}{bs}
\PYG{k}{for} \PYG{n}{bi} \PYG{o+ow}{in} \PYG{n+nb}{range}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{,}\PYG{n}{numBlocks}\PYG{p}{)}\PYG{p}{:}
  \PYG{n}{ps} \PYG{o}{=} \PYG{n}{objectmodel}\PYG{o}{.}\PYG{n}{PointSource}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{)}
  \PYG{n}{ps}\PYG{o}{.}\PYG{n}{pos} \PYG{o}{=} \PYG{n}{trajectory}\PYG{p}{[}\PYG{n}{bi}\PYG{p}{,}\PYG{p}{:}\PYG{p}{]}
  \PYG{n}{ps}\PYG{o}{.}\PYG{n}{level} \PYG{o}{=} \PYG{l+m+mi}{1}
  \PYG{n}{ps}\PYG{o}{.}\PYG{n}{channels} \PYG{o}{=} \PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}
  \PYG{n}{objectIn}\PYG{o}{.}\PYG{n}{data}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{set}\PYG{p}{(}\PYG{p}{[}\PYG{n}{ps}\PYG{p}{]}\PYG{p}{)}
  \PYG{n}{objectIn}\PYG{o}{.}\PYG{n}{swapBuffers}\PYG{p}{(}\PYG{p}{)}
  \PYG{n}{outSignal}\PYG{p}{[}\PYG{p}{:}\PYG{p}{,}\PYG{n}{bi}\PYG{o}{*}\PYG{n}{bs}\PYG{p}{:}\PYG{p}{(}\PYG{n}{bi}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{p}{)}\PYG{o}{*}\PYG{n}{bs}\PYG{p}{]}
     \PYG{o}{=} \PYG{n}{flow}\PYG{o}{.}\PYG{n}{process}\PYG{p}{(} \PYG{n}{inSignal}\PYG{p}{[}\PYG{p}{:}\PYG{p}{,}\PYG{n}{bi}\PYG{o}{*}\PYG{n}{bs}\PYG{p}{:}\PYG{p}{(}\PYG{n}{bi}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{p}{)}\PYG{o}{*}\PYG{n}{bs}\PYG{p}{]} \PYG{p}{)}
\end{sphinxVerbatim}

Here, the audio signal is partitioned into a number of blocks.
For each block, a point source object with a new position is created and transmitted to the rendering component using the methods \sphinxcode{\sphinxupquote{set()}} and \sphinxcode{\sphinxupquote{swapBuffers()}} of the object vector input port.
Then the signal flow is executed for one block of input data per iteration and the generated audio samples are concatenated into a multichannel output signal.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{offline_simulation_audio_signal}.png}
\caption{Offline simulation plots of the proposed panning algorithm: Audio signal.}\label{\detokenize{visr-python-tutorial:id25}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-offline-simulation-audio-signal}}\end{figure}

Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-offline-simulation-audio-signal}]{\sphinxcrossref{\DUrole{std,std-ref}{Offline simulation plots of the proposed panning algorithm: Audio signal.}}}} shows the output signal for one loudspeaker (top-rear right position \sphinxcode{\sphinxupquote{U-135}})) of a 9-loudspeaker setup according to ITU-R BS.2051 \phantomsection\label{\detokenize{visr-python-tutorial:id17}}{\hyperref[\detokenize{visr-python-tutorial:tut-itu2017-itu-r-bs2051-1}]{\sphinxcrossref{{[}T17{]}}}} and compares it to the output of a standard VBAP implementation.
The sound object is a sinusoidal tone rotating around the central listener at a constant elevation of \(10^{\circ}\).
The plot shows that the proposed algorithm yields a more localized, monotonically ancreasing and decreasing signal magnitude as the source psition moves, whereas in the VBAP algorithm the same loudspeaker is activated for a wider range of source position and exhibits a fluctuating magnitude.
Audio signals obtained in this way can be used for playback or used as input for further analysis, e.g., by using binaural localization models.

In addition to analyzing audio signals, it is also possible to analyze smaller building blocks and their input and output parameter data.
Two features of the VISR framework make this possible.
Firstly, all building blocks are components.
That means that they can be inspected at all levels of the hierarchy, from complex top-level signal flows down to atomic algorithms.
Secondly, by exposing the extensible parameter data subsystem to the Python language, the VISR framework enables the generation of sophisticated control data trajectories and the evaluation of parameter data generated by the signal flow in an interactive programming environment.
Here, we test the \sphinxcode{\sphinxupquote{VbapL2Panner}} component separately, setting object positions for the same set of azimuths as in the previous example.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{pannerVbapL2} \PYG{o}{=} \PYG{n}{VbapL2Panner}\PYG{p}{(} \PYG{n}{ctxt}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{renderer}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{,}
   \PYG{n+nb+bp}{None}\PYG{p}{,} \PYG{n}{numObjects}\PYG{p}{,} \PYG{n}{lc} \PYG{p}{)}
\PYG{n}{flow} \PYG{o}{=} \PYG{n}{rrl}\PYG{o}{.}\PYG{n}{AudioSignalFlow}\PYG{p}{(} \PYG{n}{pannerVbapL2} \PYG{p}{)}
\PYG{n}{objectIn} \PYG{o}{=} \PYG{n}{flow}\PYG{o}{.}\PYG{n}{parameterReceivePort}\PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{objects}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}
\PYG{n}{gainOut} \PYG{o}{=} \PYG{n}{flow}\PYG{o}{.}\PYG{n}{parameterSendPort}\PYG{p}{(}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{gains}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{)}
\PYG{n}{gainsVbapL2} \PYG{o}{=} \PYG{n}{np}\PYG{o}{.}\PYG{n}{zeros}\PYG{p}{(} \PYG{p}{(}\PYG{n}{numLsp}\PYG{p}{,}\PYG{n+nb}{len}\PYG{p}{(}\PYG{n}{az}\PYG{p}{)} \PYG{p}{)}
\PYG{k}{for} \PYG{n}{bi} \PYG{o+ow}{in} \PYG{n+nb}{range}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{,}\PYG{n}{numBlocks}\PYG{p}{)}\PYG{p}{:}
  \PYG{n}{ps1} \PYG{o}{=} \PYG{n}{ojectmodel}\PYG{o}{.}\PYG{n}{PointSource}\PYG{p}{(}\PYG{l+m+mi}{0}\PYG{p}{)}
  \PYG{n}{ps1}\PYG{o}{.}\PYG{n}{position} \PYG{o}{=} \PYG{n}{sph2cart}\PYG{p}{(} \PYG{n}{az}\PYG{p}{[}\PYG{n}{bi}\PYG{p}{]}\PYG{p}{,} \PYG{n}{el}\PYG{p}{,} \PYG{n}{r} \PYG{p}{)}
  \PYG{n}{ps1}\PYG{o}{.}\PYG{n}{channels} \PYG{o}{=} \PYG{p}{[}\PYG{l+m+mi}{0}\PYG{p}{]}\PYG{p}{;} \PYG{n}{ps1}\PYG{o}{.}\PYG{n}{level}\PYG{o}{=}\PYG{l+m+mf}{1.0}
  \PYG{n}{objectIn}\PYG{o}{.}\PYG{n}{data}\PYG{p}{(}\PYG{p}{)}\PYG{o}{.}\PYG{n}{set}\PYG{p}{(} \PYG{p}{[}\PYG{n}{ps1}\PYG{p}{]} \PYG{p}{)}
  \PYG{n}{objectIn}\PYG{o}{.}\PYG{n}{swapBuffers}\PYG{p}{(}\PYG{p}{)}
  \PYG{n}{flow}\PYG{o}{.}\PYG{n}{process}\PYG{p}{(}\PYG{p}{)}
  \PYG{n}{gainsVbapL2}\PYG{p}{[}\PYG{p}{:}\PYG{p}{,}\PYG{n}{bi}\PYG{p}{]} \PYG{o}{=}  \PYG{n}{np}\PYG{o}{.}\PYG{n}{squeeze}\PYG{p}{(}\PYG{n}{gainOut}\PYG{o}{.}\PYG{n}{data}\PYG{p}{(}\PYG{p}{)}\PYG{p}{)}
\end{sphinxVerbatim}

The flow object is executed for each setting of the azimuth value.
Since the \sphinxcode{\sphinxupquote{VbapL2Panner}} component has no audio ports, the call \sphinxcode{\sphinxupquote{flow.process()}} does not involve audio signals.
Instead, the protocol of the parameter output \sphinxcode{\sphinxupquote{"gains"}} is accessed and the panning gains for all azimuths are collected in a matrix.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{offline_simulation_gains}.png}
\caption{Offline simulation plots of the proposed panning algorithm: Panning gains.}\label{\detokenize{visr-python-tutorial:id26}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-offline-simulation-gains}}\end{figure}

Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-offline-simulation-gains}]{\sphinxcrossref{\DUrole{std,std-ref}{Offline simulation plots of the proposed panning algorithm: Panning gains.}}}} shows the resulting gains of the \sphinxcode{\sphinxupquote{VbapL2Panner}} and the standard VBAP algorithm for the upper-rear loudspeakers \sphinxcode{\sphinxupquote{U-135}} and \sphinxcode{\sphinxupquote{U+135}} as a function of the source’s azimuth.
For plain VBAP, the gains for the symmetrical loudspeaker positions are asymmetrical, and \sphinxcode{\sphinxupquote{U-135}} is active for a wide range of azimuths with some rapid gain changes.
This is in accordance with the audio signal depicted in Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-offline-simulation-audio-signal}]{\sphinxcrossref{\DUrole{std,std-ref}{Offline simulation plots of the proposed panning algorithm: Audio signal.}}}}, and is caused by ambiguities inherent to the VBAP algorithm, see e.g., \phantomsection\label{\detokenize{visr-python-tutorial:id18}}{\hyperref[\detokenize{visr-python-tutorial:tut-franck-wang-fazi2017-sparse-l1-optimal-multiloudspeaker-panning-and-its-equivalence-to-vector-based-amplitude-panning}]{\sphinxcrossref{{[}T18{]}}}}.
In contrast, the proposed algorithm offers symmetric, localized loudspeaker activations that with smoother transitions as the source moves.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{offline_simulation_energy_direction_difference}.png}
\caption{Offline simulation plots of the proposed panning algorithm: Energy vector direction difference.}\label{\detokenize{visr-python-tutorial:id27}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-offline-simulation-energy-direction-difference}}\end{figure}

Access to such data also enables more sophisticated analyses.
As an example, Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-offline-simulation-energy-direction-difference}]{\sphinxcrossref{\DUrole{std,std-ref}{Offline simulation plots of the proposed panning algorithm: Energy vector direction difference.}}}} shows the difference of the energy vector, a metric to estimate the localisation of mid-to-high frequency content, for both algorithms. It shows that the error is smaller and more even for the proposed VBAP L2 algorithm than for the standard algorithm.
This corroborates that the proposed panning scheme overcomes some shortcomings of the plain VBAP algorithm.
This example shows how VISR’s offline execution features can ease the development, testing, and evaluation of audio signal processing components, from algorithmic building blocks to complex signal flows.
By using the same implementation as for realtime rendering, this offers the potential of unifying conventional signal processing development and realtime-capable implementation.


\subsection{Subjective Listening Test Application}
\label{\detokenize{visr-python-tutorial:subjective-listening-test-application}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{panning_comparison}.png}
\caption{Subjective listening test application: VISR signal flow.}\label{\detokenize{visr-python-tutorial:id28}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-panning-comparison}}\end{figure}

In this section we demonstrate how audio processing algorithms implemented as VISR components can be readily integrated into larger, interactive applications and graphical user interfaces.
To this end we create a listening test tool, which allows for a subjective evaluation of the proposed panning algorithm and comparison to existing approaches by presenting multiple stimuli as standardised, e.g., in ITU-R BS.1534 \phantomsection\label{\detokenize{visr-python-tutorial:id19}}{\hyperref[\detokenize{visr-python-tutorial:tut-itu2017-itu-r-bs2051-1}]{\sphinxcrossref{{[}T17{]}}}}.

With the VISR framework, the signal processing is implemented as a new top-level composite component, shown in Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-panning-comparison}]{\sphinxcrossref{\DUrole{std,std-ref}{Subjective listening test application: VISR signal flow.}}}}, which contains the proposed renderer as one component, alongside renderers for other rendering schemes.
The top-level component provides audio and object metadata to all candidate algorithms, and facilitates an multichannel selector for glitch-free switching between the methods.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{listening_test_gui}.png}
\caption{Subjective listening test application: Python user interface.}\label{\detokenize{visr-python-tutorial:id29}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-listening-test-gui}}\end{figure}

In this example the graphical user interface, shown in Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-listening-test-gui}]{\sphinxcrossref{\DUrole{std,std-ref}{Subjective listening test application: Python user interface.}}}}, is implemented in Python (using the PyQt library), and the rendering is embedded into this application within a \sphinxcode{\sphinxupquote{rrl.AudioSignalFlow}} instance.
The flexible parameter subsystem allows for an interactive control of the media playback and the rendering method selection.
To this end, control data is sent directly from the UI code to the parameter ports \sphinxcode{\sphinxupquote{transport}} and \sphinxcode{\sphinxupquote{switch}}.
This example shows how the use of the VISR framework can reduce the time and effort needed to perform a subjective evaluation of audio processing algorithms.


\subsection{Use in Different Software Environments}
\label{\detokenize{visr-python-tutorial:use-in-different-software-environments}}
As explained in Section {\hyperref[\detokenize{visr-python-tutorial:visr-tutorial-subsec-visr-framework-use-multiple-enironments}]{\sphinxcrossref{\DUrole{std,std-ref}{Use in multiple software environments}}}}, the VISR framework enables the use of audio processing components by embedding them into other audio software environments.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.600\linewidth]{{max_msp_example}.png}
\caption{Interactive loudspeaker rendering binauralization implemented in Max/MSP using VISR components as externals.}\label{\detokenize{visr-python-tutorial:id30}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-max-msp-example}}\end{figure}

Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-max-msp-example}]{\sphinxcrossref{\DUrole{std,std-ref}{Interactive loudspeaker rendering binauralization implemented in Max/MSP using VISR components as externals.}}}} shows an example of an interactive multichannel loudspeaker rendering combined with a binaural auralization, both implemented as Max/MSP externals.
The input to the \sphinxcode{\sphinxupquote{visr\_renderer\textasciitilde{}}} external is provided by a Max Patch that creates audio object metadata, which are transmitted to the renderer as string messages.
The loudspeaker outputs are connected to the \sphinxcode{\sphinxupquote{virt\_lsp\_binaural\textasciitilde{}}} binauralization algorithm, which receives head orientation data from a tracking device through a serial port.
This example shows how VISR components can be integrated into interactive, possibly audio-visual applications.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{object_renderer_plugin}.png}
\caption{DAW plugin for object-based rendering using VISR components.}\label{\detokenize{visr-python-tutorial:id31}}\label{\detokenize{visr-python-tutorial:figure-visr-python-tutorial-object-renderer-plugin-vst}}\end{figure}

The second example, depicted in Figure {\hyperref[\detokenize{visr-python-tutorial:figure-visr-python-tutorial-object-renderer-plugin-vst}]{\sphinxcrossref{\DUrole{std,std-ref}{DAW plugin for object-based rendering using VISR components.}}}}, shows a DAW plugin, that renders a point source object to a multi-loudspeaker setup.
The rendering is performed by a VISR component within the plugin.
VISR’s flexible control parameter subsystem allows for controlling object parameters as the point source position and to connect them to automation parameters of the DAW.


\section{Conclusion and Outlook}
\label{\detokenize{visr-python-tutorial:conclusion-and-outlook}}\label{\detokenize{visr-python-tutorial:visr-code-turial-sec-conclusion}}
In this paper we introduced the VISR framework, an open-source portable and general-purpose framework for audio processing that is well-suited for multichannel, object-based, and spatial audio.
Based on a continued application example of a multi-loudspeaker panning algorithm, we showed how the elements of the framework can be used to create and modify complex audio signal flows.
Moreover, we explained how the extensibility features of the VISR, in particular the Python language interface, can be used to design, prototype, and evaluate novel audio processing algorithms, demonstrating how this can streamline a typical workflow in audio research and development.
Finally, we demonstrated how audio processing functionality implemented in the VISR framework can be embedded in other software environments, for example Max/MSP or plugins for digital audio workstations.

Future developments will focus on the following aspects:
Firstly, adding support for additional hardware platforms, operating system versions, and audio APIs, and improved multiprocessor support.
Secondly, providing code libraries to ease the embedding of VISR components into software environments as Max/MSP, PureData or DAW plugin SDKs.
Thirdly, to create libraries of building blocks and ready-made renderers for different application areas of audio processing.

We provide the VISR framework as an open-software framework to foster reproducible research in audio signal processing.


\section{References}
\label{\detokenize{visr-python-tutorial:references}}



\chapter{Getting VISR}
\label{\detokenize{getting-visr:getting-visr}}\label{\detokenize{getting-visr:id1}}\label{\detokenize{getting-visr::doc}}

\section{Download}
\label{\detokenize{download:download}}\label{\detokenize{download::doc}}
The VISR framework can be obtained in diffeent forms.
FOr most persons, however, downloading and installing an installer package is the most convenient way to use this framework.

Installation packages can be downloaded from the \sphinxhref{http://s3a-spatialaudio.org}{S3A software download page} .

Installation packages are available for the following platforms:
\begin{quote}
\begin{description}
\item[{Windows (x86\_64)}] \leavevmode
Recent versions (Windows 8 and Windows 10) 64 Bit only

\item[{Mac OS X}] \leavevmode
Version 10.11 and above, 64 Bit only

\item[{Linux}] \leavevmode
Ubuntu 16.04 LTS and Ubuntu 18.04 LTS, 64 bit

\item[{Rasspberry Pi (ARM)}] \leavevmode
Raspbian Stretch, 32 Bit

\end{description}
\end{quote}


\section{Installing VISR}
\label{\detokenize{installation:installing-visr}}\label{\detokenize{installation::doc}}
Binary installation packages are the suggested way to uses the VISR framework.
A binary installers enables all uses of the framework, including
\begin{itemize}
\item {} 
Running standalone applications

\item {} 
Using DAW plugins based on the VISR

\item {} 
Using the Python interfaces and creating new functionality in Python

\item {} 
Creating standalone applications and extension libraries in C++

\end{itemize}

\begin{sphinxadmonition}{hint}{Hint:}
Building the VISR from source is necessary only in these cases:
\begin{itemize}
\item {} 
Porting it to a platform where no binary installer exists

\item {} 
Fixing or changing the internal workings of the framework.

\end{itemize}
\end{sphinxadmonition}

Installation packages are available on the \sphinxhref{http://s3a-audio.space}{S3A Software download page}.

\begin{sphinxadmonition}{note}{Note:}
If you plan to use the Python integration of the VISR framework (see {\hyperref[\detokenize{getting-started:overview-python-integration}]{\sphinxcrossref{\DUrole{std,std-ref}{Python integration}}}}), you need to select an installation package matching the Python version you are using, for example \sphinxcode{\sphinxupquote{VISR-X.X.X-python36-Windows.exe}}.
\end{sphinxadmonition}


\subsection{Windows}
\label{\detokenize{installation:windows}}\label{\detokenize{installation:installation-windows}}
The graphical installer is provides as an \sphinxcode{\sphinxupquote{.exe}} file and provides a dialog-based, component-enables installation.
Figure {\hyperref[\detokenize{installation:figure-windows-installer}]{\sphinxcrossref{figure\_windows\_installer}}} shows the component selection dialog of the installer. The choices are detailed below in section {\hyperref[\detokenize{installation:installation-component-description}]{\sphinxcrossref{\DUrole{std,std-ref}{Installation components}}}}.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.600\linewidth]{{windows_installer}.png}
\caption{Graphical Windows installer.}\label{\detokenize{installation:id2}}\label{\detokenize{installation:figure-windows-installer}}\end{figure}

An executable installer (.exe) with a graphical user interface and corresponding uninstall functionality. Supported are 64-bit versions of Windows.
If required, install the “Microsoft Visual C++ Redistributable for Visual Studio 2017”, package,
for example from the \sphinxhref{https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads}{Visual C++ downloads page}.

On Windows, it is necessary to add the directory containing the VISR libraries (DLLs) as well as the directory containing third-party libraries shipped with the VISR installer to the \sphinxcode{\sphinxupquote{PATH}} variable.
To this end, open the environment variable editor (Settings -\textgreater{} System -\textgreater{} Advanced system settings -\textgreater{} Environment variables).
The environment variable on Windows 10 is depicted in figure windows\_environment\_variables\_editor .

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.600\linewidth]{{windows_environment_variables_editor}.png}
\caption{Environment variable editor on Windows 10.}\label{\detokenize{installation:id3}}\label{\detokenize{installation:windows-environment-variables-editor}}\end{figure}

Append the value \sphinxcode{\sphinxupquote{C:\textbackslash{}Program Files\textbackslash{}VISR-X.X.X\textbackslash{}lib;C:\textbackslash{}Program Files\textbackslash{}VISR-X.X.X\textbackslash{}3rd}} if the standard installation location was used (Note: Replace \sphinxcode{\sphinxupquote{X.X.X}} with the actual version number of VISR).
Depending on your system permissions and whether you VISR shall be used by all users of the computer, you can either set the \sphinxcode{\sphinxupquote{PATH}} user variable or the \sphinxcode{\sphinxupquote{PATH}} system variable.

\begin{sphinxadmonition}{note}{Note:}
Any applications used to access VISR (for example command line terminals, Python development environments, or DAWs) must be closed and reopened before the changed paths take effect.
\end{sphinxadmonition}

Append the path ‘’\textless{}install-directory\textgreater{}/lib’’ to the path variable, where ‘’install\_diectory’’ is the directory specified during the installation.
For the default path, the setting would be \sphinxcode{\sphinxupquote{c:\textbackslash{}Program Files\textbackslash{}VISR-N.N.N\textbackslash{}lib}}, where \sphinxcode{\sphinxupquote{N.N.N}} is replaced by the actual version number.
If the \sphinxcode{\sphinxupquote{PATH}} variable is edited as a string, subsequent paths are separated by semicolons.

\begin{sphinxadmonition}{note}{Note:}
Future versions of the installer might adjust the paths automatically.
However, as pointed out in
\sphinxhref{http://nsis.sourceforge.net/Path\_Manipulation}{NSIS Path manipulation},
this needs an extremely cautious implementation to avoid potential damage to users’ systems.
\end{sphinxadmonition}

To use standalone applications (see section {\hyperref[\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers}]{\sphinxcrossref{\DUrole{std,std-ref}{Using standalone applications}}}}), it may be useful to add the \sphinxcode{\sphinxupquote{bin/}} directory to the user or system path.
For the default installation location, add \sphinxcode{\sphinxupquote{c:\textbackslash{}Program Files\textbackslash{}VISR-N.N.N\textbackslash{}bin}} to the \sphinxcode{\sphinxupquote{\%PATH\%}} environment variable.


\subsection{Mac OS X}
\label{\detokenize{installation:mac-os-x}}
An installer with a graphical user interface guides through the installation process and allows the selection of optional components.
Figure {\hyperref[\detokenize{installation:figure-visr-macos-installer}]{\sphinxcrossref{\DUrole{std,std-ref}{Component-based installer for Mac OS X.}}}} shows a screenshot of this installer.
By default, it installs the VISR into the directory \sphinxcode{\sphinxupquote{/Applications/VISR-X.X.X/}} where \sphinxcode{\sphinxupquote{X.X.X}} denotes the version number.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.750\linewidth]{{visr_macos_installer}.png}
\caption{Component-based installer for Mac OS X.}\label{\detokenize{installation:id4}}\label{\detokenize{installation:figure-visr-macos-installer}}\end{figure}

To access the component selection dialog, use the button “Customize” on the “Installation Type” screen (see figure {\hyperref[\detokenize{installation:figure-visr-macos-installer-customize}]{\sphinxcrossref{\DUrole{std,std-ref}{“Installation type” screen of Mac OS X installer. Use “Customize” to get to the component selection.}}}})

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.750\linewidth]{{visr_macos_installer_customize}.png}
\caption{“Installation type” screen of Mac OS X installer. Use “Customize” to get to the component selection.}\label{\detokenize{installation:id5}}\label{\detokenize{installation:figure-visr-macos-installer-customize}}\end{figure}

To use the standalone applications from the command line, the \sphinxcode{\sphinxupquote{bin/}} subfolder of the installation directory, e.g., \sphinxcode{\sphinxupquote{/Applications/VISR-X.X.X/bin}}.
This can be done, for example, by adding

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nb}{export} \PYG{n+nv}{PATH}\PYG{o}{=}\PYGZdl{}PATH:/Applications/VISR\PYGZhy{}X.X.X/bin
\end{sphinxVerbatim}

to the file \sphinxcode{\sphinxupquote{\$HOME/\textbackslash{}.bash\_profile}}.
However, this works only for running standalone applications from a shell (i.e., a terminal window).
If you need this path also from applications that are not started from a shell, we recommend the solution used in section {\hyperref[\detokenize{installation:installation-python-setup-configuration}]{\sphinxcrossref{\DUrole{std,std-ref}{Configuration}}}}.


\subsection{Linux}
\label{\detokenize{installation:linux}}
For Linux, installation packages are provided as \sphinxstyleemphasis{.deb} (Debian) packages.
At the moment, this package is monolithic, i.e., it contains all components.
They are installed via the command

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
sudo apt install VISR\PYGZhy{}\PYGZlt{}version\PYGZgt{}.deb
\end{sphinxVerbatim}

If this command reports missing dependencies, these can be installed subsequently with the command

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
sudo apt install \PYGZhy{}\PYGZhy{}fix\PYGZhy{}broken
\end{sphinxVerbatim}

After that the framework is ready to use.


\section{Installation components}
\label{\detokenize{installation:installation-components}}\label{\detokenize{installation:installation-component-description}}
With the dialog-based, component-enabled installers, parts of the framework can be chosen depending on the intended use of the framework.
\begin{description}
\item[{Shared Libraries}] \leavevmode
The core VISR libraries. This component is mandatory and cannot be unselected.

\item[{Standalone applications.}] \leavevmode
Renderers and small tools to be run as command-line applications.

\item[{Python externals}] \leavevmode
Python modules that give access to the functionality of the framework from Python.
Also needed to run applications that use Python internally (e.g., the binaural synthesis toolkit or metadapter-enabled rendering).

\item[{Python Packages}] \leavevmode
VISR extensions implemented in Python. This group of components requires the component “Python externals”.

\item[{Development files}] \leavevmode
Header files and CMake build support - Needed to extend the VISR with components using C++ or use the framework in external C++ applications.

\item[{Loudspeaker configurations}] \leavevmode
A set of standard loudspeaker configuration files and additional example files from actual locations.

\item[{Python templates}] \leavevmode
A set of commented template files for different types of VISR components.

\item[{Documentation}] \leavevmode
User and code reference documentation as PDF documents.
The Doxygen code documentation covering the complete source code can be optionally selected. However, the latter documentation is deprecated and will be contained in the code reference documentation in the future.

\end{description}


\section{Setting up Python}
\label{\detokenize{installation:setting-up-python}}\label{\detokenize{installation:visr-installation-setting-up-python}}
As explained in section {\hyperref[\detokenize{getting-started:overview-python-integration}]{\sphinxcrossref{\DUrole{std,std-ref}{Python integration}}}}, the Python integration is an optional, albeit central, part of the VISR framework that enables a number of its functionalities, for example:
\begin{itemize}
\item {} 
Using the framework interactively from a Python interpreter.

\item {} 
Using application that use Python internally, for instance the Binaural Synthesis Toolkit or metadata adaptation processes using the metadapter.

\item {} 
Creating new signal flows or algorithms in Python.

\end{itemize}

To use these functionalities, a Python 3 distribution must be installed on the computer, and some configuration steps are required.


\subsection{Python distribution}
\label{\detokenize{installation:python-distribution}}
Depending on the system, we suggest different Python distributions:


\subsubsection{Linux}
\label{\detokenize{installation:id1}}
Use the system-provided Python3 installation.

To install, use the package manager of your distribution, e.g.,

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
sudo apt install python3
\end{sphinxVerbatim}


\subsubsection{Windows and Mac OS X}
\label{\detokenize{installation:windows-and-mac-os-x}}
We recommend \sphinxhref{https://www.anaconda.com/download/}{Anaconda}. Please make sure you install the  Python3 / 64-Bit variant.

\begin{sphinxadmonition}{note}{Note:}
Some Mac OS variants (for example 10.12) come with a pre-installed Python 3 variant in \sphinxcode{\sphinxupquote{/Library/Frameworks/Python.framework}}.
In this case, care must be taken that it does not interferes with the chosen Python distribution. In particular, the \sphinxcode{\sphinxupquote{PYTHONHOME}} environment variable must be set correctly.
\end{sphinxadmonition}


\subsection{Configuration}
\label{\detokenize{installation:configuration}}\label{\detokenize{installation:installation-python-setup-configuration}}
Two environment variables must be set to ensure the working of the VISR Python subsystem.
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{PYTHONPATH}} This variable is used to add the directory containing the VISR python modules to the system path.
To this end, the \sphinxcode{\sphinxupquote{python/}} subdirectory of the installation folder must be added to \sphinxcode{\sphinxupquote{PYTHONPATH}}.

Note that other ways exist to add to the system path, for example

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{import} \PYG{n+nn}{sys}
\PYG{n}{sys}\PYG{o}{.}\PYG{n}{path}\PYG{o}{.}\PYG{n}{append}\PYG{p}{(} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{\PYGZlt{}visr\PYGZus{}installation\PYGZus{}dir\PYGZgt{}/python}\PYG{l+s+s1}{\PYGZsq{}} \PYG{p}{)}
\end{sphinxVerbatim}

However, we recommend setting \sphinxcode{\sphinxupquote{PYTHONPATH}} and assume this in the examples throughout this document.

\end{itemize}
\begin{description}
\item[{PYTHONHOME}] \leavevmode
This variable is needed to locate the files and libraries of the Python distribution.
This is especially important if there are more than one distributions on the system, most often on Mac OS X.
Strictly speaking, this variable is required only if VISR Python code is executed from a C++ application, for instance some DAW plugins, \sphinxcode{\sphinxupquote{python\_runner}} standalone application (section ??), or the \sphinxcode{\sphinxupquote{visr\_renderer}} with metadata processing enabled. (see section {\hyperref[\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers-visr-renderer}]{\sphinxcrossref{\DUrole{std,std-ref}{VISR object-based loudspeaker renderer}}}}).

This variable has to be set to the root directory of the Python distribution, i.e.,
one level of hierarchy above the \sphinxcode{\sphinxupquote{bin/}} folder conatining the Python interpreter.
Depending on the platform and the distribution, the correct value might be:
\begin{description}
\item[{Windows with Anaconda}] \leavevmode
\sphinxcode{\sphinxupquote{C:\textbackslash{}ProgramData\textbackslash{}Anaconda3}}

\item[{Mac OS X with Anaconda}] \leavevmode
\sphinxtitleref{\$HOME/anaconda3/}

\item[{Linux}] \leavevmode
\sphinxcode{\sphinxupquote{/usr}}

\end{description}

It is necessary to check whether these settings match with your directory layout.

If the Python distribution provides a \sphinxcode{\sphinxupquote{python-config}} or \sphinxcode{\sphinxupquote{python3-config}} binary, the command

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
python\PYGZhy{}config \PYGZhy{}\PYGZhy{}prefix
\end{sphinxVerbatim}

or

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
python3\PYGZhy{}config \PYGZhy{}\PYGZhy{}prefix
\end{sphinxVerbatim}

can be used to retrieve the required value for \sphinxcode{\sphinxupquote{PYTHONHOME}}
On Linux, setting \sphinxcode{\sphinxupquote{PYTHONHOME}} is not necessary in most cases, because there is only the system-provided Python installation available.

\item[{OPENBLAS\_NUM\_THREADS}] \leavevmode
It is advisable, in many cases, to set the value of this environment variable to 1. It controls how \sphinxcode{\sphinxupquote{numpy}} numerical algebra functions are distributed to multiple CPU cores.
\sphinxcode{\sphinxupquote{numpy}} is used by the VISR Python integration as well as in many Python-based VISR components performing mathematical or DSP operations.
For the matrix/vector sizes typically encountered in our code, the overhead for distributing the work over multiple cores typically exceeds the potential gains.
Multithreading is disabled by setting the maximum number of cores (or threads) to 1:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nv}{OPENBLAS\PYGZus{}NUM\PYGZus{}THREADS} \PYG{o}{=} 1
\end{sphinxVerbatim}

This setting is optional. However, if you encounter excessive processor loads, for example a constant 100\% load in the real-time thread, this setting can help to resolve the problem.

\end{description}

Depending on the operating system, these variables can be set as follows:
\begin{description}
\item[{Linux}] \leavevmode
Append the lines

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nb}{export} \PYG{n+nv}{PYTHONPATH}\PYG{o}{=}\PYGZdl{}PYTHONPATH:/usr/share/visr/python
\PYG{n+nb}{export} \PYG{n+nv}{OPENBLAS\PYGZus{}NUM\PYGZus{}THREADS}\PYG{o}{=}1
\end{sphinxVerbatim}

to \sphinxcode{\sphinxupquote{\$HOME/.profile}}.

\item[{Windows}] \leavevmode
Add \sphinxcode{\sphinxupquote{PYTHONPATH}} entries either as a user or system variable as described in {\hyperref[\detokenize{installation:installation-windows}]{\sphinxcrossref{\DUrole{std,std-ref}{Windows}}}} section.
The corrects setting are (assuming the default installation directory and the Anaconda distribution):

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nv}{PYTHONPATH}\PYG{o}{=}c:\PYG{l+s+se}{\PYGZbs{}P}rogram Files\PYG{l+s+se}{\PYGZbs{}V}ISR\PYGZhy{}X.X.X\PYG{l+s+se}{\PYGZbs{}p}ython
\PYG{n+nv}{PYTHONHOME}\PYG{o}{=}c:\PYG{l+s+se}{\PYGZbs{}P}rogramData\PYG{l+s+se}{\PYGZbs{}A}naconda3
\PYG{n+nv}{OPENBLAS\PYGZus{}NUM\PYGZus{}THREADS}\PYG{o}{=}1
\end{sphinxVerbatim}

Note that if there is already a \sphinxcode{\sphinxupquote{PYTHONPATH}} variable, the recommended value should be appended, using a semicolon as a separator.

\item[{Mac OS X}] \leavevmode
In order to set the environment variables system-wide, without requiring that the applications in question is started from a shell, (e.g., a command-line terminal), we recommend a custom \sphinxcode{\sphinxupquote{launchd}} property list file, as detailed, e.g., in this \sphinxhref{https://apple.stackexchange.com/questions/106355/setting-the-system-wide-path-environment-variable-in-mavericks}{StackExchange thread}.

\end{description}

\begin{sphinxadmonition}{note}{Note:}
For convenience, the installers create a pre-configured \sphinxcode{\sphinxupquote{VISR-X.X.X.plist}} file in the \sphinxcode{\sphinxupquote{etc}} subdirectory of the installation directory (e.g., \sphinxcode{\sphinxupquote{/Applications/VISR-X.X.X/etc/VISR-X.X.X.plist}} ).
This file can be either loaded directly or copied to the \sphinxcode{\sphinxupquote{LaunchAgents/}} directory first. Please check the values in this file first and adjust them accordingly.

The \sphinxcode{\sphinxupquote{VISR-X.X.X.plist}} will have this contents:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{c+cp}{\PYGZlt{}?xml version=\PYGZdq{}1.0\PYGZdq{} encoding=\PYGZdq{}UTF\PYGZhy{}8\PYGZdq{}?\PYGZgt{}}
\PYG{c+cp}{\PYGZlt{}!DOCTYPE plist PUBLIC \PYGZdq{}\PYGZhy{}//Apple//DTD PLIST 1.0//EN\PYGZdq{} \PYGZdq{}http://www.apple.com/DTDs/PropertyList\PYGZhy{}1.0.dtd\PYGZdq{}\PYGZgt{}}
\PYG{n+nt}{\PYGZlt{}plist} \PYG{n+na}{version=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
\PYG{n+nt}{\PYGZlt{}dict}\PYG{n+nt}{\PYGZgt{}}
 \PYG{n+nt}{\PYGZlt{}key}\PYG{n+nt}{\PYGZgt{}}Label\PYG{n+nt}{\PYGZlt{}/key\PYGZgt{}}
 \PYG{n+nt}{\PYGZlt{}string}\PYG{n+nt}{\PYGZgt{}}my.startup\PYG{n+nt}{\PYGZlt{}/string\PYGZgt{}}
 \PYG{n+nt}{\PYGZlt{}key}\PYG{n+nt}{\PYGZgt{}}ProgramArguments\PYG{n+nt}{\PYGZlt{}/key\PYGZgt{}}
 \PYG{n+nt}{\PYGZlt{}array}\PYG{n+nt}{\PYGZgt{}}
   \PYG{n+nt}{\PYGZlt{}string}\PYG{n+nt}{\PYGZgt{}}sh\PYG{n+nt}{\PYGZlt{}/string\PYGZgt{}}
   \PYG{n+nt}{\PYGZlt{}string}\PYG{n+nt}{\PYGZgt{}}\PYGZhy{}c\PYG{n+nt}{\PYGZlt{}/string\PYGZgt{}}
   \PYG{n+nt}{\PYGZlt{}string}\PYG{n+nt}{\PYGZgt{}}
   launchctl setenv PYTHONPATH /Applications/VISR\PYGZhy{}X.X.X/python
   launchctl setenv OPENBLAS\PYGZus{}NUM\PYGZus{}THREADS 1
   launchctl setenv PYTHONHOME \PYG{n+nt}{\PYGZlt{}BASE\PYGZus{}DIRECTORY\PYGZus{}OF\PYGZus{}PYTHON\PYGZus{}INSTALLATION}\PYG{n+nt}{\PYGZgt{}}
   \PYG{n+nt}{\PYGZlt{}/string\PYGZgt{}}
 \PYG{n+nt}{\PYGZlt{}/array\PYGZgt{}}
 \PYG{n+nt}{\PYGZlt{}key}\PYG{n+nt}{\PYGZgt{}}RunAtLoad\PYG{n+nt}{\PYGZlt{}/key\PYGZgt{}}
 \PYG{n+nt}{\PYGZlt{}true}\PYG{n+nt}{/\PYGZgt{}}
\PYG{n+nt}{\PYGZlt{}/dict\PYGZgt{}}
\PYG{n+nt}{\PYGZlt{}/plist\PYGZgt{}}
\end{sphinxVerbatim}

By convention, these files are stored in \sphinxcode{\sphinxupquote{/Users/\textless{}loginname\textgreater{}/Library/LaunchAgents/}}.
To activate the settings, call

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
launchctl load \PYGZlt{}path\PYGZhy{}to\PYGZhy{}file\PYGZgt{}/VISR\PYGZhy{}X.X.X.plist
\end{sphinxVerbatim}

To take effect, all applications using these settings (e.g., terminals, Python interpreters, DAWs) must be quit and reopened.

These settings are preserved if the machine is restarted.
To deactivate them, the property list file must be unloaded:
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
launchctl unload \PYGZlt{}path\PYGZhy{}to\PYGZhy{}file\PYGZgt{}/VISR\PYGZhy{}X.X.X.plist
\end{sphinxVerbatim}
\end{quote}

If you made changes to the settings, you have to perform the \sphinxcode{\sphinxupquote{unload}} command followed by a \sphinxcode{\sphinxupquote{load}}.
\end{sphinxadmonition}


\section{Verifying the installation}
\label{\detokenize{installation:verifying-the-installation}}
We suggest some basic tests to verify that the VISR framework has been correctly installed and configured.


\subsection{Testing a standalone application}
\label{\detokenize{installation:testing-a-standalone-application}}
This test is to ensure that that the installation is successful, and that the VISR shared libraries can be located and are compatible with the system.
When using the component-enabled installers, the component \sphinxcode{\sphinxupquote{Standalone applications}} must have been selected in order to perform this check.

In a terminal (Linux shell, Mac OS Terminal application, Windows command line \sphinxcode{\sphinxupquote{cmd}}),
execute this command:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZlt{}visr\PYGZhy{}installation\PYGZhy{}dir\PYGZgt{}/bin/matrix\PYGZus{}convolver \PYGZhy{}\PYGZhy{}version
\end{sphinxVerbatim}

For the different platforms, the full commands are (assuming the default installation directory)
Windows
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
  \PYG{l+s+s2}{\PYGZdq{}c:\PYGZbs{}Program Files\PYGZbs{}VISR\PYGZhy{}X.X.X\PYGZbs{}bin\PYGZbs{}matrix\PYGZus{}convolver.exe\PYGZdq{}} \PYGZhy{}\PYGZhy{}version

Note that the quotes are necessary to cope with the space in the path.
\end{sphinxVerbatim}
\end{quote}

Mac OS X
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
/Applications/VISR\PYGZhy{}X.X.X/bin/matrix\PYGZus{}convolver \PYGZhy{}\PYGZhy{}version
\end{sphinxVerbatim}
\end{quote}

Linux
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
/usr/bin/matrix\PYGZus{}convolver \PYGZhy{}\PYGZhy{}version
\end{sphinxVerbatim}
\end{quote}

If you added the \sphinxcode{\sphinxupquote{bin/}} directory as described above, calling
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
matrix\PYGZus{}convolver \PYGZhy{}\PYGZhy{}version
\end{sphinxVerbatim}
\end{quote}

is sufficient.

In any case, the call should generate a statement like
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
VISR Matrix convolver utility  0.10.0
\end{sphinxVerbatim}
\end{quote}

If there is an error message about a missing shared library (or DLL), you should consult the respective section about installation.
In particular this applies Windows, where the \sphinxcode{\sphinxupquote{PATH}} variable needs to be set accordingly.


\subsubsection{Testing the interactive Python integration}
\label{\detokenize{installation:testing-the-interactive-python-integration}}
This test ensures that the VISR framework can be used interactively from Python interpreters.

First start a Python 3 interpreter (for example \sphinxcode{\sphinxupquote{python}} or \sphinxcode{\sphinxupquote{ipython}}).
Depending on the system, the binaries might be called \sphinxcode{\sphinxupquote{python3}} or \sphinxcode{\sphinxupquote{ipython3}}, respectively
It must be the interpreter of the Python distribution you intend to use (e.g., Anaconda).

In the interpreter, try to import the \sphinxcode{\sphinxupquote{visr}} modules
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{import} \PYG{n+nn}{visr}
\end{sphinxVerbatim}
\end{quote}

This command should return without an error message.
In this case, you can check whether the module is loaded from the correct location:
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nb}{getattr}\PYG{p}{(} \PYG{n}{visr}\PYG{p}{,} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{\PYGZus{}\PYGZus{}file\PYGZus{}\PYGZus{}}\PYG{l+s+s1}{\PYGZsq{}} \PYG{p}{)}
\end{sphinxVerbatim}
\end{quote}

The directory of the resulting file path should be \sphinxcode{\sphinxupquote{\textless{}visr-installation-dir\textgreater{}/python}}.
For example, on Windows this returns \sphinxcode{\sphinxupquote{C:\textbackslash{}Program Files\textbackslash{}VISR 0.10.0\textbackslash{}\textbackslash{}python\textbackslash{}\textbackslash{}visr.pyd}}.


\section{Source Code}
\label{\detokenize{sourcecode:source-code}}\label{\detokenize{sourcecode::doc}}
Alternatively, the VISR framework can be installed and build from source code.
It is hosted at the GitLab repository \sphinxurl{https://gitlab.eps.surrey.ac.uk:s3a/VISR.git}

To retrieve the source code, clone the repository with

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
git clone https://gitlab.eps.surrey.ac.uk:s3a/VISR.git
\end{sphinxVerbatim}

Setting up a build environment, including the required software tools, and compiling the source code is detailed in the \sphinxhref{http://s3a-spatialaudio.org}{VISR API documentation}.


\section{Support and help}
\label{\detokenize{support:support-and-help}}\label{\detokenize{support:support}}\label{\detokenize{support::doc}}
Sopport for installing and using the VISR is available through several ways.

First, you should check the FAQ section of the website (TODO: Insert link here)

Second, the mailing list (insert link to the registration page of the 3a-software list here).

Third, problems and supected bugs can be reported on (insert link to issues page of GitLab repository / later GitHub repo).


\chapter{Using standalone applications}
\label{\detokenize{using-standalone-renderers:using-standalone-applications}}\label{\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers}}\label{\detokenize{using-standalone-renderers::doc}}
The VISR framework provides a number of standalone real-time rendering applications for some of its audio processing functionality.

If a component-aware installer is used (see Section {\hyperref[\detokenize{installation:installation-component-description}]{\sphinxcrossref{\DUrole{std,std-ref}{Installation components}}}}), then the component “Standalone applications” has to be selected during installation.

The standalone applications are started as command line applications, and configured through a number of command line options or a configuration file.


\section{Common options}
\label{\detokenize{using-standalone-renderers:common-options}}\label{\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}}
All standalone applications provided with the VISR provide a common set of command line options:
\begin{description}
\item[{\sphinxstylestrong{\textendash{}version} or \sphinxstylestrong{-v}}] \leavevmode
Returns a short description of the tool and its version information.

\item[{\sphinxstylestrong{\textendash{}help} or \sphinxstylestrong{-h}}] \leavevmode
Returns a list of supported command line options with brief descriptions.

\item[{\sphinxstylestrong{\textendash{}option-file \textless{}filename\textgreater{}} or \sphinxstylestrong{@\textless{}filename\textgreater{}}}] \leavevmode
Pass a configuration file containing a set of command line options to the applications.
This options allows to store and share complex sets of command line options, and to overcome potential command line length limitations.

A typical option file has the format

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}i 2
\PYGZhy{}o 2
\PYGZhy{}f 48000
\PYGZhy{}c \PYG{l+s+s2}{\PYGZdq{}/usr/share/visr/config/generic/stereo.xml\PYGZdq{}}
\end{sphinxVerbatim}

where,by convention, one option is stored per line.

\item[{\sphinxstylestrong{\textendash{}sampling-frequency} or \sphinxstylestrong{-f}}] \leavevmode
The sampling frequency to be used for rendering, as an integer value in Hz.
Typically optional. If not given, a default value (e.g., 48000 Hz) will be used.

\item[{\sphinxstylestrong{\textendash{}period} or \sphinxstylestrong{-p}}] \leavevmode
The period, or blocksize, or buffersize to be used by the audio interface.

In most cases, the period should be a power of 2, e.g., 64, 128, 256, 512, …, 4096.
Lower values mean lower audio latency, but typically higher system load and higher susceptibility to audio underruns.

Typically an optional argument. If not given, a default value (e.g., 1024) is used.

\item[{\sphinxstylestrong{\textendash{}audio-backend} or \sphinxstylestrong{-D}}] \leavevmode
Specify the audio interface library to be used.

This option is mandatory.

The audio interfaces depend on the operating system and the configuration of the user’s system. The most common options are \sphinxstylestrong{“PortAudio”} (all platforms) and \sphinxstylestrong{“Jack”} (Linux and Mac OS X). Note that additional libraries (or backends) can be available for a specific platform, and new backends might be added in the future.

\item[{\sphinxstylestrong{-audio-ifc-options}}] \leavevmode
A string to provide additional options to the audio interface.

This is an optional argument, and its content is interface-specific.

By convention, the existing audio interfaces expect JSON (\sphinxhref{https://www.json.org/}{JavaScript Object Notation}) strings for the backend-configuration.

To pass JSON strings, the whole string should be enclosed in single or double quotes, and the quotes required by JSON must be escaped with a backslash. For example, the option might be used in this way:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
visr\PYGZus{}renderer ... \PYGZhy{}audio\PYGZhy{}ifc\PYGZhy{}options\PYG{o}{=}\PYG{l+s+s1}{\PYGZsq{}\PYGZob{} \PYGZbs{}\PYGZdq{}hostapi\PYGZbs{}\PYGZdq{}: \PYGZbs{}\PYGZdq{}WASAPI\PYGZbs{}\PYGZdq{} \PYGZcb{}\PYGZsq{}}
\end{sphinxVerbatim}

Section {\hyperref[\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers-specific-audio-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Interface-specific audio options}}}} below explains the options for the currently supported audio interfaces.

\item[{\sphinxstylestrong{-audio-ifc-option-file}}] \leavevmode
Provide a interface-specific option string within a file.

This can be used to avoid re-specifying complex options strings, to author them in a structured way, and to store and share them.

In addition, it avoids the quoting and escaping tricks needed on the command line.
For example, the option shown above could be specified in a file \sphinxstylestrong{portaudio\_options.cfg} as

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}
  \PYG{n+nt}{\PYGZdq{}hostapi\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}WASAPI\PYGZdq{}}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

and passed as

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
visr\PYGZus{}renderer ... \PYGZhy{}audio\PYGZhy{}ifc\PYGZhy{}option\PYGZhy{}file\PYG{o}{=}portaudio\PYGZus{}options.cfg
\end{sphinxVerbatim}

\end{description}

\begin{sphinxadmonition}{note}{Note:}
The options \sphinxstylestrong{\textendash{}audio-ifc-options} and \sphinxstylestrong{\textendash{}audio-ifc-option-file} are mutually
exclusive, that means other none or one of them can be provided.
\end{sphinxadmonition}


\section{VISR object-based loudspeaker renderer}
\label{\detokenize{using-standalone-renderers:visr-object-based-loudspeaker-renderer}}\label{\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers-visr-renderer}}
These renderers facilitate object-based rendering to arbitrary loudspeaker setups.
They use the VISR audio object model and the corresponding JSON format described in Section {\hyperref[\detokenize{object-based-audio-with-visr:the-visr-object-model}]{\sphinxcrossref{\DUrole{std,std-ref}{The VISR object model}}}}.

\begin{sphinxadmonition}{note}{Note:}
Object-based rendering requires audio scenes consisting of audio objects, that is, audio and corresponding
object metadata.
The audio signals have to be provided to the input of the audio interface used by the renderer.
The object metadata has to be sent as a stream of UDP messages.

The VISR framework does not provide a graphical user interface to generate object metadata.
We recommend using thehttps://www.reaper.fm\textgreater{}{}`\_.
Section “TODO: Insert name here” of the \sphinxhref{http://cvssp.org/data/s3a/public/VISRPluginSuite/html/index.html}{VISR production suite User Manual}
describes how to configure these plugins with an external renderer.
\end{sphinxadmonition}

There are two binaries for loudspeaker rendering: \sphinxstylestrong{visr\_renderer} and \sphinxstylestrong{baseline\_renderer}.
The provision of these separate binaries has technical reasons - mainly their dependency on a compatible and configured Python installation, as explained below.

The two binaries provided are:
\begin{description}
\item[{\sphinxstyleemphasis{visr\_renderer}}] \leavevmode
This is the full object-based renderer, including a powerful metadata adaptation engine for intelligent object-based rendering - the Metadapter - implemented in Python.
This metadapter is integrated into the rendering binary as an optional part, and is used if the option \sphinxstylestrong{\textendash{}metadapter-config} is specified.
The binary itself, however, needs a Python istallation to start at all, irrespective whether this option is set.

\item[{\sphinxstyleemphasis{baseline\_renderer}}] \leavevmode
This is the legacy object-based loudspeaker renderer. At the time being, it provides the same functionality as the \sphinxstylestrong{visr\_renderer},
but without the optional integrated metadapter component.
In this way, the binary is independent of a Python distribution on the user’s computer.

\end{description}

In general, we recommend to use \sphinxstylestrong{visr\_renderer} if possible, and to use \sphinxstylestrong{baseline\_renderer} on systems where the Python features
of the VISR framework are not available.

The command line arguments supported by the \sphinxstylestrong{visr\_renderer} application are:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} visr\PYGZus{}renderer.exe \PYGZhy{}\PYGZhy{}help
\PYGZhy{}h \PYG{o}{[} \PYGZhy{}\PYGZhy{}help \PYG{o}{]}                   Show \PYG{n+nb}{help} and usage information.
\PYGZhy{}v \PYG{o}{[} \PYGZhy{}\PYGZhy{}version \PYG{o}{]}                Display version information.
\PYGZhy{}\PYGZhy{}option\PYGZhy{}file arg               Load options from a file. Can also be used
                                with syntax \PYG{l+s+s2}{\PYGZdq{}@\PYGZlt{}filename\PYGZgt{}\PYGZdq{}}.
\PYGZhy{}D \PYG{o}{[} \PYGZhy{}\PYGZhy{}audio\PYGZhy{}backend \PYG{o}{]} arg      The audio backend.
\PYGZhy{}f \PYG{o}{[} \PYGZhy{}\PYGZhy{}sampling\PYGZhy{}frequency \PYG{o}{]} arg Sampling frequency \PYG{o}{[}Hz\PYG{o}{]}
\PYGZhy{}p \PYG{o}{[} \PYGZhy{}\PYGZhy{}period \PYG{o}{]} arg             Period \PYG{o}{(}blocklength\PYG{o}{)} \PYG{o}{[}Number of samples per
                                audio block\PYG{o}{]}
\PYGZhy{}c \PYG{o}{[} \PYGZhy{}\PYGZhy{}array\PYGZhy{}config \PYG{o}{]} arg       Loudspeaker array configuration file
\PYGZhy{}i \PYG{o}{[} \PYGZhy{}\PYGZhy{}input\PYGZhy{}channels \PYG{o}{]} arg     Number of input channels \PYG{k}{for} audio object
                                signal
\PYGZhy{}o \PYG{o}{[} \PYGZhy{}\PYGZhy{}output\PYGZhy{}channels \PYG{o}{]} arg    Number of audio output channels
\PYGZhy{}e \PYG{o}{[} \PYGZhy{}\PYGZhy{}object\PYGZhy{}eq\PYGZhy{}sections \PYG{o}{]} arg Number of eq \PYG{o}{(}biquad\PYG{o}{)} section processed \PYG{k}{for}
                                each object signal.
\PYGZhy{}\PYGZhy{}reverb\PYGZhy{}config arg             JSON string to configure the object\PYGZhy{}based
                                reverberation part, empty string \PYG{o}{(}default\PYG{o}{)} to
                                disable reverb.
\PYGZhy{}\PYGZhy{}tracking arg                  Enable adaptation of the panning using visual
                                tracking. Accepts the position of the tracker
                                in JSON format\PYG{l+s+s2}{\PYGZdq{}\PYGZob{} \PYGZdq{}}port\PYG{l+s+s2}{\PYGZdq{}: \PYGZlt{}UDP port number\PYGZgt{},}
\PYG{l+s+s2}{                                \PYGZdq{}}position\PYG{l+s+s2}{\PYGZdq{}: \PYGZob{}\PYGZdq{}}x\PYG{l+s+s2}{\PYGZdq{}: \PYGZlt{}x in m\PYGZgt{}, \PYGZdq{}}y\PYG{l+s+s2}{\PYGZdq{}: \PYGZlt{}y im m\PYGZgt{},}
\PYG{l+s+s2}{                                \PYGZdq{}}z\PYG{l+s+s2}{\PYGZdq{}: \PYGZlt{}z in m\PYGZgt{} \PYGZcb{}, \PYGZdq{}}rotation\PYG{l+s+s2}{\PYGZdq{}: \PYGZob{} \PYGZdq{}}rotX\PYG{l+s+s2}{\PYGZdq{}: rX,}
\PYG{l+s+s2}{                                \PYGZdq{}}rotY\PYG{l+s+s2}{\PYGZdq{}: rY, \PYGZdq{}}rotZ\PYG{l+s+s2}{\PYGZdq{}: rZ \PYGZcb{} \PYGZcb{}\PYGZdq{}} .
\PYGZhy{}r \PYG{o}{[} \PYGZhy{}\PYGZhy{}scene\PYGZhy{}port \PYG{o}{]} arg         UDP port \PYG{k}{for} receiving object metadata
\PYGZhy{}m \PYG{o}{[} \PYGZhy{}\PYGZhy{}metadapter\PYGZhy{}config \PYG{o}{]} arg  Metadapter configuration file. Requires a
                                build with Python support. If empty, no
                                metadata adaptation is performed.
\PYGZhy{}\PYGZhy{}low\PYGZhy{}frequency\PYGZhy{}panning         Activates frequency\PYGZhy{}dependent panning gains
                                and normalisation
\PYGZhy{}\PYGZhy{}audio\PYGZhy{}ifc\PYGZhy{}options arg         Audio interface optional configuration
\PYGZhy{}\PYGZhy{}audio\PYGZhy{}ifc\PYGZhy{}option\PYGZhy{}file arg     Audio interface optional configuration file
\end{sphinxVerbatim}

The arguments for the \sphinxstylestrong{baseline\_renderer} application are identical, except that the \sphinxcode{\sphinxupquote{-{-}metadapter-config}} option is not supported as explained above.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{-{-}audio-backend}} or \sphinxcode{\sphinxupquote{-D}}}] \leavevmode
The audio interface library to be used. See section {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}.

\item[{\sphinxcode{\sphinxupquote{-{-}audio-ifc-options}}:}] \leavevmode
Audio-interface specific options, section {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}.

\item[{\sphinxcode{\sphinxupquote{-{-}audio-ifc-option-file}}:}] \leavevmode
Audio-interface specific options, section {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}.

\item[{\sphinxcode{\sphinxupquote{-{-}sampling-frequency}} or \sphinxcode{\sphinxupquote{-f}}:}] \leavevmode
Sampling frequency in Hz. Default: 48000 Hz. See section {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}.

\item[{\sphinxcode{\sphinxupquote{-{-}period}} or \sphinxcode{\sphinxupquote{-p}}:}] \leavevmode
The number of samples processed in one iteration of the renderer. Should be a power of 2 (64,128,…,4096,…) . Default: 1024 samples. See section {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}.

\item[{\sphinxcode{\sphinxupquote{-{-}array-config}} or \sphinxcode{\sphinxupquote{-c}}:}] \leavevmode
File path to the loudspeaker configuration file. Path might be relative to the current working directory. Mandatory argument.
The XML file format is described in Section {\hyperref[\detokenize{object-based-audio-with-visr:loudspeaker-configuration-file-format}]{\sphinxcrossref{\DUrole{std,std-ref}{The loudspeaker configuration format}}}}.

\item[{\sphinxcode{\sphinxupquote{-{-}input-channels}} or \sphinxcode{\sphinxupquote{-i}}:}] \leavevmode
The number of audio input channels. This corresponds to the number of single-waveform objects the renderer will process. Mandatory argument. A (case-insensitive) file extension of \sphinxcode{\sphinxupquote{.xml}} triggers the use of the XML format for parsing.

\item[{\sphinxcode{\sphinxupquote{-{-}output-channels}} or \sphinxcode{\sphinxupquote{-o}}:}] \leavevmode
The number of output channels the renderer will put write to. If not given, the number of output channels is determined from the largest logical channel number in the array configuration.

\item[{\sphinxcode{\sphinxupquote{-{-}object-eq-sections}}:}] \leavevmode
The number of EQs (biquad sections) that can be specified for each object audio signal.

Default value: o, which deactivate EQ filtering for objects.

\item[{\sphinxcode{\sphinxupquote{-{-}low-frequency-panning}}:}] \leavevmode
Switches the loudspeaker panning between standard VBAP and a dual-frequency approach with separate low- and high-frequency panning rules.

Admissible values are \sphinxcode{\sphinxupquote{true}} and \sphinxcode{\sphinxupquote{false}}. The default value is \sphinxcode{\sphinxupquote{false}}, corresponding
to the standard VBAP algorithm.

\item[{\sphinxcode{\sphinxupquote{-{-}reverb-config}}:}] \leavevmode
A set of options for the integrated reverberation engine for the RSAO (\sphinxcode{\sphinxupquote{PointsourceWithReverb}}) object (see section {\hyperref[\detokenize{object-based-audio-with-visr:visr-object-based-audio-reverberation}]{\sphinxcrossref{\DUrole{std,std-ref}{Object-Based Reverberation}}}}).
To be passed as a JSON string. The supported options are:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{numReverbObjects}}:}] \leavevmode
The number of RSAO objects that can be rendered simultaneously.
These objects may have arbitrary object ids, and they are automatically allocated to the computational resources avalable.

To be provided as a nonnegative integer number The default value is 0, which means that the reverberation rendering is effectively disabled.

\item[{\sphinxcode{\sphinxupquote{lateReverbFilterLength}}:}] \leavevmode
Specify the length of the late reverberation filters, in seconds.

Provided as a floating-point value, in seconds. Default value is zero, which results in the shortest reverb filter length that can be processed by the renderer, typically one sample.

\item[{\sphinxcode{\sphinxupquote{lateReverbDecorrelationFilters}}:}] \leavevmode
Specifies a multichannel WAV file containing a set of decorrelation filters, one per loudspeaker output. The number of channels must be equal or greater than the number of loudspeakers, channels that exceed the number of loudspeakers are not used.

To be provided as a full file path. The default value is empty, which means that zero-valued filters are used, which effectively disables the late reverb.

\item[{\sphinxcode{\sphinxupquote{discreteReflectionsPerObject}}:}] \leavevmode
The maximum number of discrete reflections that can be rendered for a single RSAO object.

Given as a nonnegative integer number. The default value is 0, which means that no discrete reflections are supported.

\item[{\sphinxcode{\sphinxupquote{maxDiscreteReflectionDelay}}:}] \leavevmode
The maximum discrete reflection delay supported. This allows a for tradeoff between the computational resources, i.e., memory required by the renderer and a realistic upper limit for discrete reflection delays.

To be provided as a floating-point number in seconds. Default value is 1.0, i.e., one second.

\item[{\sphinxcode{\sphinxupquote{lateReverbFilterUpdatesPerPeriod}}}] \leavevmode
Optional argument for limiting the number of filter updates in realtime rendering.
This is to avoid processing load peaks, which might lead to audio underruns, if multiple RSAO objects are changed simultaneously.
The argument specifies the maximum number of objects for whom the late reverb filter is calculated withon one period (audio buffer). If there are more pending changes than thix number, the updates are spread over multiple periods.
This is a tradeoff between peak load and the timing accuracy and synchronity of late reverb updates.

Optional value, default value is 1, meaning at most one update per period

\end{description}

An example configuration is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}}\PYG{n}{reverb}\PYG{o}{\PYGZhy{}}\PYG{n}{config}\PYG{o}{=}\PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{\PYGZob{} }\PYG{l+s+se}{\PYGZbs{}\PYGZdq{}}\PYG{l+s+s1}{numReverbObjects}\PYG{l+s+se}{\PYGZbs{}\PYGZdq{}}\PYG{l+s+s1}{: 5, }\PYG{l+s+se}{\PYGZbs{}\PYGZdq{}}\PYG{l+s+s1}{lateReverbFilterLength}\PYG{l+s+se}{\PYGZbs{}\PYGZdq{}}\PYG{l+s+s1}{: 4.0,}
           \PYGZbs{}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{lateReverbDecorrelationFilters}\PYG{l+s+se}{\PYGZbs{}\PYGZdq{}}\PYG{l+s+s2}{: }\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{/}\PYG{n}{home}\PYG{o}{/}\PYG{n}{af5u13}\PYG{o}{/}\PYG{n}{tmp}\PYG{o}{/}\PYG{n}{decorr}\PYG{o}{.}\PYG{n}{wav}\PYGZbs{}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{,}
           \PYGZbs{}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{discreteReflectionsPerObject}\PYG{l+s+se}{\PYGZbs{}\PYGZdq{}}\PYG{l+s+s2}{: 10 \PYGZcb{}}\PYG{l+s+s2}{\PYGZsq{}}
\end{sphinxVerbatim}

\item[{\sphinxcode{\sphinxupquote{-{-}tracking}}}] \leavevmode
Activates the listener-tracked VBAP reproduction, which adjust both the VBAP gains as well as the final loudspeaker gains and delays according to the listener position. It takes a non-empty string argument containing a JSON message of the format: \sphinxcode{\sphinxupquote{\{ "port": \&lt;UDP port number\&gt;, "position": \{"x": \&lt;x in m\&gt;, "y": \&lt;y im m\&gt;, "z": \&lt;z in m\&gt; \}, "rotation": \{ "rotX": rX, "rotY": rY, "rotZ": rZ \} \}"}}. The values are defined as follows:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|}
\hline
\sphinxstyletheadfamily 
ID
&\sphinxstyletheadfamily 
Description
&\sphinxstyletheadfamily 
Unit
&\sphinxstyletheadfamily 
Default
\\
\hline
port
&
UDP port number
&
unsigned int
&
8888
\\
\hline
position.x
&
x position of the tracker
&
m
&
2.08
\\
\hline
position.y
&
y position of the tracker
&
m
&
0.0
\\
\hline
position.z
&
z position of the tracker
&
m
&
0.0
\\
\hline
rotation.rotX
&
rotation the tracker about the x axis, i.e., y-z plane
&
degree
&
0.0
\\
\hline
rotation.rotY
&
rotation the tracker about the y axis, i.e., z-x plane
&
degree
&
0.0
\\
\hline
rotation.rotZ
&
rotation the tracker about the z axis, i.e., x-y plane
&
degree
&
180
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\end{description}

\begin{sphinxadmonition}{note}{Note:}
The option parsing for \sphinxcode{\sphinxupquote{-{-}tracking}} not supported yet, default values are used invariably. To activate tracking, you need to specify the  \sphinxcode{\sphinxupquote{-{-}tracking}} option with an arbitrary parameter (even  \sphinxcode{\sphinxupquote{-{-}tracking=false}} would activate the tracking.
\end{sphinxadmonition}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{-{-}scene-port}}}] \leavevmode
The UDP network port which receives the scene data in the VISR JSON object format.

\item[{\sphinxcode{\sphinxupquote{-{-}metadapter-config}}}] \leavevmode
An optional Metadapter configuration file in XML format, provided as a full path to the file. If specified, the received metadata are passed through a sequence of metadata adaptation steps that are specified in the configuration file. If not given., metadata adaptation is not performed, and objects are directly passed to the audio renderer.

This option is not supported by the \sphinxstylestrong{baseline\_renderer} application.

\end{description}


\section{The matrix convolver renderer}
\label{\detokenize{using-standalone-renderers:the-matrix-convolver-renderer}}\label{\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers-matrix-convolver}}
The matrix convolver renderer is a multiple-input multiple-output convolution engine to be run as a command line application.

It implements uniformly partitioned fast convolution for arbitrary routing points between input and output files.


\subsection{Basic usage}
\label{\detokenize{using-standalone-renderers:basic-usage}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} matrix\PYGZus{}convolver \PYGZhy{}\PYGZhy{}help
\PYGZhy{}h \PYG{o}{[} \PYGZhy{}\PYGZhy{}help \PYG{o}{]}                   Show \PYG{n+nb}{help} and usage information.
\PYGZhy{}v \PYG{o}{[} \PYGZhy{}\PYGZhy{}version \PYG{o}{]}                Display version information.
\PYGZhy{}\PYGZhy{}option\PYGZhy{}file arg               Load options from a file. Can also be used
                                with syntax \PYG{l+s+s2}{\PYGZdq{}@\PYGZlt{}filename\PYGZgt{}\PYGZdq{}}.
\PYGZhy{}D \PYG{o}{[} \PYGZhy{}\PYGZhy{}audio\PYGZhy{}backend \PYG{o}{]} arg      The audio backend. JACK\PYGZus{}NATIVE activates the
                                native Jack driver insteat of the PortAudio
                                implementation.
\PYGZhy{}\PYGZhy{}audio\PYGZhy{}ifc\PYGZhy{}options arg         Audio interface optional configuration
\PYGZhy{}\PYGZhy{}audio\PYGZhy{}ifc\PYGZhy{}option\PYGZhy{}file arg     Audio interface optional configuration file
\PYGZhy{}\PYGZhy{}list\PYGZhy{}audio\PYGZhy{}backends           List the supported audio backends that can be
                                passed to the the \PYG{l+s+s2}{\PYGZdq{}\PYGZhy{}\PYGZhy{}audio\PYGZhy{}backend\PYGZdq{}} \PYG{o}{(}\PYG{l+s+s2}{\PYGZdq{}\PYGZhy{}D\PYGZdq{}}\PYG{o}{)}
                                option.
\PYGZhy{}\PYGZhy{}list\PYGZhy{}fft\PYGZhy{}libraries            List the supported FFT implementations that
                                can be selected using the \PYG{l+s+s2}{\PYGZdq{}\PYGZhy{}\PYGZhy{}fftLibrary\PYGZdq{}}
                                option.
\PYGZhy{}f \PYG{o}{[} \PYGZhy{}\PYGZhy{}sampling\PYGZhy{}frequency \PYG{o}{]} arg Sampling frequency \PYG{o}{[}Hz\PYG{o}{]}
\PYGZhy{}p \PYG{o}{[} \PYGZhy{}\PYGZhy{}period \PYG{o}{]} arg             Period \PYG{o}{(}block length\PYG{o}{)}: The number of samples
                                per audio block, also the block size of the
                                partitioned convolution.
\PYGZhy{}i \PYG{o}{[} \PYGZhy{}\PYGZhy{}input\PYGZhy{}channels \PYG{o}{]} arg     Number of input channels \PYG{k}{for} audio object
                                signal.
\PYGZhy{}o \PYG{o}{[} \PYGZhy{}\PYGZhy{}output\PYGZhy{}channels \PYG{o}{]} arg    Number of audio output channels.
\PYGZhy{}\PYGZhy{}filters arg                   Initial impulse responses, specified as
                                comma\PYGZhy{}separated list of one or multiple WAV
                                files.
\PYGZhy{}\PYGZhy{}filter\PYGZhy{}file\PYGZhy{}index\PYGZhy{}offsets arg Index offsets to address the impulses in the
                                provided multichannel filter files. If
                                specified, the number of values must match
                                the number of filter files.
\PYGZhy{}r \PYG{o}{[} \PYGZhy{}\PYGZhy{}routings \PYG{o}{]} arg           Initial routing entries, expects a JSON array
                                consisting of objects \PYG{l+s+s2}{\PYGZdq{}\PYGZob{}\PYGZdq{}}inputs\PYG{l+s+s2}{\PYGZdq{}: nn,}
\PYG{l+s+s2}{                                \PYGZdq{}}outputs\PYG{l+s+s2}{\PYGZdq{}:nn, \PYGZdq{}}filters\PYG{l+s+s2}{\PYGZdq{}:nn (\PYGZdq{}}gain\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{:XX)}
\PYG{l+s+s2}{\PYGZhy{}l [ \PYGZhy{}\PYGZhy{}max\PYGZhy{}filter\PYGZhy{}length ] arg  Maximum length of the impulse responses, in}
\PYG{l+s+s2}{                                samples. If not given, it defaults to the}
\PYG{l+s+s2}{                                longest provided filter,}
\PYG{l+s+s2}{\PYGZhy{}\PYGZhy{}max\PYGZhy{}routings arg              Maximum number of filter routings.}
\PYG{l+s+s2}{\PYGZhy{}\PYGZhy{}max\PYGZhy{}filters arg               Maximum number of impulse responses that can}
\PYG{l+s+s2}{                                be stored.}
\PYG{l+s+s2}{\PYGZhy{}\PYGZhy{}fft\PYGZhy{}library arg               Specify the FFT implementation to be used.}
\PYG{l+s+s2}{                                Defaults to the default implementation for}
\PYG{l+s+s2}{                                the platform.}
\end{sphinxVerbatim}


\subsection{Operation}
\label{\detokenize{using-standalone-renderers:operation}}
The matrix convolver consists of the following elements:
\begin{itemize}
\item {} 
A number of \sphinxstylestrong{input channels}.

\item {} 
A set of \sphinxstylestrong{FIR filter}, which can be reused multiple times.

\item {} 
A set of \sphinxstylestrong{output channels}.

\item {} 
A set of \sphinxstylestrong{routings}, which defines that a given input is filtered through a specific filter (with an optional gain), and the result is routed to a given output channels. All filtering results that are routed to a given output are summed together.

\end{itemize}

This interface allows for several different operation modes, for example:
\begin{itemize}
\item {} 
Multi-channel filtering where each input is filtered with one filter to give produce the same number of output channels.

\item {} 
Filtering to produce multiple, different copies of the same input signal.

\item {} 
Filtering multiple signals and adding them together, as, for example, in filter-and-sum beamforming.

\item {} 
MIMO filtering with complete matrices, where a filter is defined for each input-output combination.

\item {} 
MIMO filtering with sparse matrices, corresponding to sophisticated routings between inputs and outputs.

\end{itemize}


\subsection{Detailed option description}
\label{\detokenize{using-standalone-renderers:detailed-option-description}}
\sphinxcode{\sphinxupquote{-{-}help}} or \sphinxcode{\sphinxupquote{-h}}:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{-{-}version}} or \sphinxcode{\sphinxupquote{-v}}  :}] \leavevmode
Standard options, described in {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}

\item[{\sphinxcode{\sphinxupquote{-{-}option-file}}:}] \leavevmode
Standard options, described in {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}

\item[{\sphinxcode{\sphinxupquote{-{-}audio-backend}} or \sphinxcode{\sphinxupquote{-D}}:}] \leavevmode
Standard options, described in {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}

\item[{\sphinxcode{\sphinxupquote{-{-}audio-ifc-options}}:}] \leavevmode
Standard options, described in {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}

\item[{\sphinxcode{\sphinxupquote{-{-}audio-ifc-option-file}}:}] \leavevmode
Standard options, described in {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}

\item[{\sphinxcode{\sphinxupquote{-{-}sampling-frequency}} or \sphinxcode{\sphinxupquote{-f}}}] \leavevmode
Standard options, described in {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}

\item[{\sphinxcode{\sphinxupquote{-{-}period}} or \sphinxcode{\sphinxupquote{-p}}:}] \leavevmode
Standard options, described in {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}

\item[{\sphinxcode{\sphinxupquote{-{-}input-channels}} or \sphinxcode{\sphinxupquote{-i}}:}] \leavevmode
The number of input channels. Must not exceed the number of capture channels of the sound card.

\item[{\sphinxcode{\sphinxupquote{-o}} or \sphinxcode{\sphinxupquote{-{-}output-channels}}:}] \leavevmode
The number of output channels. Must be less or equal than the number of sound card output channels.

\item[{\sphinxcode{\sphinxupquote{-{-}filters}}}] \leavevmode
The filters, specified as a comma-separated list of WAV files. WAV files can be multichannel, in this case, every channel is handled as a separate filter.

All filters are combined into a single array, where each filter is associated to a unique index (starting from zero if not specified otherwise.)

This argument is optional. If not provided, all filters are zero-initialised. Note that if the \sphinxcode{\sphinxupquote{filters}} argument is not provided, then the option \sphinxcode{\sphinxupquote{max-routings}} must be provided.

\item[{\sphinxcode{\sphinxupquote{-{-}filter-file-index-offsets}}}] \leavevmode
Specify the start filter index for each WAV file specified by the \sphinxcode{\sphinxupquote{-{-}filters}} argument.
To be provided as a comma-separated list of nonnegative filter entries, one for each file in the \sphinxcode{\sphinxupquote{filters}} argument.
This argument is optional. If not provided, the start index of the first file is 0, and the start offset af all subsequent filter files follows the end index of the previous filter file.
This facility can be used to decouple the number of filters in the WAV files from the indexing scheme used to define the routings.

Example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}\PYGZhy{}filters \PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}filters\PYGZus{}2ch.wav, filters\PYGZus{}6ch.wav, filters\PYGZus{}4ch.wav\PYGZdq{}}
\PYGZhy{}\PYGZhy{}filter\PYGZhy{}file\PYGZhy{}index\PYGZhy{}offsets\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}2, 8, 16\PYGZdq{}}
\end{sphinxVerbatim}

Here, three WAV files are provided: \sphinxcode{\sphinxupquote{filters\_2ch.wav}}, \sphinxcode{\sphinxupquote{filters\_6ch.wav}}, and \sphinxcode{\sphinxupquote{filters\_4ch.wav}}, with 2, 6, and 4 channels respectively.
The filter offsets “2, 8, 16” mean that the filters of \sphinxcode{\sphinxupquote{filters\_2ch.wav}} will be associated to the indices 2 and 3, that of \sphinxcode{\sphinxupquote{filters\_6ch.wav}} by indices 8-13, and that of \sphinxcode{\sphinxupquote{filters\_4ch.wav}} by the indices 16-19.

Any filters below, between, or above the initialized filter channels (here, indices 0-1, 4-7, 14-15, and \textgreater{}=20) will be zero-initialised.

If the \sphinxcode{\sphinxupquote{-{-}filter-file-index-offsets}} hadn’t been provided in this example, the start offsets for the filter sets from the three files would have been 0,2,8.

\item[{\sphinxcode{\sphinxupquote{-{-}routings}} or \sphinxcode{\sphinxupquote{-r}}}] \leavevmode
Provide a list of routings points. This is to be specified as a JSON string.
A routing defines a filter being applied between a specific input channel and a specific output channels.
The JSON representation for a single entry is

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}} \PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}\PYGZlt{}i\PYGZgt{}\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}\PYGZlt{}o\PYGZgt{}\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}\PYGZlt{}f\PYGZgt{}\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}gain\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}\PYGZlt{}g\PYGZgt{}\PYGZdq{}} \PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

Here, \sphinxcode{\sphinxupquote{\textless{}i\textgreater{}}} is the index of the input channel, \sphinxcode{\sphinxupquote{\textless{}o\textgreater{}}} is the channel index of the output, and \sphinxcode{\sphinxupquote{\textless{}f\textgreater{}}} is the index of the filter (see above).
All indices are zero-offset.
The gain specification \sphinxcode{\sphinxupquote{,"gain": \textless{}g\textgreater{}}} is optional, with \sphinxcode{\sphinxupquote{\textless{}g\textgreater{}}} representing a linear-scale gain value.

A routing list is a JSON array of routing entries, for example

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{[}\PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}2\PYGZdq{}} \PYG{p}{\PYGZcb{}}\PYG{p}{,}
 \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}1\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}1\PYGZdq{}} \PYG{p}{\PYGZcb{}}\PYG{p}{,}
 \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}2\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}} \PYG{p}{\PYGZcb{}}\PYG{p}{]}
\end{sphinxVerbatim}

A routing entry can define multiple multiple routings using a Matlab-like stride syntax for \sphinxcode{\sphinxupquote{\textless{}i\textgreater{}}}, \sphinxcode{\sphinxupquote{\textless{}o\textgreater{}}}, \sphinxcode{\sphinxupquote{\textless{}f\textgreater{}}}, or several of them.
If an index is a stride sequence, then the routing entry is duplicated over all values of the stride sequence. If more than one index in the routing entry are strides, then all of them must have the same length, and each of the duplicated routing entries contains the respective value of the respective stride sequence.
For example, the strided routing entry

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}3\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0:3:9\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}1\PYGZdq{}} \PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

routes input 3 to the outputs 0, 3, 6, and 9, using the filter indexed by 1 for each routing.
In contrast.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0:2\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}2:\PYGZhy{}1:0\PYGZdq{}} \PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

is equivalent to the routing list shown above.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{[}\PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}2\PYGZdq{}} \PYG{p}{\PYGZcb{}}\PYG{p}{,}
 \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}1\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}1\PYGZdq{}} \PYG{p}{\PYGZcb{}}\PYG{p}{,}
 \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}input\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}output\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}2\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}filter\PYGZdq{}}\PYG{p}{:}\PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}} \PYG{p}{\PYGZcb{}}\PYG{p}{]}
\end{sphinxVerbatim}

\item[{\sphinxcode{\sphinxupquote{-{-}max-filter-length}} or \sphinxcode{\sphinxupquote{-l}}:}] \leavevmode
Define the maximum length of the FIR filters.
If the \sphinxcode{\sphinxupquote{-{-}filters}} option is provided, this argument is optional. In this case, admissible filter length is set to the largest length of all specified filter.
an error is reported if any specified filter exceeds the admissible length.
If \sphinxcode{\sphinxupquote{-{-}filters}} and \sphinxcode{\sphinxupquote{-{-}max-filter-length}} are both provided, then an error is generated if the length of any specified filter exceeds the value of \sphinxcode{\sphinxupquote{-{-}max-filter-length}}.

\item[{\sphinxcode{\sphinxupquote{-{-}max-routings}} :}] \leavevmode
Define the maximum number of routings.
If the \sphinxcode{\sphinxupquote{-{-}routings}} options is present, this argument is optional, and the maximum number of permissible routings is set to the number
of routing entries in the \sphinxcode{\sphinxupquote{-{-}routing}} argument.
If \sphinxcode{\sphinxupquote{routings}} and \sphinxcode{\sphinxupquote{-{-}max-routings}} are both specified, the number of entries in \sphinxcode{\sphinxupquote{-{-}routings}} must not exceed the value of \sphinxcode{\sphinxupquote{-{-}max-routings}}.

\item[{\sphinxcode{\sphinxupquote{-{-}max-filters}}:}] \leavevmode
Define the maximum number of filter entries.
This parameter is optional if the argument \sphinxcode{\sphinxupquote{-{-}filters}} is provided. In this case, the maximum filter number is set to the number of filters generated by the  \sphinxcode{\sphinxupquote{-{-}filters}} argument.

\begin{sphinxadmonition}{note}{Note:}
If combined with \sphinxcode{\sphinxupquote{-{-}filter-file-index-offsets}}, this automatically computed number of filters includes any gaps in the generated filter set.
\end{sphinxadmonition}

If \sphinxcode{\sphinxupquote{-{-}filters}} and \sphinxcode{\sphinxupquote{max-filters}} are both provided, then the number of filter entries created by \sphinxcode{\sphinxupquote{-{-}filters}} must not exceed
the value of \sphinxcode{\sphinxupquote{-{-}max-filters}}.

\item[{\sphinxcode{\sphinxupquote{-{-}fft-library}}:}] \leavevmode
Select a FFT implementation from the set of available FFT libraries.
The admissible values (strings) can be obtained through the \sphinxcode{\sphinxupquote{-{-}list-fft-libraries}} option.

\end{description}

\begin{sphinxadmonition}{note}{Note:}
The current implementation accepts only a static configuration.

Future versions, however, will provide runtime control through a network command interface.

Some arguments or argument combinations do not make sense at the moment, but will do when combined with runtime control.
Examples include the ability to provide empty routings, zero-valued filters, or to specify values for \sphinxcode{\sphinxupquote{-{-}max-routings}} or \sphinxcode{\sphinxupquote{-{-}max-filters}} that are larger than the currently set values.
\end{sphinxadmonition}


\subsection{Examples}
\label{\detokenize{using-standalone-renderers:examples}}
A channel-wise multichannel convolution can be performed as

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} matrix\PYGZus{}convolver \PYGZhy{}i \PYG{l+m}{2} \PYGZhy{}o \PYG{l+m}{2} \PYGZhy{}p \PYG{l+m}{512} \PYGZhy{}D PortAudio \PYGZhy{}f \PYG{l+m}{48000} \PYGZhy{}\PYGZhy{}filters\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}filters.wav\PYGZdq{}}
  \PYGZhy{}r \PYG{l+s+s1}{\PYGZsq{}[ \PYGZob{}\PYGZbs{}\PYGZdq{}input\PYGZbs{}\PYGZdq{}: \PYGZbs{}\PYGZdq{}0:1\PYGZbs{}\PYGZdq{}, \PYGZbs{}\PYGZdq{}output\PYGZbs{}\PYGZdq{}:\PYGZbs{}\PYGZdq{}0:1\PYGZbs{}\PYGZdq{}, \PYGZbs{}\PYGZdq{}filter\PYGZbs{}\PYGZdq{}:\PYGZbs{}\PYGZdq{}0:1\PYGZbs{}\PYGZdq{}\PYGZcb{}]\PYGZsq{}}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Note:}
The quoting is necessary when started from the command line.
\end{sphinxadmonition}

The following example shows a convolution with binaural room impulse responses, where a 9-loudspeaker multichannel signal is routed to 9x2 BRIRs
that are summed to form two ear signals.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} matrix\PYGZus{}convolver \PYGZhy{}i \PYG{l+m}{9} \PYGZhy{}o \PYG{l+m}{2} \PYGZhy{}\PYGZhy{}max\PYGZhy{}filters\PYG{o}{=}\PYG{l+m}{18} \PYGZhy{}\PYGZhy{}max\PYGZhy{}routings\PYG{o}{=}18
   \PYGZhy{}r \PYG{l+s+s2}{\PYGZdq{}[\PYGZob{}\PYGZbs{}\PYGZdq{}input\PYGZbs{}\PYGZdq{}:\PYGZbs{}\PYGZdq{}0:8\PYGZbs{}\PYGZdq{}, \PYGZbs{}\PYGZdq{}output\PYGZbs{}\PYGZdq{}:\PYGZbs{}\PYGZdq{}0\PYGZbs{}\PYGZdq{}, \PYGZbs{}\PYGZdq{}filter\PYGZbs{}\PYGZdq{}:\PYGZbs{}\PYGZdq{}0:2:16\PYGZbs{}\PYGZdq{}\PYGZcb{},}
\PYG{l+s+s2}{        \PYGZob{}\PYGZbs{}\PYGZdq{}input\PYGZbs{}\PYGZdq{}:\PYGZbs{}\PYGZdq{}0:8\PYGZbs{}\PYGZdq{}, \PYGZbs{}\PYGZdq{}output\PYGZbs{}\PYGZdq{}:\PYGZbs{}\PYGZdq{}1\PYGZbs{}\PYGZdq{}, \PYGZbs{}\PYGZdq{}filter\PYGZbs{}\PYGZdq{}:\PYGZbs{}\PYGZdq{}1:2:17\PYGZbs{}\PYGZdq{}\PYGZcb{}]\PYGZdq{}}
   \PYGZhy{}\PYGZhy{}filters\PYG{o}{=}\PYG{l+s+s2}{\PYGZdq{}bbcrdlr9ch\PYGZus{}brirs.wav\PYGZdq{}}
   \PYGZhy{}D Jack \PYGZhy{}f \PYG{l+m}{48000} \PYGZhy{}p 512
\end{sphinxVerbatim}

Here, the file \sphinxcode{\sphinxupquote{bbcrdlr9ch\_brirs.wav}} contains the 18 BRIRs, with the first nine channels for the left and the remaining channels for the right ear filters.


\section{The python\_runner application}
\label{\detokenize{using-standalone-renderers:the-python-runner-application}}\label{\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers-python-runner}}
This standalone application is an alternative way to run arbitrary VISR components in real-time.

Compared to instantiating the processing from a Python interpreter, this can be easier to control, for example within  a script or when running a device in ‘headless mode’.

For obvious reasons, this application requires an installed and correctly configured Python distribution, as described in Section {\hyperref[\detokenize{installation:installation-python-setup-configuration}]{\sphinxcrossref{\DUrole{std,std-ref}{Configuration}}}}.


\subsection{Usage}
\label{\detokenize{using-standalone-renderers:usage}}
The supported options are displayed when started with the \sphinxcode{\sphinxupquote{-{-}help}} or \sphinxcode{\sphinxupquote{-h}} option:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} python\PYGZus{}runner \PYGZhy{}\PYGZhy{}help
  \PYGZhy{}h \PYG{o}{[} \PYGZhy{}\PYGZhy{}help \PYG{o}{]}                     Show \PYG{n+nb}{help} and usage information.
  \PYGZhy{}v \PYG{o}{[} \PYGZhy{}\PYGZhy{}version \PYG{o}{]}                  Display version information.
  \PYGZhy{}\PYGZhy{}option\PYGZhy{}file arg                 Load options from a file. Can also be used
                                    with syntax \PYG{l+s+s2}{\PYGZdq{}@\PYGZlt{}filename\PYGZgt{}\PYGZdq{}}.
  \PYGZhy{}D \PYG{o}{[} \PYGZhy{}\PYGZhy{}audio\PYGZhy{}backend \PYG{o}{]} arg        The audio backend.
  \PYGZhy{}f \PYG{o}{[} \PYGZhy{}\PYGZhy{}sampling\PYGZhy{}frequency \PYG{o}{]} arg   Sampling frequency \PYG{o}{[}Hz\PYG{o}{]}
  \PYGZhy{}p \PYG{o}{[} \PYGZhy{}\PYGZhy{}period \PYG{o}{]} arg               Period \PYG{o}{(}blocklength\PYG{o}{)} \PYG{o}{[}Number of samples per
                                    audio block\PYG{o}{]}
  \PYGZhy{}m \PYG{o}{[} \PYGZhy{}\PYGZhy{}module\PYGZhy{}name \PYG{o}{]} arg          Name of the Python module to be loaded
                                    \PYG{o}{(}without path or extension\PYG{o}{)}.
  \PYGZhy{}c \PYG{o}{[} \PYGZhy{}\PYGZhy{}python\PYGZhy{}class\PYGZhy{}name \PYG{o}{]} arg    Name of the Python class \PYG{o}{(}must be a
                                    subclass of visr.Component\PYG{o}{)}.
  \PYGZhy{}n \PYG{o}{[} \PYGZhy{}\PYGZhy{}object\PYGZhy{}name \PYG{o}{]} arg          Name of the Python class \PYG{o}{(}must be a
                                    subclass of visr.Component\PYG{o}{)}.
  \PYGZhy{}a \PYG{o}{[} \PYGZhy{}\PYGZhy{}positional\PYGZhy{}arguments \PYG{o}{]} arg Comma\PYGZhy{}separated list of positional options
                                    passed to the class constructor.
  \PYGZhy{}k \PYG{o}{[} \PYGZhy{}\PYGZhy{}keyword\PYGZhy{}arguments \PYG{o}{]} arg    Comma\PYGZhy{}separated list of named \PYG{o}{(}keyword\PYG{o}{)}
                                    options passed to the class constructor.
  \PYGZhy{}d \PYG{o}{[} \PYGZhy{}\PYGZhy{}module\PYGZhy{}search\PYGZhy{}path \PYG{o}{]} arg   Optional path to search \PYG{k}{for} the Python
                                    module \PYG{o}{(}in addition to the default search
                                    path \PYG{o}{(}sys.path incl. \PYGZdl{}PYTHONPATH\PYG{o}{)}. Provided as a
                                    comma\PYGZhy{}separated list of directories.
  \PYGZhy{}\PYGZhy{}audio\PYGZhy{}ifc\PYGZhy{}options arg           Audio interface optional configuration.
  \PYGZhy{}\PYGZhy{}audio\PYGZhy{}ifc\PYGZhy{}option\PYGZhy{}file arg       Audio interface optional configuration file.
\end{sphinxVerbatim}

If the processing is correctly started, a message is displayed on the command line:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
VISR Python signal flow runner. Press \PYG{l+s+s2}{\PYGZdq{}q\PYGZlt{}Return\PYGZgt{}\PYGZdq{}} to quit.
\end{sphinxVerbatim}

To terminate the \sphinxcode{\sphinxupquote{python\_runner}}, press the “q” key followed by \textless{}Return\textgreater{}.

\begin{sphinxadmonition}{note}{Note:}
On Linux and Mac OS X, the standard program termination via \textless{}Ctrl-C\textgreater{} does not work at the moment.
Instead, this key combination is ignored, and Python exception message is shown if the program is
later terminated via “q\textless{}Return\textgreater{}”.
See issue \sphinxurl{https://gitlab.eps.surrey.ac.uk/s3a/VISR/issues/23} .
\end{sphinxadmonition}


\subsection{Detailed option description}
\label{\detokenize{using-standalone-renderers:id1}}
The standard options \sphinxcode{\sphinxupquote{-{-}help}}, \sphinxcode{\sphinxupquote{-{-}version}}, \sphinxcode{\sphinxupquote{-{-}audio-backend}}, \sphinxcode{\sphinxupquote{sampling-frequency}}, \sphinxtitleref{:code:}\textendash{}period{}`, \sphinxtitleref{:code:}\textendash{}audio-ifc-options{}`, and \sphinxtitleref{:code:}\textendash{}audio-ifc-option-file{}` are described in Section {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}.

The remaining options are:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{-{-}module-name}} or \sphinxcode{\sphinxupquote{-m}}:}] \leavevmode
Specify the name of a Python module that contains the VISR component to be executed.
That is, use the module name that would need to be imported in an interactive Python session.
The module name must be provided without the file extension.
It can be specified either with a full file path, or as a pure module name.
In the latter case, the directory containing the module must be on the Python module search
path or included in the \sphinxcode{\sphinxupquote{-{-}module-search-path}} option.

The module can be in one of several forms:
\begin{itemize}
\item {} 
A Python file (normally with extension \sphinxcode{\sphinxupquote{.py}}) that contains the component class.
The module name must be specified without the extension.

\item {} 
A directory containing a multi-file package.

\item {} 
Compiled extension modules implemented in C++. Typical file extesnions are \sphinxcode{\sphinxupquote{.so}}
(Linux and Mac OS X) or \sphinxcode{\sphinxupquote{.pyc}} (Windows). The module name must be specified without the extension.

\end{itemize}

This is a mandatory argument.

\item[{\sphinxcode{\sphinxupquote{-{-}python-class-name}} or \sphinxcode{\sphinxupquote{-c}}:}] \leavevmode
The name of the Python class to be instantiated, without the leading namespace name.
This class must be derived from \sphinxcode{\sphinxupquote{visr.Component}}
and must be defined in the module \sphinxcode{\sphinxupquote{module-name}}.

\begin{sphinxadmonition}{note}{Note:}
At the moment, only classes in the top-level namespace are supported.
That is, classes of the form \sphinxcode{\sphinxupquote{moduleName.submodule.className}} cannot be used.
\end{sphinxadmonition}

This argument is mandatory.

\item[{\sphinxcode{\sphinxupquote{-{-}object-name}} or \sphinxcode{\sphinxupquote{-n}}:}] \leavevmode
Set a name for the top-level component. This name is used, for example, in error messages
and warnings emitted from the component.

This argument is optional.
If not provided, a default name is used.

\item[{\sphinxcode{\sphinxupquote{-a}} \sphinxcode{\sphinxupquote{-{-}positional-arguments}}:}] \leavevmode
Provide a sequence of parameters to the component’s constructor as positional arguments.

The fixed first three arguments to a component constructor, i.e., \sphinxcode{\sphinxupquote{context}},
\sphinxcode{\sphinxupquote{name}} and \sphinxcode{\sphinxupquote{parent}}, do not need top be specified.
That means the first value of the sequence is passed to the fourth argument, the second value
to the fifth argument, and so on.

The parameters are passed as a Python tuple.
See, e.g., the \sphinxhref{https://docs.python.org/3.7/library/stdtypes.html\#typesseq-tuple}{Python documentation on tuples}.
Following these conventions, the arguments can be specified as follows:
\begin{itemize}
\item {} 
A comma-separated list of values, for example

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}3, 2.7,\PYGZsq{}foobar\PYGZsq{}\PYGZdq{}}
\end{sphinxVerbatim}

Note that the enclosing double quotes are required to separate the argument to \sphinxcode{\sphinxupquote{-a}}
from other options on the command line.
They are strictly necessary only if the parameter sequence contains spaces, but we
recommend to use double quotes for consistency.

If the parameter sequence consists of a single value, a training comma is required.
That is, a single positional argument is specified as

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}3,\PYGZdq{}}
\end{sphinxVerbatim}

If two or more arguments are provided, the trailing comma is optional.

\item {} 
A comma-separated list of values, enclosed in parentheses.
Apart from the additional parentheses, the syntax is identical to the
comma-separated lists above.
That is, the argument list above would be specified as

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}(3, 2.7,\PYGZsq{}foobar\PYGZsq{} )\PYGZdq{}}
\end{sphinxVerbatim}

As above, single arguments require a trailing comma.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}(3,)\PYGZdq{}}
\end{sphinxVerbatim}

\item {} 
A tuple constructed using the \sphinxcode{\sphinxupquote{tuple()}} keyword, that is

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}tuple(3, 2.7,\PYGZsq{}foobar\PYGZsq{} )\PYGZdq{}}
\end{sphinxVerbatim}

and in the single-parameter case

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}tuple(3)\PYGZdq{}}
\end{sphinxVerbatim}

That is, no trailing comma is required in this case.

\end{itemize}

The \sphinxcode{\sphinxupquote{-{-}positional-arguments}} option is optional.
If it is not provided, no positional arguments are passed to the component’s constructor.

\item[{\sphinxcode{\sphinxupquote{-{-}keyword-arguments}} or \sphinxcode{\sphinxupquote{-k}}:}] \leavevmode
A set of keyword arguments to be passed to the component’s constructor.
To be provided as a Python dictionary, for example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}k \PYG{l+s+s2}{\PYGZdq{}\PYGZob{} \PYGZsq{}argument1\PYGZsq{}: value1, \PYGZsq{}argument2\PYGZsq{}: value2, ..., \PYGZsq{}argumentN\PYGZsq{}: valueN \PYGZcb{}\PYGZdq{}}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{hint}{Hint:}
As in case of positional arguments, we suggest to enclose the complete argument
in double quotes.
When following this convention, single quotes can be used for the keywords as
\sphinxcode{\sphinxupquote{'argument1'}} and string parameters without the need for escaping quotes.
\end{sphinxadmonition}

Following Python conventions, keyword arguments must not be provided for arguments already
handled by the \sphinxcode{\sphinxupquote{-{-}positional-arguments}} option.
Likewise, keyword arguments must not be provided for the fixed first three constructor
arguments of a component: \sphinxcode{\sphinxupquote{context}}, \sphinxcode{\sphinxupquote{name}} and \sphinxcode{\sphinxupquote{parent}}.

This argument is optional; no keyword arguments are passed to the component if it is not given.

\item[{\sphinxcode{\sphinxupquote{-{-}module-search-path}} or \sphinxcode{\sphinxupquote{-d}}:}] \leavevmode
Specifies additional search paths for Python modules.

To be specified as a comma-separeted list of directory path.

These search paths can be used to locate the module containing the component to be run, unless
a directory path is passed to the \sphinxcode{\sphinxupquote{-{-}module-name}} option.
In addition, the search paths are evaluated to locate transitive dependencies of the module to be loaded.
For example, the path to VISR Python externals can be specidied in this way, thus avoiding the use of
the \sphinxcode{\sphinxupquote{PYTHONPATH}} environment variable, as described in section
{\hyperref[\detokenize{installation:installation-python-setup-configuration}]{\sphinxcrossref{\DUrole{std,std-ref}{Configuration}}}}.
The additional search paths are added to the Python search path \sphinxcode{\sphinxupquote{sys.path}} before the main
module specified by the \sphinxcode{\sphinxupquote{-m}} option is loaded.

This argument is optional, no additional search paths are added if the option is not provided.

\end{description}


\subsection{Examples}
\label{\detokenize{using-standalone-renderers:id2}}
In this example we use a simple Python-based VISR component \sphinxcode{\sphinxupquote{PythonAdder}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{class} \PYG{n+nc}{PythonAdder}\PYG{p}{(} \PYG{n}{visr}\PYG{o}{.}\PYG{n}{AtomicComponent} \PYG{p}{)}\PYG{p}{:}
  \PYG{l+s+sd}{\PYGZdq{}\PYGZdq{}\PYGZdq{} General\PYGZhy{}purpose add block for an arbitrary number of inputs\PYGZdq{}\PYGZdq{}\PYGZdq{}}
  \PYG{k}{def} \PYG{n+nf}{\PYGZus{}\PYGZus{}init\PYGZus{}\PYGZus{}}\PYG{p}{(} \PYG{n+nb+bp}{self}\PYG{p}{,} \PYG{n}{context}\PYG{p}{,} \PYG{n}{name}\PYG{p}{,} \PYG{n}{parent}\PYG{p}{,} \PYG{n}{numInputs}\PYG{p}{,} \PYG{n}{width} \PYG{p}{)}\PYG{p}{:}
  \PYG{o}{.}\PYG{o}{.}\PYG{o}{.}
\end{sphinxVerbatim}

that implements generic addition with \sphinxcode{\sphinxupquote{numInputs}} signals to be added with
\sphinxcode{\sphinxupquote{width}} signals each.
Here, the component class \sphinxcode{\sphinxupquote{PythonAdder}} is contained in a source file \sphinxcode{\sphinxupquote{pythonAtoms.py}}.

The \sphinxcode{\sphinxupquote{python\_runner}} can be invoked using positional arguments through

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} python\PYGZus{}runner \PYGZhy{}D PortAudio \PYGZhy{}f \PYG{l+m}{48000} \PYGZhy{}p 512
    \PYGZhy{}m \PYGZdl{}HOME/VISR/src/python/scripts/pythonAtoms \PYGZhy{}c PythonAdder \PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}3,2\PYGZdq{}}
\end{sphinxVerbatim}

which creates a \sphinxcode{\sphinxupquote{PythonAdder}} component with three inputs and a width of two.

The same component is constructed with the keyword argument option as

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} python\PYGZus{}runner \PYGZhy{}D PortAudio \PYGZhy{}f \PYG{l+m}{48000} \PYGZhy{}p 512
    \PYGZhy{}m \PYGZdl{}HOME/VISR/src/python/scripts/pythonAtoms \PYGZhy{}c PythonAdder \PYGZhy{}k \PYG{l+s+s2}{\PYGZdq{}\PYGZob{}\PYGZsq{}width\PYGZsq{}:2, \PYGZsq{}numInputs\PYGZsq{}:3\PYGZcb{}\PYGZdq{}}
\end{sphinxVerbatim}

Positional and keyword arguments can also be mixed, as long as the corresponding Python rules are observed:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} python\PYGZus{}runner \PYGZhy{}D PortAudio \PYGZhy{}f \PYG{l+m}{48000} \PYGZhy{}p 512
    \PYGZhy{}m \PYGZdl{}HOME/VISR/src/python/scripts/pythonAtoms \PYGZhy{}c PythonAdder \PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}3,\PYGZdq{}} \PYGZhy{}k \PYG{l+s+s2}{\PYGZdq{}\PYGZob{}\PYGZsq{}width\PYGZsq{}:2\PYGZcb{}\PYGZdq{}}
\end{sphinxVerbatim}

Note the trailing comma for the positional option.

So far, the examples specified the path to the module explicitly.
If this path (\sphinxcode{\sphinxupquote{\$HOME/VISR/src/python/scripts}} in the example) is contained in the default Python search path, i.e., \sphinxcode{\sphinxupquote{sys.path}}, then the pure module name suffices

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} python\PYGZus{}runner \PYGZhy{}D PortAudio \PYGZhy{}f \PYG{l+m}{48000} \PYGZhy{}p 512
    \PYGZhy{}m pythonAtoms \PYGZhy{}c PythonAdder \PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}3,\PYGZdq{}} \PYGZhy{}k \PYG{l+s+s2}{\PYGZdq{}\PYGZob{}\PYGZsq{}width\PYGZsq{}:2\PYGZcb{}\PYGZdq{}}
\end{sphinxVerbatim}

Another way to locate the module is to provide the path through the \sphinxcode{\sphinxupquote{module-search-path}} option.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} python\PYGZus{}runner \PYGZhy{}D PortAudio \PYGZhy{}f \PYG{l+m}{48000} \PYGZhy{}p 512
    \PYGZhy{}m pythonAtoms \PYGZhy{}c PythonAdder \PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}3,\PYGZdq{}} \PYGZhy{}k \PYG{l+s+s2}{\PYGZdq{}\PYGZob{}\PYGZsq{}width\PYGZsq{}:2\PYGZcb{}\PYGZdq{}}
    \PYGZhy{}\PYGZhy{}module\PYGZhy{}search\PYGZhy{}path \PYGZdl{}HOME/VISR/src/python/scripts
\end{sphinxVerbatim}

Finally, the option \sphinxcode{\sphinxupquote{-{-}module-search-path}} can also be used to locate modules needed by the
main module. For example, the path to the core VISR modules can be specified in this way, thus
eradicating the need to add them to the default Python search path, for example by adding them to
the \sphinxcode{\sphinxupquote{PYTHONPATH}} variable.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{}\PYGZgt{} python\PYGZus{}runner \PYGZhy{}D PortAudio \PYGZhy{}f \PYG{l+m}{48000} \PYGZhy{}p 512
    \PYGZhy{}m pythonAtoms \PYGZhy{}c PythonAdder \PYGZhy{}a \PYG{l+s+s2}{\PYGZdq{}3,\PYGZdq{}} \PYGZhy{}k \PYG{l+s+s2}{\PYGZdq{}\PYGZob{}\PYGZsq{}width\PYGZsq{}:2\PYGZcb{}\PYGZdq{}}
    \PYGZhy{}\PYGZhy{}module\PYGZhy{}search\PYGZhy{}path
    \PYGZdl{}HOME/VISR/src/python/scripts,/usr/share/visr/python
\end{sphinxVerbatim}


\section{Interface-specific audio options}
\label{\detokenize{using-standalone-renderers:interface-specific-audio-options}}\label{\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers-specific-audio-options}}
This section described the audio-interface-specific options that can be passed through the
\sphinxcode{\sphinxupquote{-{-}audio-ifc-options}} or \sphinxcode{\sphinxupquote{-{-}audio-ifc-option-file}} arguments.


\subsection{PortAudio interface}
\label{\detokenize{using-standalone-renderers:portaudio-interface}}
The interface-specific options for the PortAudio interface are to be provided as a JSON file,
for example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}
 \PYG{n+nt}{\PYGZdq{}sampleformat\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}...\PYGZdq{}}\PYG{p}{,}
 \PYG{n+nt}{\PYGZdq{}interleaved\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}...\PYGZdq{}}\PYG{p}{,}
 \PYG{n+nt}{\PYGZdq{}hostapi\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}...\PYGZdq{}}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Note:}
When used on the command line using the \sphinxcode{\sphinxupquote{-{-}audio-ifc-options}} argument, apply the quotation and escaping as described in Section {\hyperref[\detokenize{using-standalone-renderers:using-standalone-renderers-common-options}]{\sphinxcrossref{\DUrole{std,std-ref}{Common options}}}}.
\end{sphinxadmonition}

The following options are supported for the PortAudio interface:
\begin{description}
\item[{\sphinxstylestrong{sampleformat}}] \leavevmode
Specifies the PortAudio sample format. Possible values are:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{signedInt8Bit}}

\item {} 
\sphinxcode{\sphinxupquote{unsignedInt8Bit}}

\item {} 
\sphinxcode{\sphinxupquote{signedInt16Bit}}

\item {} 
\sphinxcode{\sphinxupquote{unsignedInt16Bit}}

\item {} 
\sphinxcode{\sphinxupquote{signedInt24Bit}}

\item {} 
\sphinxcode{\sphinxupquote{unsignedInt24Bit}}

\item {} 
\sphinxcode{\sphinxupquote{signedInt32Bit}}

\item {} 
\sphinxcode{\sphinxupquote{unsignedInt32Bit}}

\item {} 
\sphinxcode{\sphinxupquote{float32Bit}} .

\end{itemize}

\item[{\sphinxstylestrong{interleaved}:}] \leavevmode
Enable/disable interleaved mode, possible values are \sphinxcode{\sphinxupquote{true, false}}.

\item[{\sphinxstylestrong{hostapi}:}] \leavevmode
Used to specify PortAudio backend audio interface. Possible values are:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{default}}: This activates the default backend

\item {} 
\sphinxcode{\sphinxupquote{WASAPI}} : Supported OS: Windows.

\item {} 
\sphinxcode{\sphinxupquote{ASIO}} : Supported OS: Windows.

\item {} 
\sphinxcode{\sphinxupquote{WDMKS}}: Supported OS: Windows.

\item {} 
\sphinxcode{\sphinxupquote{DirectSound}} : Supported OS: Windows.

\item {} 
\sphinxcode{\sphinxupquote{CoreAudio}} : Supported OS: MacOs.

\item {} 
\sphinxcode{\sphinxupquote{ALSA}} : Supported OS: Linux.

\item {} 
\sphinxcode{\sphinxupquote{JACK}} : Supported OSs: MacOs, Linux.

\end{itemize}

PortAudio aupports a number of other APIs. However, they are outdated or refer to obsolete platforms and therefore should not be used:
- \sphinxcode{\sphinxupquote{SoundManager}} (MacOs)
- \sphinxcode{\sphinxupquote{OSS}} (Linux)
- \sphinxcode{\sphinxupquote{AL}}
- \sphinxcode{\sphinxupquote{BeOS}}
- \sphinxcode{\sphinxupquote{AudioScienceHPI}} (Linux)

\end{description}

This configuration is an example of usage of PortAudio, with Jack audio interface as backend.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}
  \PYG{n+nt}{\PYGZdq{}sampleformat\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}float32Bit\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}interleaved\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}false\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}hostapi\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}JACK\PYGZdq{}}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}


\subsection{Jack audio interface}
\label{\detokenize{using-standalone-renderers:jack-audio-interface}}
The following options can be provided when using Jack as our top level component’s Audio Interface:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{clientname}}:}] \leavevmode
Jack Client name for our top level component.

\item[{\sphinxcode{\sphinxupquote{servername}}:}] \leavevmode
Jack Server name. If not provided, the default Jack server is used.

\item[{\sphinxcode{\sphinxupquote{autoconnect}}:}] \leavevmode
Globally enable/disable the automatic connection of ports.
Admissible values are \sphinxcode{\sphinxupquote{true}} and \sphinxcode{\sphinxupquote{false}}.
This setting can be overridden specifically for capture and playback ports in the port configuration section described below.

\end{description}

\sphinxcode{\sphinxupquote{portconfig}}: Subset of options regarding the configuration and connection of Jack Ports, see following section.


\subsubsection{Port Configuration}
\label{\detokenize{using-standalone-renderers:port-configuration}}
The port configuration section allows to individually set properties for the capture, i.e., input, and the playback, i.e., output, ports of an application.

\sphinxcode{\sphinxupquote{capture}}: Specifies that the following options regard the top level component’s capture ports only
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{autoconnect}} : Enable/disable auto connection to an external jack client’s input ports, possible values are \sphinxcode{\sphinxupquote{true, false}}

\item {} 
\sphinxcode{\sphinxupquote{port}}: Jack ports specification
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{basename}}: Common name for all top level component’s capture ports

\item {} 
\sphinxcode{\sphinxupquote{indices}}:  list of port numbers to append to top level component’s capture port name. It is possible to use Matlab’s colon operator to express a list of numbers in a compact fashion (es.”0:4” means appending numbers 0 to 3 to port names)

\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{externalport}}: Specification of an external jack client to connect to if \sphinxcode{\sphinxupquote{autoconnect}} is enabled.}] \leavevmode\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{client}}: Name of an external jack client to use as input for our top level component (es. “system”)

\item {} 
\sphinxcode{\sphinxupquote{portname}}: Common name for all external jack client input ports

\item {} 
\sphinxcode{\sphinxupquote{indices}}: List of port numbers that together with :code:{}` portname{}` describe existing external jack client input ports. It is possible to use Matlab’s colon operator to express a list of numbers.

\end{itemize}

\end{description}

\end{itemize}

\end{itemize}

\sphinxcode{\sphinxupquote{playback}}: Specifies that the following options regard the top level component’s playback ports only.
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{autoconnect}} : Enable/disable auto connection to an external jack client’s output ports, possible values are \sphinxcode{\sphinxupquote{true, false}}

\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{port}}: Jack ports specification}] \leavevmode\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{basename}}: Common name for all top level component’s playback ports

\item {} 
\sphinxcode{\sphinxupquote{indices}}:  list of port numbers to append to top level component’s playback port name. It is possible to use Matlab’s colon operator to express a list of numbers in a compact fashion (es.”0:4” means appending numbers 0 to 4 to port names)

\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{externalport}}: Specification of an external jack client to connect to if \sphinxcode{\sphinxupquote{autoconnect}} is enabled.}] \leavevmode\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{client}}: Name of an external jack client to use as output for our top level component (es. “system”)

\item {} 
\sphinxcode{\sphinxupquote{portname}}: Common name for all external jack client output ports

\item {} 
\sphinxcode{\sphinxupquote{indices}}: List of port numbers that together with :code:{}` portname{}` describe existing external jack client output ports. It is possible to use Matlab’s colon operator to express a list of numbers.

\end{itemize}

\end{description}

\end{itemize}

\end{description}

\end{itemize}


\subsubsection{Simple Example}
\label{\detokenize{using-standalone-renderers:simple-example}}
This configuration example shows how to auto-connect the Jack input and output ports of an application to the default jack client (\sphinxcode{\sphinxupquote{system}}), specifying which range of ports to connect.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}
  \PYG{n+nt}{\PYGZdq{}clientname\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}BaseRenderer\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}autoconnect\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}true\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}portconfig\PYGZdq{}}\PYG{p}{:}
  \PYG{p}{\PYGZob{}}
    \PYG{n+nt}{\PYGZdq{}capture\PYGZdq{}}\PYG{p}{:}
    \PYG{p}{\PYGZob{}}
      \PYG{n+nt}{\PYGZdq{}port\PYGZdq{}}\PYG{p}{:}
      \PYG{p}{[}\PYG{p}{\PYGZob{}} \PYG{n+nt}{\PYGZdq{}externalport\PYGZdq{}} \PYG{p}{:} \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}indices\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}1:4\PYGZdq{}}\PYG{p}{\PYGZcb{}} \PYG{p}{\PYGZcb{}}\PYG{p}{]}
    \PYG{p}{\PYGZcb{}}\PYG{p}{,}
    \PYG{n+nt}{\PYGZdq{}playback\PYGZdq{}}\PYG{p}{:}
    \PYG{p}{\PYGZob{}}
      \PYG{n+nt}{\PYGZdq{}port\PYGZdq{}}\PYG{p}{:}
      \PYG{p}{[}\PYG{p}{\PYGZob{}} \PYG{n+nt}{\PYGZdq{}externalport\PYGZdq{}} \PYG{p}{:} \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}indices\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}5:8\PYGZdq{}}\PYG{p}{\PYGZcb{}} \PYG{p}{\PYGZcb{}}\PYG{p}{]}
    \PYG{p}{\PYGZcb{}}
  \PYG{p}{\PYGZcb{}}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[scale=1.0]{{jacksimpleexample}.jpeg}
\caption{Jack audio complex configuration example.}\label{\detokenize{using-standalone-renderers:id3}}\label{\detokenize{using-standalone-renderers:figure-jack-config-simple-example}}\end{figure}


\subsubsection{Complex Example}
\label{\detokenize{using-standalone-renderers:complex-example}}
Follow a more complex example where auto-connection of ports is performed specifying different jack clients and the ranges of ports to be connected are described both for the top level component and for external clients.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}
  \PYG{n+nt}{\PYGZdq{}clientname\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}VisrRenderer\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}servername\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}autoconnect\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}true\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}portconfig\PYGZdq{}}\PYG{p}{:}
  \PYG{p}{\PYGZob{}}
    \PYG{n+nt}{\PYGZdq{}capture\PYGZdq{}}\PYG{p}{:}
    \PYG{p}{\PYGZob{}}
      \PYG{n+nt}{\PYGZdq{}autoconnect\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}true\PYGZdq{}}\PYG{p}{,}
      \PYG{n+nt}{\PYGZdq{}port\PYGZdq{}}\PYG{p}{:}
      \PYG{p}{[}
        \PYG{p}{\PYGZob{}}
         \PYG{n+nt}{\PYGZdq{}basename\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}Baseinput\PYGZus{}\PYGZdq{}} \PYG{p}{,}
         \PYG{n+nt}{\PYGZdq{}indices\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0:1\PYGZdq{}}\PYG{p}{,}
         \PYG{n+nt}{\PYGZdq{}externalport\PYGZdq{}} \PYG{p}{:}
          \PYG{p}{\PYGZob{}}
            \PYG{n+nt}{\PYGZdq{}client\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}REAPER\PYGZdq{}}\PYG{p}{,}
            \PYG{n+nt}{\PYGZdq{}portname\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}out\PYGZdq{}}\PYG{p}{,}
            \PYG{n+nt}{\PYGZdq{}indices\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}1:2\PYGZdq{}}
          \PYG{p}{\PYGZcb{}}
        \PYG{p}{\PYGZcb{}}\PYG{p}{,}
        \PYG{p}{\PYGZob{}}
         \PYG{n+nt}{\PYGZdq{}basename\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}Baseinput\PYGZus{}\PYGZdq{}} \PYG{p}{,}
         \PYG{n+nt}{\PYGZdq{}indices\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}2:3\PYGZdq{}}\PYG{p}{,}
         \PYG{n+nt}{\PYGZdq{}externalport\PYGZdq{}} \PYG{p}{:}
          \PYG{p}{\PYGZob{}}
            \PYG{n+nt}{\PYGZdq{}indices\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}4:5\PYGZdq{}}
          \PYG{p}{\PYGZcb{}}
         \PYG{p}{\PYGZcb{}}
      \PYG{p}{]}
    \PYG{p}{\PYGZcb{}}\PYG{p}{,}
    \PYG{n+nt}{\PYGZdq{}playback\PYGZdq{}}\PYG{p}{:}
    \PYG{p}{\PYGZob{}}
      \PYG{n+nt}{\PYGZdq{}autoconnect\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}true\PYGZdq{}}\PYG{p}{,}
      \PYG{n+nt}{\PYGZdq{}port\PYGZdq{}}\PYG{p}{:}
      \PYG{p}{[}\PYG{p}{\PYGZob{}}
        \PYG{n+nt}{\PYGZdq{}basename\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}Baseoutput\PYGZus{}\PYGZdq{}} \PYG{p}{,}
        \PYG{n+nt}{\PYGZdq{}indices\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0:1\PYGZdq{}}\PYG{p}{,}
        \PYG{n+nt}{\PYGZdq{}externalport\PYGZdq{}} \PYG{p}{:}
         \PYG{p}{\PYGZob{}}
          \PYG{n+nt}{\PYGZdq{}client\PYGZdq{}} \PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}system\PYGZdq{}}\PYG{p}{,}
          \PYG{n+nt}{\PYGZdq{}portname\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}playback\PYGZus{}\PYGZdq{}}\PYG{p}{,}
          \PYG{n+nt}{\PYGZdq{}indices\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}4:5\PYGZdq{}}
         \PYG{p}{\PYGZcb{}}
       \PYG{p}{\PYGZcb{}}\PYG{p}{]}
    \PYG{p}{\PYGZcb{}}
  \PYG{p}{\PYGZcb{}}
\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[scale=1.0]{{jackexample}.jpeg}
\caption{Jack audio complex configuration example.}\label{\detokenize{using-standalone-renderers:id4}}\label{\detokenize{using-standalone-renderers:figure-jack-config-complex-example}}\end{figure}


\chapter{Object-Based Audio with VISR}
\label{\detokenize{object-based-audio-with-visr:object-based-audio-with-visr}}\label{\detokenize{object-based-audio-with-visr:visr-object-based-audio}}\label{\detokenize{object-based-audio-with-visr::doc}}

\section{Overview}
\label{\detokenize{object-based-audio-with-visr:overview}}
Although the VISR framework is deliberately application-agnostic, it is well-suited for working with spatial and object-based audio.
This is due to a number of reasons:
\begin{itemize}
\item {} 
The focus on multichannel audio makes it suitable for object-based audio, which often features complex sound scenes consisting of many signals, as well as multichannel reproduction systems.

\item {} 
The ability to handle complex, also structure parameter data allows for the generation and transmission of object metadata within the system.

\item {} 
The modular, reusable component structure fosters the creation of complex signal flows that are often used in object-bases audio.

\item {} 
Last but not least, the VISR framework was conceived in the \sphinxhref{http://www.s3a-spatialaudio.org}{S3A project} a research project on spatial and object-based audio.

\end{itemize}

Consequently the VISR framework contains different types of functionality to support processing of object-based audio.
These are typically implemened as libraries, for example component libraries.


\section{The VISR object model}
\label{\detokenize{object-based-audio-with-visr:the-visr-object-model}}\label{\detokenize{object-based-audio-with-visr:id1}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.700\linewidth]{{visr_object_based_object_model_hierarchy}.png}
\caption{Object types and hierarchy.}\label{\detokenize{object-based-audio-with-visr:id9}}\end{figure}

The VISR object model supports a hierarchical and extensible set of object types.
These types and their relations are shown above.


\subsection{JSON representation}
\label{\detokenize{object-based-audio-with-visr:json-representation}}
For transmission, object vectors are encoded as JSON messages.

A scene vector (or a part thereof) has the format

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdq{}objects\PYGZdq{}: [ \PYGZob{}\PYGZlt{}object 0\PYGZgt{}\PYGZcb{}, \PYGZob{}\PYGZlt{}object 1\PYGZgt{}\PYGZcb{}, ... , \PYGZob{}\PYGZlt{}object n\PYGZgt{}\PYGZcb{}]
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{\textless{}object k\textgreater{}}} stands for the encoding of a single object. The objects can be arranged in arbitary order as long as the object ids are unique. Moreover, the object vector can be split into arbitrary subsets and be transmitted as individual \sphinxcode{\sphinxupquote{"objects"}} messages.


\subsection{Encoding of the individual object types}
\label{\detokenize{object-based-audio-with-visr:encoding-of-the-individual-object-types}}

\subsubsection{Coordinate system}
\label{\detokenize{object-based-audio-with-visr:coordinate-system}}
Depending on the object type, either Cartesian and spherical coordinates are use. The coordinate axes follow, e.g., the ITU-R BS.2051 conventions.

For Cartesian coordinates, this means:
\begin{itemize}
\item {} 
x axis points to the front

\item {} 
y axis points to the left.

\item {} 
z axis points up.

\end{itemize}

Coordinates are measured in meters.

Likewise, for spherical coordinates:
\begin{itemize}
\item {} 
The azimuth angle is measured counterclockwise from the x axis (front).

\item {} 
The elevation angle is measure up (positive values) or down (negative values) from the horizontal plane.

\end{itemize}

Coordinates are represented in the JSON format in degree (this does not necessarily hold for the internal representation in the renderer).


\subsubsection{Object}
\label{\detokenize{object-based-audio-with-visr:object}}
\sphinxcode{\sphinxupquote{Object}} is the base type of all objects. Therefore, the attributes are common to all objects.
The following attributes are supported:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{"id"}}}] \leavevmode
The object id, a nonnegative integer that must be unique withing the object vector (mandatory attribute).

\item[{\sphinxcode{\sphinxupquote{"group"}}}] \leavevmode
The group id, a nonnegative integer (mandatory attribute). Not used in the core renderer, but potentially in the metadata adaptation process.

\item[{\sphinxcode{\sphinxupquote{"channels"}}}] \leavevmode
A list of audio channel indices referencing the audio signals associated with this object. The list is formed as a string consisting of comma-separated unsigned integers enclosed in quotation marks, e.g., “0,3, 5, 7 ” with arbitrary amounts of whitespace in between. The format also allows Matlab-style ranges for any part of the list. For instance, “0, 2 : 2 : 8, 10” is equivalent to “0,2,4,6,8,10”. This is a mandatory argument. The reuired number of channels is typically determined by the object type and its parameters. For instance, point source objects are invariably single-channel, while the number of required channels of a HOA object depends on the Ambisonics order specified by the “order” of this object.

\item[{\sphinxcode{\sphinxupquote{"level"}}}] \leavevmode
The level of the audio object in linear scale as a floating-point number. Note that this value does not necessarily denote the loudness of the reproduced object, since the latter also depends on the level of the audio signal(s). (Mandatory argument).

\item[{\sphinxcode{\sphinxupquote{"priority"}}}] \leavevmode
The priority of the object given as an unsigned integer (mandatory argument). Lower numbers represent higher priority, with “0” being the highest prority. Not currently used in the core renderer, but potentially (and moe appropriately) in the metadata processing.

\item[{\sphinxcode{\sphinxupquote{"eq"}}}] \leavevmode
An array of parametric EQ parameters to be applied to all audio signals for this object. This is an optional attribute, if not present, a ‘flat’, i.e., unity-gain equalisation curve is applied. The attribute has the format

\end{description}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdq{}eq\PYGZdq{}: [\PYGZob{}\PYGZlt{}eq 0\PYGZgt{}\PYGZcb{}, \PYGZob{}\PYGZlt{}eq 1\PYGZcb{},...\PYGZob{}\PYGZlt{}eq n\PYGZhy{}1\PYGZgt{}\PYGZcb{}]
\end{sphinxVerbatim}

: The number of admissible EQ sections is renderer-dependent. Providing more EQ parameters for a single object than supported by the renderer might result in an error message and termination of the renderer. If less EQ parameters are sent than supported by the renderer, the remaining EQ sections are padded with ‘flat’ characteristics. The individual EQ section have the form

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZob{} \PYGZdq{}type\PYGZdq{}: \PYGZdq{}\PYGZlt{}type\PYGZgt{}\PYGZdq{}, \PYGZdq{}f\PYGZdq{}: (center/cutoff frequency), \PYGZdq{}q\PYGZdq{}: (quality) [, \PYGZdq{}gain\PYGZdq{}: (dB) \PYGZcb{}
\end{sphinxVerbatim}

with the following attributes:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{"type"}}}] \leavevmode
A type string chosen from the following values: \sphinxcode{\sphinxupquote{"lowpass"}}, \sphinxcode{\sphinxupquote{"highpass"}}, \sphinxcode{\sphinxupquote{"bandpass"}}, \sphinxcode{\sphinxupquote{"bandstop"}}, \sphinxcode{\sphinxupquote{"peak"}}, \sphinxcode{\sphinxupquote{"lowshelf"}}, \sphinxcode{\sphinxupquote{"highshelf"}}, \sphinxcode{\sphinxupquote{"allpass"}}.

\item[{\sphinxcode{\sphinxupquote{"f"}}}] \leavevmode
Centre/cutoff frequency in Hz (depending on the filter type).

\item[{\sphinxcode{\sphinxupquote{"q"}}}] \leavevmode
Dimensionless Q (quality) parameter.

\item[{\sphinxcode{\sphinxupquote{"gain"}}}] \leavevmode
Optional gain parameter (in dB). If not provided, the default value of 0 dB is used. Only used by the filter types \sphinxcode{\sphinxupquote{"peak"}}, \sphinxcode{\sphinxupquote{"lowshelf"}}, and \sphinxcode{\sphinxupquote{"highshelf"}}. The filter characteristics follow the \sphinxhref{http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt}{Audio EQ Cookbook formulas}.

\end{description}


\subsubsection{PointSource}
\label{\detokenize{object-based-audio-with-visr:pointsource}}
Point sources are invariable single-channel objects, that is the \sphinxcode{\sphinxupquote{"channels"}} attribute of the base type \sphinxcode{\sphinxupquote{Object}} must contain a single channel index.
The type string is \sphinxcode{\sphinxupquote{"point"}}.

The point source coordinates sre specified in the \sphinxcode{\sphinxupquote{"position"}}, which is an object holding either Cartesian coordinates \sphinxcode{\sphinxupquote{"x"}}, \sphinxcode{\sphinxupquote{"y"}}, and \sphinxcode{\sphinxupquote{"z"}} or spherical coordinates \sphinxcode{\sphinxupquote{"az"}}, \sphinxcode{\sphinxupquote{"el"}}, \sphinxcode{\sphinxupquote{"radius"}}


\paragraph{Example}
\label{\detokenize{object-based-audio-with-visr:example}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}} \PYG{n+nt}{\PYGZdq{}id\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}5\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}channels\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}2\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}type\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}point\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}group\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}2\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}priority\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}level\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0.350\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}position\PYGZdq{}}\PYG{p}{:} \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}x\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}3.0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}y\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}\PYGZhy{}0.5\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}z\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0.25\PYGZdq{}} \PYG{p}{\PYGZcb{}} \PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}

or, using polar coordinates,

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}} \PYG{n+nt}{\PYGZdq{}id\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}5\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}channels\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}2\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}type\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}point\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}group\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}2\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}priority\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}level\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0.350\PYGZdq{}}\PYG{p}{,}
  \PYG{n+nt}{\PYGZdq{}position\PYGZdq{}}\PYG{p}{:} \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}az\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}30\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}el\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}15.0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}radius\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}1.25\PYGZdq{}} \PYG{p}{\PYGZcb{}} \PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}


\subsubsection{PlaneWave}
\label{\detokenize{object-based-audio-with-visr:planewave}}
Plane waves differ from point sources that they do not exhibit distance-dependent attenuation and do not provide parallalax effects for moving listener positions. Because the main reproduction method in the VISR renderer at the moment is VBAP, plane waves are handled identically to point sources. This might change for alternative reproduction methods, including listener position adaptive VBAP.

Plane waves use the type \sphinxcode{\sphinxupquote{"plane"}} and are single-channel objects.

The plane wave representation uses an object \sphinxcode{\sphinxupquote{"direction"}} containing the attributes \sphinxcode{\sphinxupquote{"az"}} and \sphinxcode{\sphinxupquote{"el"}} to describe azimuth and elevation of the direction of the impinging source. The third parameter \sphinxcode{\sphinxupquote{"refDist"}} (reference distance) encodes the relative timing of the object’s audio signal: A value of 0 means that a sound event at signal time 0 is perceived at the central listener at time 0.


\paragraph{Example}
\label{\detokenize{object-based-audio-with-visr:id2}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}id\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mi}{5}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}channels\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mi}{5}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}type\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}plane\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}group\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}priority\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}level\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mf}{1.000000}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}direction\PYGZdq{}}\PYG{p}{:} \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}az\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mf}{30.0}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}el\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mf}{45.0}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}refdist\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mf}{12.00} \PYG{p}{\PYGZcb{}} \PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}


\subsubsection{PointSourceDiffuse}
\label{\detokenize{object-based-audio-with-visr:pointsourcediffuse}}
Point source with diffuseness are derived from PointSource and therefore support all attributes of the latter.
In addition they define the attribute \sphinxcode{\sphinxupquote{"diffuseness"}} that is a floating-point supposed to be in the range between 0.0 and 1.0 and describes the amount of diffuse energy relative to the point source radiation.

They are single-channel and use the type string \sphinxcode{\sphinxupquote{"pointdiffuse"}}.


\paragraph{Example}
\label{\detokenize{object-based-audio-with-visr:id3}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}id\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}5\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}channels\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}5\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}type\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}pointdiffuse\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}group\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}priority\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0\PYGZdq{}}\PYG{p}{,}
 \PYG{n+nt}{\PYGZdq{}level\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}1.0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}diffuseness\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0.35\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}position\PYGZdq{}}\PYG{p}{:} \PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}x\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}3.0\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}y\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}\PYGZhy{}0.5\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}z\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}0.25\PYGZdq{}} \PYG{p}{\PYGZcb{}} \PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}


\subsubsection{DiffuseSource}
\label{\detokenize{object-based-audio-with-visr:diffusesource}}
This source type describes a surrounding objects reproducing decorrelated signals obtained from the single object audio signal.

This object does not introduce any other attributes apart from those inherited from the base class Object. The type string is \sphinxcode{\sphinxupquote{"diffuse"}}.


\paragraph{Example}
\label{\detokenize{object-based-audio-with-visr:id4}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{p}{\PYGZob{}}\PYG{n+nt}{\PYGZdq{}id\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}channels\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}type\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}diffuse\PYGZdq{}}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}group\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}priority\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mi}{0}\PYG{p}{,} \PYG{n+nt}{\PYGZdq{}level\PYGZdq{}}\PYG{p}{:} \PYG{l+m+mf}{1.000000}\PYG{p}{\PYGZcb{}}
\end{sphinxVerbatim}


\subsubsection{HoaSource}
\label{\detokenize{object-based-audio-with-visr:hoasource}}
This source type represents a Ambisonics sound field of arbitrary order. It is a multichannel object where the number of channels depends on the Ambisonics order \(N\): \(ch=(N+1)^{2}\). The audio signals (as indexed by the \sphinxcode{\sphinxupquote{"channels"}} attribute, are expected to be in ACN channel order \sphinxurl{http://ambisonics.ch/standards/channels/}.

The type string is \sphinxcode{\sphinxupquote{"hoa"}}.


\paragraph{Example}
\label{\detokenize{object-based-audio-with-visr:id5}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZob{}\PYGZdq{}type\PYGZdq{}: \PYGZdq{}hoa\PYGZdq{}, \PYGZdq{}channels\PYGZdq{}: \PYGZdq{}0:8\PYGZdq{}, \PYGZdq{}group\PYGZdq{}: 0, \PYGZdq{}id\PYGZdq{}: 0, \PYGZdq{}level\PYGZdq{}: 1, \PYGZdq{}order\PYGZdq{}: 2, \PYGZdq{}priority\PYGZdq{}: 0\PYGZcb{},
\end{sphinxVerbatim}


\subsubsection{ChannelObject}
\label{\detokenize{object-based-audio-with-visr:channelobject}}
Channel objects are audio signals that are routed directly to a loudspeaker (or group of loudspeakers) specified by an id.

This type is derived from \sphinxcode{\sphinxupquote{Object}} and adds the \sphinxcode{\sphinxupquote{"outputChannels"}} attribute. This attribute is a string contains a list of loudspeaker ids (i.e., labels).
Channel objects can contain an arbitrary number of channels. The \sphinxcode{\sphinxupquote{outputChannels}} must contain an entry for each channel. This can be either a single label or a list of labels enclosed in square brackets.
In the latter case, the respective channel is routed to the list of loudspeakers.

An \sphinxcode{\sphinxupquote{diffuseness}} attribute controls the level of decorrelation applied, from 0.0 (no decorrelation) to 1.0 (fully replayed to the decorrelation filters). OPtional attribute, default is 0.0.

If a channel is routed to more than one loudspeaker, the levels of these loudspeakers are normalised using the same norm as the respective panner (VBAP, VBIP in case of separate high-frequency panning, or diffuse panning).


\paragraph{Example}
\label{\detokenize{object-based-audio-with-visr:id6}}
Single-channel object routed to a single loudspeaker:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZob{}\PYGZdq{}id\PYGZdq{}: 2, \PYGZdq{}channels\PYGZdq{}: \PYGZdq{}3\PYGZdq{}, \PYGZdq{}type\PYGZdq{}: \PYGZdq{}channel\PYGZdq{}, \PYGZdq{}group\PYGZdq{}: 0, \PYGZdq{}priority\PYGZdq{}: 0, \PYGZdq{}level\PYGZdq{}: 0.50000, \PYGZdq{}diffuseness\PYGZdq{}: 0.5,
  \PYGZdq{}outputChannels\PYGZdq{}: \PYGZdq{}M+030\PYGZdq{}\PYGZcb{} ]
\end{sphinxVerbatim}

Alternative syntax for single-channel syntax :

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZob{}\PYGZdq{}id\PYGZdq{}: 2, \PYGZdq{}channels\PYGZdq{}: \PYGZdq{}3\PYGZdq{}, \PYGZdq{}type\PYGZdq{}: \PYGZdq{}channel\PYGZdq{}, \PYGZdq{}group\PYGZdq{}: 0, \PYGZdq{}priority\PYGZdq{}: 0, \PYGZdq{}level\PYGZdq{}: 0.50000, \PYGZdq{}diffuseness\PYGZdq{}: 0.5,
 \PYGZdq{}outputChannels\PYGZdq{}: \PYGZdq{}[M+030]\PYGZdq{}\PYGZcb{} ]
\end{sphinxVerbatim}

Single channel routed to multiple loudspeakers:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZob{}\PYGZdq{}id\PYGZdq{}: 2, \PYGZdq{}channels\PYGZdq{}: \PYGZdq{}3\PYGZdq{}, \PYGZdq{}type\PYGZdq{}: \PYGZdq{}channel\PYGZdq{}, \PYGZdq{}group\PYGZdq{}: 0, \PYGZdq{}priority\PYGZdq{}: 0, \PYGZdq{}level\PYGZdq{}: 0.50000, \PYGZdq{}diffuseness\PYGZdq{}: 0.5,
 \PYGZdq{}outputChannels\PYGZdq{}: \PYGZdq{}[M+030, M\PYGZhy{}030]\PYGZdq{}\PYGZcb{} ]
\end{sphinxVerbatim}

Multiple channels routed to single or multiple loudspeakers:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZob{} \PYGZdq{}id\PYGZdq{}: 2, \PYGZdq{}channels\PYGZdq{}: \PYGZdq{}4:8\PYGZdq{}, \PYGZdq{}type\PYGZdq{}: \PYGZdq{}channel\PYGZdq{}, \PYGZdq{}group\PYGZdq{}: 0, \PYGZdq{}priority\PYGZdq{}: 0,
  \PYGZdq{}level\PYGZdq{}: 0.350000, \PYGZdq{}diffuseness\PYGZdq{}: 0.25,
  \PYGZdq{}outputChannels\PYGZdq{}: \PYGZdq{}M+000, [M+030], [M\PYGZhy{}030, U+030], U+110\PYGZdq{}\PYGZcb{}]
\end{sphinxVerbatim}


\subsubsection{PointSourceWithReverb}
\label{\detokenize{object-based-audio-with-visr:pointsourcewithreverb}}\label{\detokenize{object-based-audio-with-visr:visr-object-model-reverb-object}}
PointSourceWithReverb is a single-channel object that adds reverb to a PointSource. It uses the type string \sphinxcode{\sphinxupquote{"pointreverb"}}.
In addition to the Object and PointSource properties it defines an attribute “room” containing the objects \sphinxcode{\sphinxupquote{"ereflect"}} (early reflections) and \sphinxcode{\sphinxupquote{"lreverb"}} (late reverberation). \sphinxcode{\sphinxupquote{"ereflect"}} is an array of early reflection objects, consisting of IIR coefficients (\sphinxcode{\sphinxupquote{"biquadsos"}}, a point source position \sphinxcode{\sphinxupquote{"position"}} using the same format as in \sphinxcode{\sphinxupquote{PointSource}}, and additional level and delay information.

The maximum number of discrete reflections per reverb object is a configuration parameter of the renderer.

The \sphinxcode{\sphinxupquote{"lreverb"}} object contains parameter data in fixed frequency bands that are used to synthesize reverb tails.


\paragraph{Example}
\label{\detokenize{object-based-audio-with-visr:id7}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZob{} \PYGZdq{}type\PYGZdq{}: \PYGZdq{}pointreverb\PYGZdq{}, \PYGZdq{}channels\PYGZdq{}: \PYGZdq{}4\PYGZdq{}, \PYGZdq{}group\PYGZdq{}: 0, \PYGZdq{}id\PYGZdq{}: 1,\PYGZdq{}level\PYGZdq{}: 1,
  \PYGZdq{}position\PYGZdq{}: \PYGZob{}\PYGZdq{}x\PYGZdq{}: 1.5, \PYGZdq{}y\PYGZdq{}: 0.0, \PYGZdq{}z\PYGZdq{}: 0.0\PYGZcb{}, \PYGZdq{}priority\PYGZdq{}: 0,
  \PYGZdq{}room\PYGZdq{}: \PYGZob{}
  \PYGZdq{}ereflect\PYGZdq{}: [\PYGZob{}\PYGZdq{}biquadsos\PYGZdq{}: [\PYGZob{}\PYGZdq{}a0\PYGZdq{}: \PYGZdq{}1.00000e+00\PYGZdq{}, \PYGZdq{}a1\PYGZdq{}: \PYGZdq{}\PYGZhy{}1.05734e+00\PYGZdq{}, \PYGZdq{}a2\PYGZdq{}: \PYGZdq{}5.69314e\PYGZhy{}01\PYGZdq{},
                               \PYGZdq{}b0\PYGZdq{}: \PYGZdq{}3.87648e\PYGZhy{}01\PYGZdq{}, \PYGZdq{}b1\PYGZdq{}: \PYGZdq{}0.00000e+00\PYGZdq{}, \PYGZdq{}b2\PYGZdq{}: \PYGZdq{}0.00000e+00\PYGZdq{}\PYGZcb{},
                              ( more biquad coefficients)
                              \PYGZob{}\PYGZdq{}a0\PYGZdq{}: \PYGZdq{}1.00000e+00\PYGZdq{}, \PYGZdq{}a1\PYGZdq{}: \PYGZdq{}\PYGZhy{}7.20132e\PYGZhy{}02\PYGZdq{}, \PYGZdq{}a2\PYGZdq{}: \PYGZdq{}6.48827e\PYGZhy{}01\PYGZdq{},
                               \PYGZdq{}b0\PYGZdq{}: \PYGZdq{}1.00000e+00\PYGZdq{}, \PYGZdq{}b1\PYGZdq{}: \PYGZdq{}0.00000e+00\PYGZdq{}, \PYGZdq{}b2\PYGZdq{}: \PYGZdq{}0.00000e+00\PYGZdq{}\PYGZcb{}],
                \PYGZdq{}delay\PYGZdq{}: \PYGZdq{}0.00931\PYGZdq{}, \PYGZdq{}level\PYGZdq{}: \PYGZdq{}0.0603584806\PYGZdq{}, \PYGZdq{}position\PYGZdq{}: \PYGZob{}\PYGZdq{}az\PYGZdq{}: 337.0, \PYGZdq{}el\PYGZdq{}: \PYGZdq{}\PYGZhy{}1.00000\PYGZdq{}, \PYGZdq{}refdist\PYGZdq{}: \PYGZdq{}1.00000\PYGZdq{}\PYGZcb{} \PYGZcb{},
              ( more early reflections )
            ],
\PYGZdq{}lreverb\PYGZdq{}: \PYGZob{}\PYGZdq{}attacktime\PYGZdq{}: \PYGZdq{}0.01321, 0.01321, 0.01321, 0.01321, 0.01321, 0.01321, 0.01321, 0.01321, 0.01321\PYGZdq{},
            \PYGZdq{}decayconst\PYGZdq{}: \PYGZdq{}\PYGZhy{}4.50698, \PYGZhy{}5.02028, \PYGZhy{}5.75817, \PYGZhy{}5.36509, \PYGZhy{}5.42654, \PYGZhy{}5.62316, \PYGZhy{}5.75298, \PYGZhy{}6.41075, \PYGZhy{}11.13465\PYGZdq{},
            \PYGZdq{}level\PYGZdq{}: \PYGZdq{}0.02522, 0.01052, 0.01657, 0.02744, 0.02058, 0.01679, 0.01698, 0.01433, 0.00041\PYGZdq{}, \PYGZdq{}delay\PYGZdq{}: \PYGZdq{}0.00931\PYGZdq{} \PYGZcb{} \PYGZcb{}
\end{sphinxVerbatim}


\section{Predefined object-based rendering primitives and renderers}
\label{\detokenize{object-based-audio-with-visr:predefined-object-based-rendering-primitives-and-renderers}}
The default component library contains numerous atomic components for object-based audio as well as ready-made rendering signal flows.

These include:


\subsection{Atomic components}
\label{\detokenize{object-based-audio-with-visr:atomic-components}}\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{rcl.SceneDecoder}}

\item {} 
\sphinxcode{\sphinxupquote{rcl.SceneEncoder}}

\item {} 
\sphinxcode{\sphinxupquote{rcl.PanningCalculator}}

\item {} 
\sphinxcode{\sphinxupquote{rcl.ObjectGainEqCalculator}}

\item {} 
\sphinxcode{\sphinxupquote{rcl.HoaAllradGainCalculator}}

\item {} 
\sphinxcode{\sphinxupquote{rcl.CAPGainCalculator}}

\item {} 
\sphinxcode{\sphinxupquote{rcl.DiffusionGainCalculator}}

\item {} 
\sphinxcode{\sphinxupquote{rcl.ObjectGainEqCalculator}}

\end{itemize}


\subsection{Composite components}
\label{\detokenize{object-based-audio-with-visr:composite-components}}\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{signalflows.CoreRenderer}}

\item {} 
\sphinxcode{\sphinxupquote{signalflows.BaselineRenderer}}

\item {} 
\sphinxcode{\sphinxupquote{reverbobject.ReverbObjectRenderer}}

\item {} 
\sphinxcode{\sphinxupquote{visr\_bst.DynamicHrirRenderer}}

\item {} 
\sphinxcode{\sphinxupquote{visr\_bst.HoaObjectToBinauralRenderer}}

\item {} 
\sphinxcode{\sphinxupquote{visr\_bst.ObjectToVirtualLoudspeakerRenderer}}

\end{itemize}


\section{Standalone renderers}
\label{\detokenize{object-based-audio-with-visr:standalone-renderers}}
The loudspeaker renderers are described in Section {\hyperref[\detokenize{using-standalone-renderers:using-visr-using-standalone-renderers-visr-renderer}]{\sphinxcrossref{\DUrole{std,std-ref}{VISR object-based loudspeaker renderer}}}}.


\section{Object-Based Reverberation}
\label{\detokenize{object-based-audio-with-visr:object-based-reverberation}}\label{\detokenize{object-based-audio-with-visr:visr-object-based-audio-reverberation}}
\begin{sphinxadmonition}{note}{Note:}
This section will describe the support for object-based reverberation in the VISR renderers.
This is based on the reverb object \phantomsection\label{\detokenize{object-based-audio-with-visr:id8}}{\hyperref[\detokenize{references:coleman2017reverb}]{\sphinxcrossref{{[}CFJ+17{]}}}} using the object representation described in Section {\hyperref[\detokenize{object-based-audio-with-visr:visr-object-model-reverb-object}]{\sphinxcrossref{\DUrole{std,std-ref}{PointSourceWithReverb}}}}.
The functionality is contained in the library \sphinxcode{\sphinxupquote{reverbobject}} and the corresponding Python module \sphinxcode{\sphinxupquote{reverbobject}}.
\end{sphinxadmonition}


\section{The loudspeaker configuration format}
\label{\detokenize{object-based-audio-with-visr:the-loudspeaker-configuration-format}}\label{\detokenize{object-based-audio-with-visr:loudspeaker-configuration-file-format}}
Loudspeaker configurations are used to tell a renderer about the loudspeaker positions
and other properties of the setup.
It is used primarily in the loudspeaker renderers, including binaural renderering that use a virtual loudspeaker setup internally.

This section describes the format of a loudspeaker configuration and explains the helper functions provided with a VISR installation to create configuration files.


\subsection{Configuration file example}
\label{\detokenize{object-based-audio-with-visr:configuration-file-example}}
A loudspeaker configuration has to be specified in an XML file.

An example is given below.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nt}{\PYGZlt{}panningConfiguration}\PYG{n+nt}{\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}M+000\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}1\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}cart} \PYG{n+na}{x=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}} \PYG{n+na}{y=}\PYG{l+s}{\PYGZdq{}0.0\PYGZdq{}} \PYG{n+na}{z=}\PYG{l+s}{\PYGZdq{}0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}2\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}30.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}0.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}M+030\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}3\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}30.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}0.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}110\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}4\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}110.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}0.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}M+110\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}5\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}110.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}0.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}6\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}30.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}30.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}U+030\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}7\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}30.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}30.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}110\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}8\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}110.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}30.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}loudspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}U+110\PYGZdq{}} \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}9\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}110.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}30.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/loudspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}virtualspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}VoS\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}0.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}90.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M+000\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M+030\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M+110\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}110\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/virtualspeaker\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}VoS\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}M+110\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}VoS\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}VoS\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M+000\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M+000\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}M+030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}VoS\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M+000\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}M+030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}VoS\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M+110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U+030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M+000\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U+030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}M+030\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M+000\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}110\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}030\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}110\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U+110\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}110\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U+110\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}M+110\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U+030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}110\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}030\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U+030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}U+110\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}U\PYGZhy{}110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U+030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}U+110\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M+110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}triplet} \PYG{n+na}{l1=}\PYG{l+s}{\PYGZdq{}U+030\PYGZdq{}} \PYG{n+na}{l2=}\PYG{l+s}{\PYGZdq{}M+030\PYGZdq{}} \PYG{n+na}{l3=}\PYG{l+s}{\PYGZdq{}M+110\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}subwoofer} \PYG{n+na}{assignedLoudspeakers=}\PYG{l+s}{\PYGZdq{}M+000, M\PYGZhy{}030, M+030, M\PYGZhy{}110, M+110, U\PYGZhy{}030, U+030, U\PYGZhy{}110, U+110\PYGZdq{}}
          \PYG{n+na}{channel=}\PYG{l+s}{\PYGZdq{}10\PYGZdq{}} \PYG{n+na}{delay=}\PYG{l+s}{\PYGZdq{}0\PYGZdq{}} \PYG{n+na}{eq=}\PYG{l+s}{\PYGZdq{}lowpass\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}0\PYGZdq{}}
          \PYG{n+na}{weights=}\PYG{l+s}{\PYGZdq{}1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0\PYGZdq{}}
          \PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}outputEqConfiguration} \PYG{n+na}{numberOfBiquads=}\PYG{l+s}{\PYGZdq{}1\PYGZdq{}} \PYG{n+na}{type=}\PYG{l+s}{\PYGZdq{}iir\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
      \PYG{n+nt}{\PYGZlt{}filterSpec} \PYG{n+na}{name=}\PYG{l+s}{\PYGZdq{}lowpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
         \PYG{n+nt}{\PYGZlt{}biquad} \PYG{n+na}{a1=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}1.9688283\PYGZdq{}} \PYG{n+na}{a2=}\PYG{l+s}{\PYGZdq{}0.96907117\PYGZdq{}} \PYG{n+na}{b0=}\PYG{l+s}{\PYGZdq{}6.0729856e\PYGZhy{}05\PYGZdq{}} \PYG{n+na}{b1=}\PYG{l+s}{\PYGZdq{}0.00012145971\PYGZdq{}} \PYG{n+na}{b2=}\PYG{l+s}{\PYGZdq{}6.0729856e\PYGZhy{}05\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
      \PYG{n+nt}{\PYGZlt{}/filterSpec\PYGZgt{}}
      \PYG{n+nt}{\PYGZlt{}filterSpec} \PYG{n+na}{name=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
         \PYG{n+nt}{\PYGZlt{}biquad} \PYG{n+na}{a1=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}1.9688283\PYGZdq{}} \PYG{n+na}{a2=}\PYG{l+s}{\PYGZdq{}0.96907117\PYGZdq{}} \PYG{n+na}{b0=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}0.98447486\PYGZdq{}} \PYG{n+na}{b1=}\PYG{l+s}{\PYGZdq{}1.9689497\PYGZdq{}} \PYG{n+na}{b2=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}0.98447486\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
      \PYG{n+nt}{\PYGZlt{}/filterSpec\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/outputEqConfiguration\PYGZgt{}}
\PYG{n+nt}{\PYGZlt{}/panningConfiguration\PYGZgt{}}
\end{sphinxVerbatim}


\subsection{Predefined configuration files}
\label{\detokenize{object-based-audio-with-visr:predefined-configuration-files}}
The VISR package comes with a number of preconfigured loudspeaker configurations.
They are contained in the directory \sphinxcode{\sphinxupquote{\$VISR\_ROOT/config/}}.

The subdirectory \sphinxcode{\sphinxupquote{config/generic}} contains standard configurations, mainly from the \sphinxhref{https://www.itu.int/rec/R-REC-BS.2051/en}{ITU-R BS2051 standard}.

The supported configurations are:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|T|T|}
\hline
\sphinxstyletheadfamily 
Name
&\sphinxstyletheadfamily 
File name
&\sphinxstyletheadfamily 
Number of loudspeakers
(upper, horizontal, lower)
&\sphinxstyletheadfamily 
Dimension
&\sphinxstyletheadfamily 
Virtual loudspeakers
(azimuth, elevation)
&\sphinxstyletheadfamily 
Comment
\\
\hline
System A
&
bs2051-0+2+0
&
0, 2, 0
&
2D
&
(180,0)
&
Stereo
\\
\hline
System B
&
bs2051-0+5+0
&
0, 5, 0
&
2D
&
—
&
5.1
\\
\hline
System C
&
bs2051-2+5+0
&
2, 5, 0
&
3D
&
(0,90), (0,-90)
&\\
\hline
System D
&
bs2051-3+7+0
&
3, 7, 0
&
3D
&
(0,90), (0,-90)
&\\
\hline
System E
&
bs2051-4+5+0
&
4, 5, 0
&
3D
&
(0,90), (0,-90)
&\\
\hline
System F
&
bs2051-4+5+1
&
4, 5, 1
&
3D
&
(0,90), (0,-90)
&\\
\hline
System G
&
bs2051-4+9+0
&
4, 9, 0
&
3D
&
(0,90), (0,-90)
&\\
\hline
System H
&
bs2051-9+10+3
&
9, 10, 3
&
3D
&
(0,-90)
&
22.2 (NHK)
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

For all configurations, versions with and without subwoofer channels are provided. The version with subwoofer has
no suffix, the version without has \sphinxcode{\sphinxupquote{-no-subwoofer}} appended to the file name.
In general, the version with subwoofer should be preferred and the generated loudspeaker outputs are identical.
The output channel mapping is identical for both cases. In some cases the subwoofer channels are embedded
into the block of loudspeaker output channels. In the corresponding configurations without subwoofer, these
channels are not used.

For the stereo configuration, an additional configuration \sphinxcode{\sphinxupquote{bs2051-0+2+0-rear-fading.xml}} is provided in
which sound sources are faded out as they approach \(180^{\circ}\). In all other cases, the energy from virtual loudspeakers (as denoted in the table above) is distributed to neighboring real loudspeakers.

The subdirectories \sphinxcode{\sphinxupquote{config/isvr}}, \sphinxcode{\sphinxupquote{config/surrey}}, and \sphinxcode{\sphinxupquote{config/bbc}} contain examples of actual listening rooms.
The functions to generated these configurations are contained in the subdirectories \sphinxcode{\sphinxupquote{scripts/}} within these folders.


\subsection{Generation functions}
\label{\detokenize{object-based-audio-with-visr:generation-functions}}
To ease the creation of generation functions, the VISR framework provides several Python functions
to create the XML configuration files from a number of loudspeaker coordinates and additional optional parameters.
These functions are contained in the Python module \sphinxcode{\sphinxupquote{loudspeakerconfig}}.
If the VISR framework was installed through a binary installer and Python was configured as described in {\hyperref[\detokenize{installation:installation-python-setup-configuration}]{\sphinxcrossref{\DUrole{std,std-ref}{Configuration}}}}, then the package can be directly imported, e.g.,

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{import} \PYG{n+nn}{loudspeakerconfig}
\PYG{n}{loudspeakerconfig}\PYG{o}{.}\PYG{n}{createArrayConfigFile}\PYG{p}{(} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.} \PYG{p}{)}
\end{sphinxVerbatim}

or

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{from} \PYG{n+nn}{loudspeakerconfig} \PYG{k+kn}{import} \PYG{n}{createArrayConfigFile}\PYG{p}{(} \PYG{o}{.}\PYG{o}{.}\PYG{o}{.} \PYG{p}{)}
\end{sphinxVerbatim}

The main function in this module is \sphinxcode{\sphinxupquote{createArrayConfigFile()}}.
It takes a set of loudspeaker coordinates, an output file name, and a large set of additional options:
\index{createArrayConfigFile() (in module loudspeakerconfig)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{object-based-audio-with-visr:loudspeakerconfig.createArrayConfigFile}}\pysiglinewithargsret{\sphinxcode{\sphinxupquote{loudspeakerconfig.}}\sphinxbfcode{\sphinxupquote{createArrayConfigFile}}}{\emph{outputFileName}, \emph{lspPositions}, \emph{twoDconfig=False}, \emph{sphericalPositions=False}, \emph{channelIndices=None}, \emph{loudspeakerLabels=None}, \emph{triplets=None}, \emph{distanceDelay=False}, \emph{distanceAttenuation=False}, \emph{lspDelays=None}, \emph{lspGainDB=None}, \emph{eqConfiguration=None}, \emph{virtualLoudspeakers={[}{]}}, \emph{subwooferConfig={[}{]}}, \emph{comment=None}, \emph{speedOfSound=340.0}}{}
Generate a loudspeaker configuration XML file.
\begin{quote}\begin{description}
\item[{Parameters}] \leavevmode\begin{itemize}
\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{outputFileName}} (\sphinxstyleliteralemphasis{\sphinxupquote{string}}) \textendash{} The file name of the XML file to be written. This can be a file name or path.
The file extension (typically .xml) must be provided by the user.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{lspPositions}} (\sphinxstyleliteralemphasis{\sphinxupquote{array-like}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{3xL}}\sphinxstyleliteralemphasis{\sphinxupquote{ or }}\sphinxstyleliteralemphasis{\sphinxupquote{2xL}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{where L is the number of loudspeakers.}}) \textendash{} Provide the loudspeaker in Cartesian coordinates, relative to the centre of the array.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{twoDconfig}} (\sphinxstyleliteralemphasis{\sphinxupquote{bool}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} Whether the loudspeaker configuration is 2D or 3D (default). In the former case, the lspPositions
parameter does not need to have a third row, and it is ignored if present. If twoDconfig if True,
then the loudspeaker coordinates in the do not have an “z” or “el” coordinate. Likewise,
the triangulation “triplets” consist only of two loudspeakers.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{sphericalPositions}} (\sphinxstyleliteralemphasis{\sphinxupquote{bool}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} Specify whether the loudspeaker and virtual loudspeaker positions are written in spherical (True)
or Cartesian coordinates (False). Default is Cartesian.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{channelIndices}} (\sphinxstyleliteralemphasis{\sphinxupquote{array-like}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} A list of output integer channel indices, one for each real loudspeaker. Optional argument, if not provided, consecutive indices starting from 1 are assigned. If provided, the length of the array must match the number of real loudspeakers, and indices must be unique.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{loudspeakerLabels}} (\sphinxstyleliteralemphasis{\sphinxupquote{array-like}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} A list of strings containing alphanumerical labels for the real loudspeakers.
Labels must be unique, consist of the characters ‘a-zA-Z0-9\&()+:\_-‘, one for
each real loudspeaker. The labels are used to reference loudspeakers in triplets,
virtual loudspeaker routings, and subwoofer configs.
Optional parameter. If not provided, labels of the form ‘lsp\_i’ with i=1,2,…
are generated.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{triplets}} (\sphinxstyleliteralemphasis{\sphinxupquote{array-like}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional.}}) \textendash{} A loudspeaker triangulation. To be provided as a list of arrays consisting of three
(or two in case of a 2D configuration) loudspeaker labels. Labels must match
existing values of the loudspeakerLabels  parameter.
Optional parameter, to be provided only in special cases. By default, the
triangulation is computed internally.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{distanceDelay}} (\sphinxstyleliteralemphasis{\sphinxupquote{bool}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} Whether the loudspeaker signals are delayed such that they arrive simultaneously in the array centre.
This can be used if the loudspeaker distances to the centre ar not equal. In this case
the farthest loudspeaker gets a delay of 0 s, and closer loudpeakers a positive delay.
The distance compensation delay is added to the \sphinxcode{\sphinxupquote{lspDelays}} parameter (if present).
Optional attribute. The default (False) means no distance attenuation is used.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{distanceAttenuation}} (\sphinxstyleliteralemphasis{\sphinxupquote{bool}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} Whether the loudspeaker gains shall be scaled if the loudspeaker distances are not 1.0.
In this case, a 1/r distance law is applied such that the farthest loudspeaker
gets a scaling factor of 0 dB, and lower factors are assigned to loudspeakers closer to the centre.
The gain factors are applied on top of the optional parameter \sphinxcode{\sphinxupquote{lspGainDB}}, if present.
Optional attribute. Default is False (no distance attenutation applied)

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{lspDelays}} (\sphinxstyleliteralemphasis{\sphinxupquote{array-like}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} An array of delay values to be applied tothe loudspeakers. Values are to be provided in seconds.
If not provided, no delays are applied. If specified, the length of the array must match the
number of real loudspeakers.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{lspGainDB}} (\sphinxstyleliteralemphasis{\sphinxupquote{array-like}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional.}}) \textendash{} An array of gain values (in dB) to adjust the output gains of the real loudpeakers.
If provided, the length must match the number of real loudspeakers.
By default, no additional gains are applied.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{virtualLoudspeakers}} (\sphinxstyleliteralemphasis{\sphinxupquote{array of dicts}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} 
Provide a set of additional virtual/phantom/dead/imaginary loudspeaker nodes to adjust the triangulation of the array. Each entry is a dict consisting of the following key-value pairs.
\begin{itemize}
\item {} 
”id”: A alphanumeric id, following the same rules as the loudspeaker indices. Must be unique across all real and imaginary loudspeakers.

\item {} 
”pos”: A 3- or vector containing the position in Cartesian coordinates. 2 elements are allowed for 2D setups.

\item {} 
”routing”: Specification how the panning gains calculated for this loudspeaker are distributed to neighbouring real loudspeakers. Provided as a list of tuples (label, gain), where label is the id of a real loudspeaker and gain is a linear gain value. Optional element, if not given, the energy of the virtual loudspeaker is discarded.

\end{itemize}

Optional argument. No virtual loudspeakers are created if not specified.


\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{eqConfiguration}} (\sphinxstyleliteralemphasis{\sphinxupquote{array of structures}}\sphinxstyleliteralemphasis{\sphinxupquote{ (}}\sphinxstyleliteralemphasis{\sphinxupquote{dicts}}\sphinxstyleliteralemphasis{\sphinxupquote{)}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} 
Define a set of EQ filters to be applied to loudspeaker and subwoofer output channels. Each entry of the list is a dict containing the following key-value pairs.
\begin{itemize}
\item {} 
”name”: A unique, nonempty id that is referenced in loudspeaker and subwoofer specifications.

\item {} 
”filter”: A list of biquad definitions, where each element is a dictionary containing the keys ‘b’ and ‘a’ that represent the numerator and denominator of the transfer function. ‘b’ must be a 3-element numeric vector, and ‘a’ a three- or two-element numeric vector. In the latter case, the leading coefficient is assumed to be 1, i.e., a normalised transfer function.

\item {} 
”loudspeakers”: A list of loudspeaker labels (real loudspeakers) to whom the eq is applied.

\end{itemize}


\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{subwooferConfig}} (\sphinxstyleliteralemphasis{\sphinxupquote{array of dicts}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} 
A list of subwoofer specifications, where each entry is a dictionary with the following key-value pairs:
\begin{itemize}
\item {} 
”name”: A string to name the subwoofer. If not provided, a default name will be generated.

\item {} 
”channel”: An output channel number for the subwoofer signal. Must be unique across all loudspeakers and subwoofers.

\item {} 
”assignedSpeakers”: A list of ids of (real) loudspeakers. The signals of these loudspeakers are used in the computation of the subwoofer signal.

\item {} 
”weights”: An optional weighting applied to the loudspeaker signals of the the assigned loudspeakers. If provided, it must be an array-like sequence with the same length as assignedSpeakers. If not given, all assigned speakers are weighted equally with factor “1.0”.

\end{itemize}


\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{comment}} (\sphinxstyleliteralemphasis{\sphinxupquote{string}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} Optional string to be written as an XML comment at the head of the file.

\end{itemize}

\end{description}\end{quote}
\paragraph{Examples}

A minimal example of a 3D configuration:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{createArrayConfigFile}\PYG{p}{(} \PYG{l+s+s1}{\PYGZsq{}}\PYG{l+s+s1}{bs2051\PYGZhy{}4+5+0.xml}\PYG{l+s+s1}{\PYGZsq{}}\PYG{p}{,}
                       \PYG{n}{lspPositions} \PYG{o}{=} \PYG{n}{lspPos}\PYG{p}{,}
                       \PYG{n}{twoDconfig} \PYG{o}{=} \PYG{n+nb+bp}{False}\PYG{p}{,}
                       \PYG{n}{sphericalPositions}\PYG{o}{=}\PYG{n+nb+bp}{True}\PYG{p}{,}
                       \PYG{n}{channelIndices} \PYG{o}{=} \PYG{p}{[}\PYG{l+m+mi}{1}\PYG{p}{,} \PYG{l+m+mi}{2}\PYG{p}{,} \PYG{l+m+mi}{3}\PYG{p}{,} \PYG{l+m+mi}{5}\PYG{p}{,} \PYG{l+m+mi}{6}\PYG{p}{,} \PYG{l+m+mi}{7}\PYG{p}{,} \PYG{l+m+mi}{8}\PYG{p}{,} \PYG{l+m+mi}{9}\PYG{p}{,} \PYG{l+m+mi}{10}\PYG{p}{]}\PYG{p}{,}
                       \PYG{n}{loudspeakerLabels} \PYG{o}{=}  \PYG{p}{[}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M+030}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M\PYGZhy{}030}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M+000}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M+110}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M\PYGZhy{}110}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,}
                          \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{U+030}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{U\PYGZhy{}030}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{U+110}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{U\PYGZhy{}110}\PYG{l+s+s2}{\PYGZdq{}}  \PYG{p}{]}\PYG{p}{,}
                       \PYG{n}{virtualLoudspeakers} \PYG{o}{=} \PYG{p}{[} \PYG{p}{\PYGZob{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{id}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{VotD}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{pos}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{p}{[}\PYG{l+m+mf}{0.0}\PYG{p}{,} \PYG{l+m+mf}{0.0}\PYG{p}{,}\PYG{o}{\PYGZhy{}}\PYG{l+m+mf}{1.0}\PYG{p}{]}\PYG{p}{,}
                                            \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{routing}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{:} \PYG{p}{[} \PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M+030}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+m+mf}{0.2}\PYG{p}{)}\PYG{p}{,} \PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M\PYGZhy{}030}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+m+mf}{0.2}\PYG{p}{)}\PYG{p}{,}
                                             \PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M+000}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+m+mf}{0.2}\PYG{p}{)}\PYG{p}{,} \PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M+110}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+m+mf}{0.2}\PYG{p}{)}\PYG{p}{,} \PYG{p}{(}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{M\PYGZhy{}110}\PYG{l+s+s2}{\PYGZdq{}}\PYG{p}{,} \PYG{l+m+mf}{0.2}\PYG{p}{)} \PYG{p}{]} \PYG{p}{\PYGZcb{}}\PYG{p}{]}
\end{sphinxVerbatim}

\end{fulllineitems}


The function \sphinxtitleref{createArrayConfigFromSofa()} can be used to create configuration files from a SOFA file to be used, for example in a virtual loudspeaker renderer (\sphinxcode{\sphinxupquote{visr\_bst.VirtualLoudspeakerRenderer}}):
\index{createArrayConfigFromSofa() (in module loudspeakerconfig)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{object-based-audio-with-visr:loudspeakerconfig.createArrayConfigFromSofa}}\pysiglinewithargsret{\sphinxcode{\sphinxupquote{loudspeakerconfig.}}\sphinxbfcode{\sphinxupquote{createArrayConfigFromSofa}}}{\emph{sofaFile}, \emph{xmlFile=None}, \emph{lspLabels=None}, \emph{twoDSetup=False}, \emph{virtualLoudspeakers={[}{]}}}{}
Create a loudspeaker configuraton file from a SOFA file containing a number of emitters representing loudspeakers.
\begin{quote}\begin{description}
\item[{Parameters}] \leavevmode\begin{itemize}
\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{sofaFile}} (\sphinxstyleliteralemphasis{\sphinxupquote{string}}) \textendash{} A file path to a SOFA file.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{xmlFile}} (\sphinxstyleliteralemphasis{\sphinxupquote{string}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} Path of the XML output file to be written.
Optional argument, if not provided, the SOFA file path is used with the extension replaced by “.xml”

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{lspLabels}} (\sphinxstyleliteralemphasis{\sphinxupquote{list of strings}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} List of loudspeaker labels, must match the number of emitters in the SOFA files.
If not provided, numbered labels are automatically generated.

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{twoDSetup}} (\sphinxstyleliteralemphasis{\sphinxupquote{bool}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} Flag specifying whether the aray is to be considered plane (True) or 3D (False).
Optional value, dafault is False (3D).

\item {} 
\sphinxstyleliteralstrong{\sphinxupquote{virtualLoudspeakers}} (\sphinxstyleliteralemphasis{\sphinxupquote{list}}\sphinxstyleliteralemphasis{\sphinxupquote{, }}\sphinxstyleliteralemphasis{\sphinxupquote{optional}}) \textendash{} A list of virtual loudspeakers to be added to the setup. Each entry must be a Python dict as decribed
in the function {\hyperref[\detokenize{object-based-audio-with-visr:loudspeakerconfig.createArrayConfigFile}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{loudspeakerconfig.createArrayConfigFile()}}}}}.

\end{itemize}

\end{description}\end{quote}

\end{fulllineitems}



\subsection{Format description}
\label{\detokenize{object-based-audio-with-visr:format-description}}
The root node of the XML file is \sphinxcode{\sphinxupquote{\textless{}panningConfiguration\textgreater{}}}.
This root element supports the following optional attributes:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{isInfinite}}}] \leavevmode
Whether the loudspeakers are regarded as point sources located on the unit sphere (\sphinxcode{\sphinxupquote{false}}) or as plane waves, corresponding to an infinite distance (\sphinxcode{\sphinxupquote{true}}). The default value is \sphinxcode{\sphinxupquote{false}}.

\item[{\sphinxcode{\sphinxupquote{dimension}}}] \leavevmode
Whether the setup is considered as a 2-dimensional configuration (value \sphinxcode{\sphinxupquote{2}}) or as three-dimensional (\sphinxcode{\sphinxupquote{3}}, thedefault). In the 2D case, the array is considered in the x-y plane , and the \sphinxcode{\sphinxupquote{z}} or \sphinxcode{\sphinxupquote{el}} attributes of the loudspeaker positions are not evaluated. In this case, the triplet specifications consist of two indices only (technically they are pairs, not triplets).

\end{description}

Within the \sphinxcode{\sphinxupquote{\textless{}panningConfiguration\textgreater{}}} root element, the following elements are supported:
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\textless{}loudspeaker\textgreater{}}}}] \leavevmode
Represents a reproduction loudspeaker.
The position  is encoded either in a \sphinxcode{\sphinxupquote{\textless{}cart\textgreater{}}} node representing the cartesian coordinates in the \sphinxcode{\sphinxupquote{x}}, \sphinxcode{\sphinxupquote{y}} and \sphinxcode{\sphinxupquote{z}} attributes (floating point values in meter), or a \sphinxcode{\sphinxupquote{\textless{}polar\textgreater{}}} node with the attributes \sphinxcode{\sphinxupquote{az}} and \sphinxcode{\sphinxupquote{el}} (azimuth and elevation, both in degree) and \sphinxcode{\sphinxupquote{r}} (radius, in meter).

The \sphinxcode{\sphinxupquote{\textless{}loudspeaker\textgreater{}}} nodes supports for a number of attributes:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{id}} A mandatory, non-empty string identification for the loudspeaker, which must be unique across all \sphinxcode{\sphinxupquote{\textless{}loudspeaker\textgreater{}}} and \sphinxcode{\sphinxupquote{\textless{}virtualspeaker\textgreater{}}} (see below) elements.
Permitted are alpha-numeric characters, numbers, and the characters “@\&()+/:\_-“.
ID strings are case-sensitive.

\item {} 
\sphinxcode{\sphinxupquote{channel}} The output channel number (sound card channel) for this loudspeaker. Logical channel indices start from 1. Each channel must be assigned at most once over the set of all loudspeaker and subwoofers of the setup..

\item {} 
\sphinxcode{\sphinxupquote{gainDB}} or \sphinxcode{\sphinxupquote{gain}} Additional gain adjustment for this loudspeaker, either in linear scale or in dB (floating-point values. The  default value is 1.0 or 0 dB.  \sphinxcode{\sphinxupquote{gainDB}} or \sphinxcode{\sphinxupquote{gain}} are mutually exclusive.

\item {} 
\sphinxcode{\sphinxupquote{delay}} Delay adjustment to be applied to this loudspeaker as a floating-point value in seconds. The default value is  0.0).

\item {} 
\sphinxcode{\sphinxupquote{eq}} An optional output equalisation filter to be applied for this loudspeaker.
Specified as a non-empty string that needs to match an \sphinxcode{\sphinxupquote{filterSpec}} element in the \sphinxcode{\sphinxupquote{outputEqConfiguration}}
element (see below). If not given, no EQ is applied to for this loudspeaker.

\end{itemize}

\item[{\sphinxcode{\sphinxupquote{\textless{}virtualspeaker\textgreater{}}}}] \leavevmode
An additional vertex added to the triangulation that does not correspond to a physical loudspeaker. Consist of a numerical \sphinxcode{\sphinxupquote{id}} attribute and a position specified either as a \sphinxcode{\sphinxupquote{\textless{}cart\textgreater{}}} or a \sphinxcode{\sphinxupquote{\textless{}polar\textgreater{}}} node (see \sphinxcode{\sphinxupquote{\textless{}loudspeaker\textgreater{}}} specification).

The \sphinxcode{\sphinxupquote{\textless{}virtualspeaker\textgreater{}}} node provides the following configuration options:
\begin{itemize}
\item {} 
A mandatory, nonempty and unique attribute \sphinxcode{\sphinxupquote{id}} that follows the same rules as for the \sphinxcode{\sphinxupquote{\textless{}loudspeaker\textgreater{}}} elements.

\item {} 
A number of \sphinxcode{\sphinxupquote{route}} sub-elements that specify how the energy from this virtual loudspeaker is routed to real loudspeakers.
The \sphinxcode{\sphinxupquote{route}} element has the following attributes:
* \sphinxcode{\sphinxupquote{lspId}}: The ID of an existing real loudspeaker.
* \sphinxcode{\sphinxupquote{gainDB}}: A scaling factor with which the gain of the virtual loudspeaker is distributed to the real loudspeaker.

In the above example, the routing specification is given by

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
 \PYG{n+nt}{\PYGZlt{}virtualspeaker} \PYG{n+na}{id=}\PYG{l+s}{\PYGZdq{}VoS\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}polar} \PYG{n+na}{az=}\PYG{l+s}{\PYGZdq{}0.0\PYGZdq{}} \PYG{n+na}{el=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}90.0\PYGZdq{}} \PYG{n+na}{r=}\PYG{l+s}{\PYGZdq{}1.0\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M+000\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M+030\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}030\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M+110\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}route} \PYG{n+na}{lspId=}\PYG{l+s}{\PYGZdq{}M\PYGZhy{}110\PYGZdq{}} \PYG{n+na}{gainDB=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}13.9794\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
\PYG{n+nt}{\PYGZlt{}/virtualspeaker\PYGZgt{}}
\end{sphinxVerbatim}

That means that the energy of the virtual speaker \sphinxcode{\sphinxupquote{"vos"}} is routed to five surrounding speakers, with a scaling factor of 13.97 dB each.

\end{itemize}

\end{description}

\sphinxcode{\sphinxupquote{\textless{}subwoofer\textgreater{}}} Specify a subwoofer channel. In the current implementation, the loudspeaker are weighted and mixed into an arbitray number of subwoofer channels. The attributes are:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{assignedLoudspeakers}} The loudspeaker signals (given as a sequence of logical loudspeaker IDs) that contribute to the subwoofer signals. Given as comma-separated list of loudspeaker index or loudspeaker ranges. Index sequences are similar to Matlab array definitions, except that thes commas separating the parts of the sequence are compulsory.

Complex example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
assignedLoudspeakers = \PYGZdq{}1, 3,4,5:7, 2, 8:\PYGZhy{}3:1\PYGZdq{}
\end{sphinxVerbatim}

\item {} 
\sphinxcode{\sphinxupquote{weights}} Optional weights (linear scale) that scale the contributions of the assigned speakers to the subwoofer signal.
Given as a sequence of comma-separated linear-scale gain values, Matlab ranges are also allowed. The number of elements must match the \sphinxcode{\sphinxupquote{assignedLoudspeakers}} index list. Optional value, the default option assigns 1.0 for all assigned loudspeakers.
Example: “0:0.2:1.0, 1, 1, 1:-0.2:0”.

\item {} 
\sphinxcode{\sphinxupquote{gainDB}} or \sphinxcode{\sphinxupquote{gain}} Additional gain adjustment for this subwoofer, either in linear scale or in dB (floating-point valus, default 1.0 / 0 dB ). Applied on top of the \sphinxcode{\sphinxupquote{weight}} attributes to the summed subwoofer signal. See the \sphinxcode{\sphinxupquote{\textless{}loudspeaker\textgreater{}}} specification.

\item {} 
\sphinxcode{\sphinxupquote{delay}} Delay adjustment for this (floating-point value in seconds, default 0.0). See the \sphinxcode{\sphinxupquote{\textless{}loudspeaker\textgreater{}}} specification.

\end{itemize}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{\textless{}triplet\textgreater{}}}}] \leavevmode
Loudspeaker triplet specified by the attributes \sphinxcode{\sphinxupquote{l1}}, \sphinxcode{\sphinxupquote{l2}}, and \sphinxcode{\sphinxupquote{l3}}.
The values of \sphinxcode{\sphinxupquote{l1}}, \sphinxcode{\sphinxupquote{l2}}, and \sphinxcode{\sphinxupquote{l3}} must correspond to IDs of existing real or virtual loudspeakers.
In case of a 2D setup, only \sphinxcode{\sphinxupquote{l1}} and \sphinxcode{\sphinxupquote{l2}} are evaluated.

\begin{sphinxadmonition}{note}{Note:}
At the time being, triplet specifications must be generated externally and placed in the configuration file.
This is typically done by creating a Delaunay triangulation on the sphere, which can be done in Matlab or Python.

Future versions of the loudspeaker renderer might perform the triangulation internally, or might not require a
conventional triangulation at all. In these cases, is it possible that the renderer ignores or internally
adapts the specified triplets.
\end{sphinxadmonition}

\item[{\sphinxcode{\sphinxupquote{outputEqConfiguration}}}] \leavevmode
This optional element must occur at most once.
It provides a global specification for equalisation filters for loudspeakers and subwoofers.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n+nt}{\PYGZlt{}outputEqConfiguration}  \PYG{n+na}{type=}\PYG{l+s}{\PYGZdq{}iir\PYGZdq{}} \PYG{n+na}{numberOfBiquads=}\PYG{l+s}{\PYGZdq{}1\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}filterSpec} \PYG{n+na}{name=}\PYG{l+s}{\PYGZdq{}lowpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}biquad} \PYG{n+na}{a1=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}1.9688283\PYGZdq{}} \PYG{n+na}{a2=}\PYG{l+s}{\PYGZdq{}0.96907117\PYGZdq{}} \PYG{n+na}{b0=}\PYG{l+s}{\PYGZdq{}6.0729856e\PYGZhy{}05\PYGZdq{}} \PYG{n+na}{b1=}\PYG{l+s}{\PYGZdq{}0.00012145971\PYGZdq{}} \PYG{n+na}{b2=}\PYG{l+s}{\PYGZdq{}6.0729856e\PYGZhy{}05\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/filterSpec\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}filterSpec} \PYG{n+na}{name=}\PYG{l+s}{\PYGZdq{}highpass\PYGZdq{}}\PYG{n+nt}{\PYGZgt{}}
    \PYG{n+nt}{\PYGZlt{}biquad} \PYG{n+na}{a1=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}1.9688283\PYGZdq{}} \PYG{n+na}{a2=}\PYG{l+s}{\PYGZdq{}0.96907117\PYGZdq{}} \PYG{n+na}{b0=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}0.98447486\PYGZdq{}} \PYG{n+na}{b1=}\PYG{l+s}{\PYGZdq{}1.9689497\PYGZdq{}} \PYG{n+na}{b2=}\PYG{l+s}{\PYGZdq{}\PYGZhy{}0.98447486\PYGZdq{}}\PYG{n+nt}{/\PYGZgt{}}
  \PYG{n+nt}{\PYGZlt{}/filterSpec\PYGZgt{}}
\PYG{n+nt}{\PYGZlt{}/outputEqConfiguration\PYGZgt{}}
\end{sphinxVerbatim}

The  attributes are:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{type}}: The type of the output filters. At the moment, only IIR filters provide as second-order sections (biquads) are supported. Thus, the value \sphinxcode{\sphinxupquote{"iir"}} must be set.

\item {} 
\sphinxcode{\sphinxupquote{numberOfBiquads}}: This value is specific to the \sphinxcode{\sphinxupquote{"iir"}} filter type.

\end{itemize}

The filters are described in \sphinxcode{\sphinxupquote{filterSpec}} elements.
These are identifed by a \sphinxcode{\sphinxupquote{name}} attribute, which must be an non-empty string unique across all \sphinxcode{\sphinxupquote{filterSpec}} elements.
For the type \sphinxcode{\sphinxupquote{iir}}, a \sphinxcode{\sphinxupquote{filterSpec}} element consists of at most \sphinxcode{\sphinxupquote{numberOfBiquad}} nodes of type \sphinxcode{\sphinxupquote{biquad}}, which represent the coefficients of one second-order IIR (biquad) section.
This is done through the attributes \sphinxcode{\sphinxupquote{a1}},  \sphinxcode{\sphinxupquote{a2}}, \sphinxcode{\sphinxupquote{b0}}, \sphinxcode{\sphinxupquote{b1}}, \sphinxcode{\sphinxupquote{b2}} that represent the coefficients of the normalised transfer function
\begin{equation*}
\begin{split}H(z) = \frac{ b_0 + b_1 z^{-1} + b_{2}z^{-2} }{1 + a_1 z^{-1} + a_{2}z^{-2}}\end{split}
\end{equation*}
\end{description}


\chapter{The default component library}
\label{\detokenize{rcl_component_documentation:the-default-component-library}}\label{\detokenize{rcl_component_documentation:visr-default-component-library-reference}}\label{\detokenize{rcl_component_documentation::doc}}
\begin{sphinxadmonition}{note}{Note:}
The component documentation is extracted from the Python classes (or Python bindings in case of C++ classes).
For the exact C++ interfaces, see the VISR API documentation or the header documentation in the C++ code.

This information is also avalaible through Python’s interactive documentation, e.g., through

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{g+gp}{\PYGZgt{}\PYGZgt{}\PYGZgt{} }\PYG{k+kn}{import} \PYG{n+nn}{rcl}
\PYG{g+gp}{\PYGZgt{}\PYGZgt{}\PYGZgt{} }\PYG{n}{help}\PYG{p}{(} \PYG{n}{rcl}\PYG{o}{.}\PYG{n}{Add} \PYG{p}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\section{Module \sphinxstyleliteralintitle{\sphinxupquote{rcl}} overview}
\label{\detokenize{rcl_component_documentation:module-rcl-overview}}\label{\detokenize{rcl_component_documentation:visr-component-library-reference-rcl}}
The \sphinxcode{\sphinxupquote{rcl}} library is the default library for atomic components.
It is contained in the default distribution of the VISR.

\begin{sphinxadmonition}{note}{Note:}
The separation into a library for atomic components (\sphinxcode{\sphinxupquote{rcl}}) and composite components
({\hyperref[\detokenize{rcl_component_documentation:visr-component-library-reference-composite}]{\sphinxcrossref{\DUrole{std,std-ref}{Module signalflows overview}}}}) is largely for historical reasons.
In the future, the component library/libraries will be restructured into topical units.
\end{sphinxadmonition}


\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.Add}}}
\label{\detokenize{rcl_component_documentation:component-rcl-add}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.BiquadIirFilter}}}
\label{\detokenize{rcl_component_documentation:component-rcl-biquadiirfilter}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.CAPGainCalculator}}}
\label{\detokenize{rcl_component_documentation:component-rcl-capgaincalculator}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.ChannelObjectRoutingCalculator}}}
\label{\detokenize{rcl_component_documentation:component-rcl-channelobjectroutingcalculator}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.CrossfadingFirFilterMatrix}}}
\label{\detokenize{rcl_component_documentation:component-rcl-crossfadingfirfiltermatrix}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.DelayMatrix}}}
\label{\detokenize{rcl_component_documentation:component-rcl-delaymatrix}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.DelayVector}}}
\label{\detokenize{rcl_component_documentation:component-rcl-delayvector}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.DiffusionGainCalculator}}}
\label{\detokenize{rcl_component_documentation:component-rcl-diffusiongaincalculator}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.FirFilterMatrix}}}
\label{\detokenize{rcl_component_documentation:component-rcl-firfiltermatrix}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.GainMatrix}}}
\label{\detokenize{rcl_component_documentation:component-rcl-gainmatrix}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.GainVector}}}
\label{\detokenize{rcl_component_documentation:component-rcl-gainvector}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.HoaAllradGainCalculator}}}
\label{\detokenize{rcl_component_documentation:component-rcl-hoaallradgaincalculator}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.InterpolatingFirFilterMatrix}}}
\label{\detokenize{rcl_component_documentation:component-rcl-interpolatingfirfiltermatrix}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.ListenerCompensation}}}
\label{\detokenize{rcl_component_documentation:component-rcl-listenercompensation}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.Nullsource}}}
\label{\detokenize{rcl_component_documentation:component-rcl-nullsource}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.ObjectGainEqCalculator}}}
\label{\detokenize{rcl_component_documentation:component-rcl-objectgaineqcalculator}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.PanningCalculator}}}
\label{\detokenize{rcl_component_documentation:component-rcl-panningcalculator}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.PositionDecoder}}}
\label{\detokenize{rcl_component_documentation:component-rcl-positiondecoder}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.ScalarOscDecoder}}}
\label{\detokenize{rcl_component_documentation:component-rcl-scalaroscdecoder}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.SceneDecoder}}}
\label{\detokenize{rcl_component_documentation:component-rcl-scenedecoder}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.SceneEncoder}}}
\label{\detokenize{rcl_component_documentation:component-rcl-sceneencoder}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.SignalRouting}}}
\label{\detokenize{rcl_component_documentation:component-rcl-signalrouting}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.SparseGainMatrix}}}
\label{\detokenize{rcl_component_documentation:component-rcl-sparsegainmatrix}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.TimeFrequencyTransform}}}
\label{\detokenize{rcl_component_documentation:component-rcl-timefrequencytransform}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.TimeFrequencyInverseTransform}}}
\label{\detokenize{rcl_component_documentation:component-rcl-timefrequencyinversetransform}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.UdpReceiver}}}
\label{\detokenize{rcl_component_documentation:component-rcl-udpreceiver}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{rcl.UdpSender}}}
\label{\detokenize{rcl_component_documentation:component-rcl-udpsender}}

\section{Module \sphinxstyleliteralintitle{\sphinxupquote{signalflows}} overview}
\label{\detokenize{rcl_component_documentation:module-signalflows-overview}}\label{\detokenize{rcl_component_documentation:visr-component-library-reference-composite}}
The \sphinxcode{\sphinxupquote{signalflows}} contains composite components that are part of the standard distribution of the VISR.


\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{signalflows.CoreRenderer}}}
\label{\detokenize{rcl_component_documentation:component-signalflows-corerenderer}}

\subsection{Component \sphinxstyleliteralintitle{\sphinxupquote{signalflows.BaselineRenderer}}}
\label{\detokenize{rcl_component_documentation:component-signalflows-baselinerenderer}}

\chapter{The Binaural Synthesis Toolkit}
\label{\detokenize{binaural-synthesis-toolkit:the-binaural-synthesis-toolkit}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst}}\label{\detokenize{binaural-synthesis-toolkit::doc}}
The binaural synthesis toolkit (VISR\_BST) is an extensible set of components for realtime and offline binaural synthesis.

This section consists of two parts.
First, Section {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-tutorial}]{\sphinxcrossref{\DUrole{std,std-ref}{Tutorial}}}} introduces the BST in a tutorial-style form.
After that, Section {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-component-reference}]{\sphinxcrossref{\DUrole{std,std-ref}{Component reference}}}} describes all components and helper classes and functions in detail.


\section{Tutorial}
\label{\detokenize{binaural-synthesis-toolkit:tutorial}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-tutorial}}
\begin{sphinxadmonition}{note}{Note:}
This tutorial is based on the AES e-Brief:

Franck, A., Costantini, G., Pike, C., and Fazi, F. M., “An Open Realtime Binaural Synthesis Toolkit for Audio Research,” in Proc. Audio Eng. Soc. 144th Conv., Milano, Italy, 2018, Engineering Brief.”
\end{sphinxadmonition}

Binaural synthesis has gained fundamental importance both as a practical sound reproduction method and as a tool in audio research. Binaural rendering requires significant implementation effort, especially if head movement tracking or dynamic sound scenes are required, thus impeding audio research. For this reason we propose the Binaural Synthesis Toolkit (BST), a portable, open source, and extensible software package for binaural synthesis. In this paper we present the design of the BST and the three rendering approaches currently implemented. In contrast to most other software, the BST can easily be adapted and extended by users. The Binaural Synthesis Toolkit is released as an open software package as a flexible solution for binaural reproduction and to foster reproducible research in this field.


\subsection{Introduction}
\label{\detokenize{binaural-synthesis-toolkit:introduction}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-introduction}}
Binaural synthesis aims at recreating spatial audio by recreating binaural signals at the listener’s ears \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id1}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-nicol2010-binaural-technology}]{\sphinxcrossref{{[}B1{]}}}}, using either headphones or loudspeakers.
While binaural technology is an area of active research for a long time, the shift of music consumption towards mobile listening, object-based content, as well as the increasing importance of augmented and virtual reality (AR/VR) applications emphasize the increasing significance of binaural reproduction.
In addition, binaural techniques are an important tool in many areas of audio research and development, from basic perceptual experiments to auralization of acoustic environments or the evaluation of spatial sound reproduction \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id2}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-lindau-weinzierl2012-assessing-the-plausibility-of-virtual-acoustic-environments}]{\sphinxcrossref{{[}B2{]}}}}.

Regardless of the application, synthesizing binaural content invariably comprises a number of software building blocks, e.g., HRTF/BRIR selection and/or interpolation, signal filtering, modeling and applying interaural time and level differences, etc. \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id3}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-jot-larcher-warusfel-1995-digital-signal-processing-issues-in-the-context-of-binaural-and-transaural-stereophony}]{\sphinxcrossref{{[}B3{]}}}}.
Dynamic binaural synthesis significantly increases the plausibility of reproduction by including dynamic cues as head movements \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id4}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-algazi-duda2011-headphone-based-spatial-sound}]{\sphinxcrossref{{[}B4{]}}}}, but requires both a real-time implementation and additional DSP functionality as time-variant delays, dynamic filter updates, and filter crossfading techniques.
This implies a considerable implementation effort for research based on binaural synthesis, increases the likelihood of errors due to implementation effects, and makes it difficult to reproduce or evaluate the research of others.
This argument is in line with the increasing importance of software in (audio) research, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id5}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-cannam-figueira-plumbley2012-sound-software-towards-software-research-in-audio-and-music-research}]{\sphinxcrossref{{[}B5{]}}}}, and the generally growing awareness of reproducible research, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id6}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-wilson-et-al2014-best-practices-for-scientific-computing}]{\sphinxcrossref{{[}B6{]}}}}.

For this reason we introduce the Binaural Synthesis Toolkit (BST) as an open source, portable, and extensible software library for real-time and offline binaural synthesis.
Our intention is to provide baseline implementations for main binaural rendering schemes as well as DSP building blocks that enable the modification of existing renderers as well as the implementation of new rendering approaches.

The objective of its paper is to describe the architecture of the BST to enable its use as well as its adaptation by the audio community.
In essence, the BST is a set of processing components implemented within the VISR — an open  software rendering framework for audio rendering \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id7}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-franck-et-al2018-an-open-software-rendering-framework-for-audio-reproduction-and-reproducible-research}]{\sphinxcrossref{{[}B7{]}}}} — and preconfigured renderers built upon these components.
At the moment, three renderers are provided, namely HRIR-based dynamic synthesis, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id8}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-algazi-duda2011-headphone-based-spatial-sound}]{\sphinxcrossref{{[}B4{]}}}}, virtual loudspeaker synthesis (also termed room scanning \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id9}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-mackensen-et-al1999-binaural-room-scanning-a-new-tool-for-acoustic-and-psychoacoustic-research}]{\sphinxcrossref{{[}B8{]}}}}), and binaural rendering based on higher order Ambisonics (HOA), e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id10}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-daniel-rault-polack1998-ambisonics-encoding-of-other-audio-format-for-multiple-listening-conditions}]{\sphinxcrossref{{[}B9{]}}}}.
BRIR/HRIR data can be provided in the AES69-2015 format (SOFA) \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id11}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-aes2015-aes69-sofa-standard}]{\sphinxcrossref{{[}B10{]}}}} (\sphinxurl{http://www.sofaconventions.org}), allowing for arbitrary HRIR/BRIR measurement grids, and enabling the use of a wide range of impulse response datasets.

Compared to existing software projects supporting binaural synthesis, for instance Spat \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id12}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-daniel-rault-polack1998-ambisonics-encoding-of-other-audio-format-for-multiple-listening-conditions}]{\sphinxcrossref{{[}B9{]}}}} or the SoundScape Renderer (SSR) \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id13}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-geier-spors2012-spatial-audio-with-the-soundscape-renderer}]{\sphinxcrossref{{[}B11{]}}}}, the BST offers several new possibilities.
On the one hand, its modular structure is designed for easy adaptation and extension rather than providing a fixed functionality.
To a large extent, this is achieved by the Python language interface of the underlying VISR, and the fact that most high-level BST components are implemented in Python.
On the other hand, while most other software projects are mainly for real-time use, BST components can be used both in real-time and in fully parametrizable offline simulations using the same code base.
This makes the BST an effective tool for algorithm development.
Again, these capabilities are enabled mainly by the Python language integration of the BST and the underlying VISR.

This paper is structured as follows.
The underlying VISR framework and how its features influence the design and the uses of the BST is briefly outlined in Sec. {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-introduction}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction}}}}.
Section {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-preconfigured-renderers}]{\sphinxcrossref{\DUrole{std,std-ref}{Preconfigured Binaural Renderers}}}} discusses the three rendering approaches currently implemented in the BST, their use, configuration, and optional features.
The main building blocks of these renderers, which can also be used to adapt the BST or to implement different synthesis methods, are outlined in section Sec. {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-rendering-building-blocks}]{\sphinxcrossref{\DUrole{std,std-ref}{Rendering Building Blocks}}}}.
Section {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-application-examples}]{\sphinxcrossref{\DUrole{std,std-ref}{Application Examples}}}} shows practical examples of using the BST, while
Sec. {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-conclusion}]{\sphinxcrossref{\DUrole{std,std-ref}{Conclusion}}}} summarizes the paper.


\subsection{The VISR Framework}
\label{\detokenize{binaural-synthesis-toolkit:the-visr-framework}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-visr-framework}}
The binaural synthesis toolkit is based on the VISR (Versatile Interactive Scene Renderer) framework, an open-source, portable, and extensible software for audio processing \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id14}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-franck-et-al2018-an-open-software-rendering-framework-for-audio-reproduction-and-reproducible-research}]{\sphinxcrossref{{[}B7{]}}}}.
It is being developed as part of the S3A project (\sphinxurl{http://www.s3a-spatialaudio.org}) \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id15}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-coleman-et-al2018-an-audio-visual-system-for-object-based-audio}]{\sphinxcrossref{{[}B12{]}}}}.
At the moment, it is supported on Linux (Intel and Raspberry Pi), Mac OS X, and Windows.
VISR is a general-purpose audio processing software with emphasis on, but not limited to, multichannel and object-based audio.
This section outlines the main features of the VISR framework and the implications on design and usage of the BST.


\subsubsection{Component-Based Design}
\label{\detokenize{binaural-synthesis-toolkit:component-based-design}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{visr_component_schematic}.png}
\caption{General interface of a VISR component.}\label{\detokenize{binaural-synthesis-toolkit:id43}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-component-schematic}}\end{figure}

VISR is a software framework, which means that it enables a systematic reuse of functionalities and is designed for extension by users.
To this, all processing tasks are implemented within \sphinxstyleemphasis{components}, software entities that communicate with other components and the external environment through a defined, common interface.
Fig. {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-component-schematic}]{\sphinxcrossref{\DUrole{std,std-ref}{General interface of a VISR component.}}}} depicts the general structure of a component.


\subsubsection{Ports}
\label{\detokenize{binaural-synthesis-toolkit:ports}}
Data inputs and outputs to components are represented by \sphinxstyleemphasis{ports}.
They enable configurable, directional flow of information between components or with the outside environment.
There are two distinct types of ports: audio and parameter ports.
Audio ports accept or create multichannel audio signals with an arbitrary, configurable number of single/mono audio signal waveforms, which is referred as the \sphinxstyleemphasis{width} of the port.
Audio ports are configured with unique name, a width and a sample type such as \sphinxcode{\sphinxupquote{float}} or \sphinxcode{\sphinxupquote{int16}}.

Parameter ports, on the other hand, convey control and parameter information between components or from and to the external environment.
Parameter data is significantly more diverse than audio data.
For example, parameter data used in the BST includes vectors of gain or delay values, FIR or IIR filter coefficients, audio object metadata, and structures to represent the listener’s orientation.
In addition to the data type, there are also different communication semantics for parameters.
For example, data can change in each iteration of the audio processing, be updated only sporadically, or communicated through messages queues.
In VISR, these semantics are termed \sphinxstyleemphasis{communication protocols} and form an additional property of a parameter port.
The semantics described above are implemented by the communication protocols \sphinxcode{\sphinxupquote{SharedData}}, \sphinxcode{\sphinxupquote{DoubleBuffering}}, and \sphinxcode{\sphinxupquote{MessageQueue}}, respectively.
Several parameter types feature additional configuration data, such as the dimension of a matrix parameter.
In the VISR framework, such options are passed in \sphinxcode{\sphinxupquote{ParameterConfig}} objects.
This allows extensive type checking, for instance to ensure that only matrix parameter of matching dimensions are connected.
Combining these features, a parameter port is described by these properties: a unique name, a parameter type, a communication protocol type and an optional parameter configuration object.


\subsubsection{Hierarchical Signal Flows}
\label{\detokenize{binaural-synthesis-toolkit:hierarchical-signal-flows}}
To create and reuse more complex functionality out of existing building blocks, VISR signal flows can be structured hierarchically.
To this end, there are two different kinds of components in VISR, \sphinxstyleemphasis{atomic} and \sphinxstyleemphasis{composite}.
They have the same external interface, that means that they can be used in the same way.
Figures {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-atomic-component}]{\sphinxcrossref{\DUrole{std,std-ref}{Atomic VISR component.}}}} and {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-composite-component}]{\sphinxcrossref{\DUrole{std,std-ref}{Composite VISR component.}}}} schematically depict these two types.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{visr_atomic_component}.png}
\caption{Atomic VISR component.}\label{\detokenize{binaural-synthesis-toolkit:id44}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-atomic-component}}\end{figure}

\sphinxstyleemphasis{Atomic components} implement processing task in program code, e.g., in C++ or Python.
They feature a constructor which may take a variety of configuration options to tailor the behaviour of the component and to initialize its state.
The operation of an atomic component is implemented in the \sphinxcode{\sphinxupquote{process}} method.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{visr_composite_component}.png}
\caption{Composite VISR component.}\label{\detokenize{binaural-synthesis-toolkit:id45}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-composite-component}}\end{figure}

In contrast, a \sphinxstyleemphasis{composite component} contains a set of interconnected components (atomic or composite) to define its behaviour.
This allows the specification of more complex signal flows in terms of existing functionality, but also the reuse of such complex signal flows.
As their atomic counterparts, they may take a rich set of constructor options.
These can control which contained components are constructed, how they are configured, and how they are connected.
It is worth noting that nested components do not impair computational efficiency because the hierarchy is flattened at initialisation time and therefore not visible to the runtime engine.

This hierarchical structure has far-reaching consequences for the design and the use of the BST.
Firstly, it allows for an easy use of existing VISR components in BST components.
Secondly, BST renderers can easily be augmented by additional functionality, such as receiving and decoding of object metadata or headtracking information, by wrapping it into a new composite component.
Thirdly, BST functionality can be conveniently integrated into larger audio applications implemented in the VISR, for instance the transaural loudspeaker array rendering described in Sec. {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-subsec-tutorial-application-examples-transaural-loudspeaker-array}]{\sphinxcrossref{\DUrole{std,std-ref}{Transaural Loudspeaker Array}}}}.


\subsubsection{Standard Component Library}
\label{\detokenize{binaural-synthesis-toolkit:standard-component-library}}
The runtime component library (\sphinxcode{\sphinxupquote{rcl}}) of the VISR framework contains a number of components for general-purpose DSP and object-based audio operations.
They are typically implemented in C++ and therefore relatively efficient.
The rcl library includes arithmetic operations on multichannel signals, gain vectors and matrices, delay lines, FIR and IIR filtering blocks, but also network senders and receivers and
components for decoding and handling of object audio metadata.


\subsubsection{Runtime Engine}
\label{\detokenize{binaural-synthesis-toolkit:runtime-engine}}
A key objective of the VISR framework is to enable users to focus on their processing task \textendash{} performed in
a component \textendash{} while automating tedious tasks, such as error checking, communication between components,
or interfacing audio hardware, as far as possible.
The rendering runtime library (rrl) serves this purpose. Starting from a top-level component,
it is only necessary to construct an object of type \sphinxcode{\sphinxupquote{AudioSignalFlow}} for this component. All operations
from consistency checking to the initialization of memory buffers and data structures for rendering is
performed by this object. The audiointerfaces library provides abstractions for different audio interface
APIs (such as Jack, PortAudio, or ASIO). Realtime rendering is started by connecting the SignalFlow
object to an audiointerfaces object.


\subsubsection{Python interface}
\label{\detokenize{binaural-synthesis-toolkit:python-interface}}
While the core of the VISR framework is implemented in C++, it provides a full application programming interface (API) for the Python programming language.
This is to enable users to adapt or extend signal flows more productively, using an interpreted language with a more accessible, readable syntax and enabling the use of rich libraries for numeric computing and DSP, such as NumPy and SciPy \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id16}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-oliphant2007-python-for-scientific-computing}]{\sphinxcrossref{{[}B13{]}}}}.
The Python API can be used in three principal ways:
\begin{description}
\item[{\sphinxstylestrong{Configuring and running signal flows}}] \leavevmode
Components can be created and configured from the interactive Python interpreters or script files.
This makes this task fully programmable and removes the need for external scripts to configure renders.
In the same way, audio interfaces can be configured, instantiated and started from within Python, enabling
realtime rendering from within an interactive interpreter.

\item[{\sphinxstylestrong{Extending and creating signal flow}}] \leavevmode
As described above, complex signal flows are typically created as composite components.
This can be done in Python by deriving a class from the base class \sphinxcode{\sphinxupquote{visr.CompositeComponent}}.
The behavior of the signal flow is defined in the class’ constructor by creating external ports, contained components,
and their interconnections.
Instances of this class can be used for realtime rendering from the Python interpreter, as described above,
or from a standalone application.
Most of the BST renderer signal flows are implemented in this way, ensuring readability and easy extension by users.

\item[{\sphinxstylestrong{Adding atomic functionality}}] \leavevmode
In the same way as composites, atomic components can be implemented by deriving from \sphinxcode{\sphinxupquote{visr.AtomicComponent}}.
This involves implementing the constructor set up the component and the \sphinxcode{\sphinxupquote{process()}} method that performs
the run-time processing.
The resulting objects can be embedded in either Python or C++ composite components (via a helper class \sphinxcode{\sphinxupquote{PythonWrapper}}).
In the BST toolkit, the controller components that define the logic of the specific binaural rendering approaches are implemented as atomic components in Python.
This language choice allows for rapid prototyping, comprehensible code, and easy adaptation.

\end{description}


\subsubsection{Offline Rendering}
\label{\detokenize{binaural-synthesis-toolkit:offline-rendering}}
By virtue of the Python integration, signal flows implemented as components are not limited to realtime rendering, but can also be executed in an offline programming environment.
Because the top-level audio and parameter ports of a component can be accessed externally, dynamic rendering features such as moving objects or head movements can be simulated in a deterministic way.
In the majority of uses, this is most conveniently performed in an interactive Python environment.
Applications of this feature range from regression tests of atomic components or complex composite signal flows, performance simulations, to offline rendering of complete sound scenes.
A full characterization of the offline rendering support is beyond the scope of this paper, interested readers are referred to \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id17}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-franck-et-al2018-an-open-software-rendering-framework-for-audio-reproduction-and-reproducible-research}]{\sphinxcrossref{{[}B7{]}}}}.


\subsubsection{Use in multiple software environments}
\label{\detokenize{binaural-synthesis-toolkit:use-in-multiple-software-environments}}
In addition to realtime rendering and offline Python scripting, VISR components can also be embedded into audio software environments such as digital audio  workstations (DAWs) plugins, or Max/MSP or Pd externals.
This means that parts of the BST can be used from these applications, creating new tools and integrating into the workflow of more researchers and creatives.
Support libraries are provided to ease this task by reducing the amount of code required for this embedding.
Again, a full discussion of this paper is beyond the scope of this paper, see \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id18}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-franck-et-al2018-an-open-software-rendering-framework-for-audio-reproduction-and-reproducible-research}]{\sphinxcrossref{{[}B7{]}}}} for a discussion.


\subsection{Preconfigured Binaural Renderers}
\label{\detokenize{binaural-synthesis-toolkit:preconfigured-binaural-renderers}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-preconfigured-renderers}}
The VISR Binaural Synthesis Toolkit contains prepackaged, configurable renderers (or signal flows) for three major binaural synthesis strategies. They are implemented as composite VISR components in Python. On the one hand, this means that they can be readily used either as standalone binaural renderers or as part of larger audio processing schemes. On the other hand, the use of Python allows for easy modification and extension. This section describes the general structure and the configuration options of these three renderers.
Features common to all approaches, such as an option to include headphone transfer function (HPTF) compensation filters, are not described here.
Entities such as components, ports, or configuration options are set in a monospaced font, e.g., \sphinxcode{\sphinxupquote{input}}.


\subsubsection{Dynamic HRIR-Based Synthesis}
\label{\detokenize{binaural-synthesis-toolkit:dynamic-hrir-based-synthesis}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-subsec-tutorial-dynamic-hrir-based-synthesis}}
This approach renders sound objects, typically point sources or plane waves represented by position metadata and a mono signal, using spatial datasets of head-related impulse responses (HRIR) or, equivalently, head-related transfer functions (HRTFs), e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id19}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-jot-larcher-warusfel-1995-digital-signal-processing-issues-in-the-context-of-binaural-and-transaural-stereophony}]{\sphinxcrossref{{[}B3{]}}}}\phantomsection\label{\detokenize{binaural-synthesis-toolkit:id20}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-algazi-duda2011-headphone-based-spatial-sound}]{\sphinxcrossref{{[}B4{]}}}}.
This approach is widely used in audio research and for practical reproduction and is well-suited for object-based audio as well as AR/VR applications.
In its basic form, it synthesizes sound scenes under freefield conditions, and is therefore often augmented by a reverberation engine, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id21}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-jot-walsh-philp2006-binaural-simulation-of-complex-acoustic-scenes-for-interactive-audio}]{\sphinxcrossref{{[}B14{]}}}}.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{dynamic_hrir_synthesis}.png}
\caption{Dynamic binaural synthesis rendering component. Optional parts are dashed.}\label{\detokenize{binaural-synthesis-toolkit:id46}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-dynamic-hrir-synthesis}}\end{figure}

The signal flow of the BST dynamic HRIR renderer is shown in {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-dynamic-hrir-synthesis}]{\sphinxcrossref{\DUrole{std,std-ref}{Dynamic binaural synthesis rendering component. Optional parts are dashed.}}}}.
It is implemented as a composite VISR component named \sphinxcode{\sphinxupquote{DynamicHrirRenderer}}.
The logic of the synthesis is encapsulated in the atomic component \sphinxcode{\sphinxupquote{DynamicHrirController}}.
It receives object metadata and determines a pair of HRIR filters for each object, which are transmitted to the DSP components.
The controller is initialized with a spatial HRIR dataset and the corresponding grid locations of the IRs.
Audio object metadata, including positions and levels, are received through the parameter input port \sphinxcode{\sphinxupquote{objects}}.
If present, the listener’s head orientation is received through the optional input \sphinxcode{\sphinxupquote{tracking}} and incorporated in the HRIR calculation.
At the moment, two HRIR calculation methods are supported: nearest-neighbour selection and barycentric interpolation using a Delaunay triangulation, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id22}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-gamper2013-selection-and-interpolation-of-hrtf-for-rendering-moving-virtual-sources}]{\sphinxcrossref{{[}B15{]}}}}.
The generated IRs, one per sound object and ear, are transmitted through the output port \sphinxcode{\sphinxupquote{filters}} to the \sphinxcode{\sphinxupquote{DynamicConvolver}} component, which performs time-variant MIMO (multiple-input, multiple-output) FFT-based convolution of the object audio signals and combines them into binaural output.
Depending on the configuration, the \sphinxcode{\sphinxupquote{DynamicConvolver}} uses crossfading to reduce audible artifacts when changing filters.

The HRTF dataset, including the measurement position grid, can be provided in the AES69:2015 (SOFA) format \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id23}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-aes2015-aes69-sofa-standard}]{\sphinxcrossref{{[}B10{]}}}}.
Optionally the rendering component accepts preprocessed datasets where the HRIRs are time-aligned and the onset delays are kept apart (e.g., in the \sphinxcode{\sphinxupquote{Data.Delay}} field of the SOFA format).
Applying the delays separately can improve HRIR interpolation quality, reduces audible effects when updating filters, and can therefore enable the use of coarser HRIR datasets, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id24}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-jot-larcher-warusfel-1995-digital-signal-processing-issues-in-the-context-of-binaural-and-transaural-stereophony}]{\sphinxcrossref{{[}B3{]}}}}.
Because the pure delay part of the HRIRs dominates the ITD cue of the synthesized binaural signal, this also provides a means to use alternative ITD models instead of the measured IR delays, or to implement ITD  individualization \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id25}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-lindau-estrella-weinzierl2010-individualization-of-dynamic-binaural-synthesis-by-real-time-manipulation-of-the-itd}]{\sphinxcrossref{{[}B16{]}}}}.
In the same way, the filter gain may be calculated separately, for instance to simulate near-field source effects \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id26}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-jot-walsh-philp2006-binaural-simulation-of-complex-acoustic-scenes-for-interactive-audio}]{\sphinxcrossref{{[}B14{]}}}}.
In either of these cases, the dynamic delay and/or gain coefficients are calculated in the \sphinxcode{\sphinxupquote{DynamicHrirController}}, and the optional component \sphinxcode{\sphinxupquote{DelayGainMatrix}} is instantiated to apply these values prior to the convolution.
As described in Sec. {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-building-blocks-delays}]{\sphinxcrossref{\DUrole{std,std-ref}{Delay Lines: Vectors and Matrices}}}}, the delay/gain components support configurable fractional delay filtering and smooth parameter updates, thus ensuring audio quality and reducing audible artifacts in dynamic rendering scenarios.


\subsubsection{Higher Order Ambisonics-Based Synthesis}
\label{\detokenize{binaural-synthesis-toolkit:higher-order-ambisonics-based-synthesis}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-tutorial-hoa-based-synthesis}}
A second approach, termed HOA (Higher Order Ambisonics)-based synthesis, is based on a spherical harmonics (SH) representation of a spatial sound scene, i.e., higher-order B-format.
First-order B-format binaural synthesis has been proposed, e.g., in \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id27}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-mckeag-mcgrath1996-sound-field-format-to-binaural-decoder-with-head-tracking}]{\sphinxcrossref{{[}B17{]}}}}\phantomsection\label{\detokenize{binaural-synthesis-toolkit:id28}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-jot-wardle-larcher1998-approaches-to-binaural-synthesis}]{\sphinxcrossref{{[}B18{]}}}}, and extended to higher Ambisonic orders, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id29}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-bernschuetz-et-al2014-binaural-reproduction-of-plane-waves-with-reduced-modal-order}]{\sphinxcrossref{{[}B19{]}}}}.
This scene-based rendering approach forms, for example, the basis of the spatial audio synthesis in Facebook’s Audio360 Google’s Resonance Audio SDK \sphinxurl{https://github.com/resonance-audio/resonance-audio-web-sdk}.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{hoa_to_binaural_renderer}.png}
\caption{Binaural synthesis based on HOA.}\label{\detokenize{binaural-synthesis-toolkit:id47}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-hoa-to-binaural-renderer}}\end{figure}

The signal flow of the generic HOA synthesis renderer is depicted in Fig. {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-hoa-to-binaural-renderer}]{\sphinxcrossref{\DUrole{std,std-ref}{Binaural synthesis based on HOA.}}}}.
The component \sphinxcode{\sphinxupquote{HoaBinauralRenderer}} accepts a HOA input signal, i.e., higher-order B-format, of a selectable order \(L\), consisting of \((L+1)^2\) channels.
If head tracking is enabled, the component \sphinxcode{\sphinxupquote{RotationMatrixCalculator}} computes a rotation matrix for spherical harmonics using a recurrent formula \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id30}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-ivanic-ruedenberg1996-rotation-matrices-for-real-spherical-harmonics-direct-determination-by-recursion}]{\sphinxcrossref{{[}B20{]}}}}.
These coefficients are applied to the B-format signal in the gain matrix component \sphinxcode{\sphinxupquote{HoaSignalRotation}}, effectively rotating the sound field to compensate for the listener’s orientation.
The component of this signal are filtered with a bank of \((L+1)^2\) static FIR filters for each ear \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id31}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-bernschuetz-et-al2014-binaural-reproduction-of-plane-waves-with-reduced-modal-order}]{\sphinxcrossref{{[}B19{]}}}} in the \sphinxcode{\sphinxupquote{StaticConvolver}} component, which also performs an ear-wise summation of the filtered signals to yield the binaural output signal.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{hoa_object_to_binaural_renderer}.png}
\caption{HOA binaural synthesis of object-based scenes.}\label{\detokenize{binaural-synthesis-toolkit:id48}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-hoa-object-to-binaural-renderer}}\end{figure}

Figure {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-hoa-object-to-binaural-renderer}]{\sphinxcrossref{\DUrole{std,std-ref}{HOA binaural synthesis of object-based scenes.}}}} shows a variant of the HOA synthesis that operates on an object-based scene.
Component \sphinxcode{\sphinxupquote{ObjectToHoaCoefficients}} transforms the object metadata into a set of SH coefficients for each object. If head tracking is active, the component \sphinxcode{\sphinxupquote{HoaCoefficientRotation}} receives orientation data from the optional \sphinxcode{\sphinxupquote{tracking}} input and applies a rotation matrix  to the HOA coefficients. The \sphinxcode{\sphinxupquote{HoaSignalEncoder}} component uses these data to encode the object signals into a B-format signal. This representation is transformed to a binaural signal in the same way as in the generic HOA binaural renderer.
The advantage of this approach is that the rotation is performed on the SH coefficients, that is a much lower rate than the audio sampling frequency, and is consequently more efficient.


\subsubsection{Virtual Loudspeaker Rendering/ Binaural Room Scanning}
\label{\detokenize{binaural-synthesis-toolkit:virtual-loudspeaker-rendering-binaural-room-scanning}}
The third principal approach implemented in the BST, denoted as virtual loudspeaker rendering, uses binaural room impulse responses of a multi-loudspeaker setup in a given acoustic environment to recreate the listening experience in that room. For this reason it is also referred to as \sphinxstyleemphasis{binaural room scanning} \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id32}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-mackensen-et-al1999-binaural-room-scanning-a-new-tool-for-acoustic-and-psychoacoustic-research}]{\sphinxcrossref{{[}B8{]}}}}\phantomsection\label{\detokenize{binaural-synthesis-toolkit:id33}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-algazi-duda2011-headphone-based-spatial-sound}]{\sphinxcrossref{{[}B4{]}}}}.
Headtracking can be used to incorporate the listener’s orientation by switching or interpolating between BRIR data provided for a grid of orientations.
While the BST supports both 2D and 3D grids, exiting datasets, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id34}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-pike-melchior-tew2014-assessing-the-plausibility-of-non-individualised-dynamic-binaural-synthesis-in-a-small-room}]{\sphinxcrossref{{[}B21{]}}}}\phantomsection\label{\detokenize{binaural-synthesis-toolkit:id35}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-pike-romanov2017-an-impulse-response-dataset-for-dynamic-data-based-auralization-of-advanced-sound-systems}]{\sphinxcrossref{{[}B22{]}}}} are typically restricted to orientations in the horizontal plane because of the measurement effort and data size.
In contrast to the aforementioned methods, this approach does not operate on audio objects but on loudspeaker signals.
It is therefore used to reproduce channel-based content or to transform the output of loudspeaker-based rendering methods to binaural, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id36}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-laitinen-pulkki2009-binaural-rendering-for-directional-audio-coding}]{\sphinxcrossref{{[}B23{]}}}}.

\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{virtual_loudspeaker_renderer}.png}
\caption{Virtual loudspeaker renderer.}\label{\detokenize{binaural-synthesis-toolkit:id49}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-virtual-loudspeaker-renderer}}\end{figure}

The signal flow of the \sphinxcode{\sphinxupquote{Virtual-Loudspeaker-Renderer}} is displayed Fig. {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-virtual-loudspeaker-renderer}]{\sphinxcrossref{\DUrole{std,std-ref}{Virtual loudspeaker renderer.}}}}.
As in the dynamic HRIR renderer ({\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-subsec-tutorial-dynamic-hrir-based-synthesis}]{\sphinxcrossref{\DUrole{std,std-ref}{Dynamic HRIR-Based Synthesis}}}}), the logic is implemented in a controller component, \sphinxcode{\sphinxupquote{VirtualLoudspeakerController}}.
It loads the BRIR dataset from a SOFA file and uses the optional parameter input port \sphinxcode{\sphinxupquote{tracking}} to select and potentially interpolate the room impulse responses according to the head rotation.
The resulting BRIRs are sent to the \sphinxcode{\sphinxupquote{DynamicBrirConvolution}} component, where the \(L\) loudspeaker signals are convolved, optionally crossfaded, and summed to form the binaural output.

If the onset delays are extracted from the BRIRs, they are dynamically computed in the controller and applied in the optional \sphinxcode{\sphinxupquote{DynamicDelayMatrix}} component.
As in case dynamic HRIR synthesis, this can help to improve filter interpolation, reduce switching artifacts, and allow for coarser BRIR datasets.
To reduce memory requirements and the computational load due to filter interpolation and switching, the late part of the BRIRs can optionally be rendered statically, i.e., independent of the head rotation, as described in \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id37}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-pike-melchior-tew2014-assessing-the-plausibility-of-non-individualised-dynamic-binaural-synthesis-in-a-small-room}]{\sphinxcrossref{{[}B21{]}}}}.
In this case, the loudspeaker signals are processed through an additional branch consisting of a fixed delay matrix \sphinxcode{\sphinxupquote{LateDelayMatrix}}, which applies the time offset (mixing time) of the late reverberation tail, and the static convolver \sphinxcode{\sphinxupquote{LateConvolutionEngine}}.
The result is combined with the dynamically convolved early part to form the binaural output signal.


\subsection{Rendering Building Blocks}
\label{\detokenize{binaural-synthesis-toolkit:rendering-building-blocks}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-rendering-building-blocks}}
After describing the ready-made binaural synthesis approaches provided in the BST, this section explains the main DSP building blocks used to implement these algorithms in more detail.
On the one hand, this is to provide more insight into the workings of these renderers.
On the other hand, these components can also be used to adapt or extend the BST, or to implement alternative synthesis approaches.

As outlined in Sec. {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-visr-framework}]{\sphinxcrossref{\DUrole{std,std-ref}{The VISR Framework}}}}, most of the present generic DSP functionality is implemented as C++ components in the VISR \sphinxcode{\sphinxupquote{rcl}} library.
Python language interfaces are provided to enable their use in Python components.
They are typically application-independent and therefore highly configurable.
For instance, the widths (i.e., the number of individual signals) of input and output ports can be changed.
Other parameters, such as gains, delay values, or filters, can be either set statically or updated during runtime.
To this end, parameter ports to update these values can be activated in the component’s initialization, typically using an argument \sphinxcode{\sphinxupquote{controlInputs}} with a component-specific enumeration type.
In a \sphinxcode{\sphinxupquote{DelayVector}} object, for example, the setting \sphinxcode{\sphinxupquote{controlInputs = rcl.DelayVector.PortConfigConfig.Delay}} activates the parameter input port to set delay values at runtime.


\subsubsection{Convolution Kernels}
\label{\detokenize{binaural-synthesis-toolkit:convolution-kernels}}
Convolution with FIR filters representing HRIR or BRIR data is an essential operation in binaural synthesis.
The VISR framework provides different components for multiple-input, multiple-output FIR filtering using fast convolution techniques.

The most basic, \sphinxcode{\sphinxupquote{rcl.FirFilterMatrix}}, enables arbitrary sets of filtering operations between individual signals of its variable-width input and output ports.
To this end, so-called \sphinxstyleemphasis{routings} — lists of elements formed by an input index, an output index and a filter id — can be provided either during initialisation or at runtime.
In this way, widely different filtering operations can be performed by the same component.
Examples are multichannel channel-wise filtering, dense MIMO filter matrix, or application-specific topologies such as filtering a set of object signals to a left and right HRIR each, and summing the results ear-wise.
FFT and inverse FFT transforms are reused for multiple filtering operations where possible, improving efficiency compared to simple channel-wise convolution.
Depending on the configuration, both the routing points and the FIR filters can be exchanged at runtime, and the changes are performed instantaneously.

To avoid artifacts due to such filter switching operations, the component \sphinxcode{\sphinxupquote{rcl.CrossFadingFirFilterMatrix}} extends this filter matrix by a crossfading implementation to enable smooth transitions.
To this end, an additional configuration parameter \sphinxcode{\sphinxupquote{interpolationSteps}} is added to specify the duration of the transition to a new filter.
At the moment, this operation is performed in the time domain, thus incurring significant increase in computational complexity.
This can be partly alleviated by frequency-domain filter exchange strategies, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id38}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-franck2014-efficient-frequency-domain-crossfading-for-fast-convolution-with-application-to-binaural-synthesis}]{\sphinxcrossref{{[}B24{]}}}}, which can be implemented
without changing the component’s interface.


\subsubsection{Gain Vectors and Matrices}
\label{\detokenize{binaural-synthesis-toolkit:gain-vectors-and-matrices}}
Gains are used, for example, to apply audio object levels or distance attenuation, or to perform matrix operations as rotations on HOA signals.
The VISR \sphinxcode{\sphinxupquote{rcl}} library provides three component types for vector and matrix delays.
\sphinxcode{\sphinxupquote{rcl.GainVector}} applies individual gains to an arbitrary-width audio signal.
\sphinxcode{\sphinxupquote{rcl.GainMatrix}} performs a matrixing operation between an audio input and an audio output signal of arbitrary, possibly different widths using a dense matrix of gain coefficients.
If a significant part of the gains are zero, \sphinxcode{\sphinxupquote{rcl.GainMatrixSparse}} performs this matrixing more efficiently.
To this end, \sphinxcode{\sphinxupquote{rcl.GainMatrixSparse}} is configured with a set of \sphinxstyleemphasis{routings}, similar to those used with the convolution components, to describe the location of the nonzero gains.

All gain components can be configured with initial gains values to allow static operation with fixed coefficients.
Optionally, a parameter input \sphinxcode{\sphinxupquote{gain}} can be activated to receive run-time updates.
In this case, the gains are smoothly and linearly changed to their new value within a transition period defined by the optional parameter \sphinxcode{\sphinxupquote{interpolationSteps}} (in samples).
This ensures click-free operation.


\subsubsection{Delay Lines: Vectors and Matrices}
\label{\detokenize{binaural-synthesis-toolkit:delay-lines-vectors-and-matrices}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-building-blocks-delays}}
Time delays are ubiquitous in binaural synthesis, with uses ranging from modeling of propagation delays, simulation of Doppler effects, the separate application of HRIR/BRIR onset delays, or the incorporation of analytic ITD models.
The VISR provides two components, \sphinxcode{\sphinxupquote{rcl.DelayVector}} and \sphinxcode{\sphinxupquote{rcl.DelayMatrix}} for applying channel-wise and matrix time delays to arbitrary-width signals.
For time-variant delay operation, an optional parameter input \sphinxcode{\sphinxupquote{delay}} is instantiated to receive runtime updates.
For artifact-free operation, the time delays are transitioned smoothly to the new values, based on a \sphinxcode{\sphinxupquote{interpolationsteps}} configuration parameter as described above.
In addition, fractional delay (FD) filtering is essential for maintaining audio quality in time-variant delay lines.
To this end, a FD algorithm can be selected using the \sphinxcode{\sphinxupquote{interpolationType}} parameter.
Currently the delay components support nearest-neighbor interpolation and Lagrange interpolation of arbitrary order based on an efficient linear-complexity implementation \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id39}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-franck2008-efficient-algorithms-and-structures-for-fractional-delay-filtering-based-on-lagrange-interpolation}]{\sphinxcrossref{{[}B25{]}}}}.
Since signal delays are often applied in combination with a scaling, i.e., gain, and because these operations can be combined efficiently, the VISR delay components support an optional \sphinxcode{\sphinxupquote{gain}} parameter input port that can be activated if required.


\subsubsection{Head Tracking Data Receivers}
\label{\detokenize{binaural-synthesis-toolkit:head-tracking-data-receivers}}
For real-time dynamic rendering, data from head tracking devices must be supplied to the \sphinxcode{\sphinxupquote{tracking}} input port.
To this end we provide an extensible library of tracking data receivers.
These are implemented in Python for conciseness and to make adaptation to other devices easier.
Tracking receiver components transform the device-specific tracking information into the parameter type \sphinxcode{\sphinxupquote{pml.ListenerPosition}} that represents a listener position (not used in the current binaural renderers) and orientation within the VISR framework.
Currently, the following devices are supported: The following devices are supported at the moment.
Razor AHRS headtracker (\sphinxurl{https://github.com/Razor-AHRS/razor-9dof-ahrs}), MrHeadTracker (\sphinxurl{https://git.iem.at/DIY/MrHeadTracker/}), HTC VIVE Tracker (\sphinxurl{https://www.vive.com/us/vive-tracker/}), and Intel RealSense (\sphinxurl{https://www.intel.com/content/www/us/en/architecture-and-technology/realsense-overview.html}).
The separation of the tracking data receivers and the example implementations in Python will ease the creation of components for additional tracking devices.


\subsection{Application Examples}
\label{\detokenize{binaural-synthesis-toolkit:application-examples}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-application-examples}}
In this section we provide a number of usage examples for the Binaural Synthesis Toolkit.


\subsubsection{Offline algorithm evaluation}
\label{\detokenize{binaural-synthesis-toolkit:offline-algorithm-evaluation}}
Algorithm development often requires deterministic, repeatable simulation runs and the generation of objective results such as waveforms, plots, or error metrics.
The VISR Python integration provides an environment for simulating dynamic scenarios using the same binaural synthesis algorithms as in the real-time case in an offline, scripted fashion.
To this end, one of the BST renderers (or an adapted version) is configured and instantiated in a Python script.
Within this script, the renderer is executed in a block-by block fashion, providing audio object signals, object metadata and (optionally) listener orientation updates.
The resulting binaural output signal can be displayed, saved as an audio file, or analyzed using the rich scientific computing libraries of Python.
Thus it is easy to switch between conventional audio research and realtime rendering using the same code base.


\subsubsection{Realtime HRIR synthesis of object-based scenes}
\label{\detokenize{binaural-synthesis-toolkit:realtime-hrir-synthesis-of-object-based-scenes}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{object_based_scene_renderer}.png}
\caption{Application: Object scene rendering.}\label{\detokenize{binaural-synthesis-toolkit:id50}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-object-based-scene-renderer}}\end{figure}

In this use case, a complex object-based scene, e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id40}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-woodcock-et-al2016-presenting-the-s3a-object-based-audio-drama-dataset}]{\sphinxcrossref{{[}B26{]}}}} is reproduced binaurally.
The dynamic scene is stored in the Audio Definition Model (ADM) \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id41}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-itu2017-itu-r-2076-1-adm}]{\sphinxcrossref{{[}B27{]}}}} format and played through a specialized software player, generating a multichannel audio signal containing the object waveforms, and the object metadata as a UDP network stream.
A new composite component \sphinxcode{\sphinxupquote{ObjectSceneRenderer}}, depicted in Fig. {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-object-based-scene-renderer}]{\sphinxcrossref{\DUrole{std,std-ref}{Application: Object scene rendering.}}}}, is created to reproduce such content.
It contains a \sphinxcode{\sphinxupquote{UdpReceiver}} and a \sphinxcode{\sphinxupquote{SceneDecoder}} component, both part of the VISR \sphinxcode{\sphinxupquote{rcl}} library, to receive object metadata and to decode it into the internal representation.
This and the multichannel object audio is passed to the \sphinxcode{\sphinxupquote{DynamicHrirRenderer}}.
Optionally, information from a head tracking device is decoded in the \sphinxcode{\sphinxupquote{HeadtrackingReceiver}} component and passed to the \sphinxcode{\sphinxupquote{tracking}} input of the renderer.


\subsubsection{Transaural Loudspeaker Array}
\label{\detokenize{binaural-synthesis-toolkit:transaural-loudspeaker-array}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-subsec-tutorial-application-examples-transaural-loudspeaker-array}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{transaural_array_renderer}.png}
\caption{Application: Transaural array rendering}\label{\detokenize{binaural-synthesis-toolkit:id51}}\label{\detokenize{binaural-synthesis-toolkit:figure-visr-bst-transaural-array-renderer}}\end{figure}

A variant of the object scene rendering for transaural array reproduction e.g., \phantomsection\label{\detokenize{binaural-synthesis-toolkit:id42}}{\hyperref[\detokenize{binaural-synthesis-toolkit:bst-simon-galvez-fazi2015-loudspeaker-arrays-for-transaural-reproduction}]{\sphinxcrossref{{[}B28{]}}}} is depicted in Fig. {\hyperref[\detokenize{binaural-synthesis-toolkit:figure-visr-bst-transaural-array-renderer}]{\sphinxcrossref{\DUrole{std,std-ref}{Application: Transaural array rendering}}}}.
It features a new top-level composite component \sphinxcode{\sphinxupquote{TransauralArrayRendering}}, which connects a \sphinxcode{\sphinxupquote{ObjectSceneRenderer}} to the transaural-specific crosstalk cancellation algorithm, which is implemented using the VISR framework.
The output of the latter is sent to a multichannel loudspeaker array.

These examples show how the BST can be used in practical reproduction scenarios, and how it can be embedded in more complex audio algorithms.


\subsection{Conclusion}
\label{\detokenize{binaural-synthesis-toolkit:conclusion}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-sec-tutorial-conclusion}}
In this paper we introduced the Binaural Synthesis Toolkit, an open, portable  software package for binaural rendering over headphones and transaural systems.
It features an extensible, component-based design that is based on the open VISR framework.
Currently, the Binaural Synthesis Toolkit provides baseline implementations for three general binaural rendering schemes: Dynamic HRTF-based synthesis, rendering based on spherical higher order Ambisonics, and binaural room scanning.
A distinguishing feature, compared to existing software, is the C++/Python interoperability of the BST and the underlying VISR framework.
It facilitates accessible, readable code, ease of modification, and the ability to use the binaural rendering context in different applications or more complex processing systems.

While providing baseline rendering methods in an open, extensible toolkit will reamin the focus of the BST, future extensions might include a dynamic room model, listener position adaptation, or more sophisticated signal processing methods for convolution, filter interpolation and updating, or fractional delay filtering.
We alsop aim to make the renderers and building available as easy-to use tools such as digital audio workstation (DAW) plugins or Max/MSP externals.

The intended use of the BST is as a tool for practical binaural sound reproduction and to foster reproducible research in audio.


\subsection{References}
\label{\detokenize{binaural-synthesis-toolkit:references}}



\section{Component reference}
\label{\detokenize{binaural-synthesis-toolkit:component-reference}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-component-reference}}

\subsection{The renderer components}
\label{\detokenize{binaural-synthesis-toolkit:the-renderer-components}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-reference-core-renderers}}
The renderer classes contain the audio signal flow for one binaural synthesis approach.
Typically, they have a large number of configuration parameters to select between different processing variants.

In contrasts to the realtime renderering components (Section {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-reference-realtime-renderers}]{\sphinxcrossref{\DUrole{std,std-ref}{Realtime rendering components}}}}), the core renderers are designed to be usable in very different environments, for example within a realtime renderer, but also in an offline simultation or a DAW external where control input is provided differently.
For this reason, components as network data receivers are omitted, and all parameter input and output is handled through parameter ports instead.


\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{DynamicHrirRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-dynamichrirrenderer}}
\begin{figure}[htbp]
\centering
\capstart

\noindent\sphinxincludegraphics[width=0.800\linewidth]{{dynamic_hrir_synthesis}.png}
\caption{\sphinxcode{\sphinxupquote{DynamicHrirRenderer}} component}\label{\detokenize{binaural-synthesis-toolkit:id52}}\end{figure}


\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{HoaBinauralRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-hoabinauralrenderer}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{HoaObjectToBinauralRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-hoaobjecttobinauralrenderer}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{VirtualLoudspeakerRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-virtualloudspeakerrenderer}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{ObjectToVirtualLoudspeakerRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-objecttovirtualloudspeakerrenderer}}

\subsection{Realtime rendering components}
\label{\detokenize{binaural-synthesis-toolkit:realtime-rendering-components}}\label{\detokenize{binaural-synthesis-toolkit:visr-bst-reference-realtime-renderers}}
The realtime rendering components provide signal flows for the different rendering approaches including the realtime input/output for head tracking information and, where applicable, object metadata.
These classes are therefore less versatile than the core renderers described in Section {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-reference-core-renderers}]{\sphinxcrossref{\DUrole{std,std-ref}{The renderer components}}}}, but provide ready-to-go components for many practical uses.


\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{RealtimeDynamicHrirRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-realtimedynamichrirrenderer}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{RealtimeHoaObjectToBinauralRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-realtimehoaobjecttobinauralrenderer}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{RealtimeHoaBinauralRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-realtimehoabinauralrenderer}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{RealtimeVirtualLoudspeakerRenderer}}}
\label{\detokenize{binaural-synthesis-toolkit:component-realtimevirtualloudspeakerrenderer}}

\subsection{Controller components}
\label{\detokenize{binaural-synthesis-toolkit:controller-components}}
Controller components implement the logic of binaural synthesis renderer and control the audio processing.
Therefore the form the core of the BST.
There are two controllers, one for dynamic HRIR synthesis and one for virtual loudspeaker rendererin.
Note that the HOA synthesis rendering does not require a controller.


\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{DynamicHrirController}}}
\label{\detokenize{binaural-synthesis-toolkit:component-dynamichrircontroller}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{VirtualLoudspeakerController}}}
\label{\detokenize{binaural-synthesis-toolkit:component-virtualloudspeakercontroller}}

\subsection{HOA components}
\label{\detokenize{binaural-synthesis-toolkit:hoa-components}}
The sub-module \sphinxcode{\sphinxupquote{visr\_bst.hoa\_components}} contains a set of processing components that are used
in the HOA (higher-order Ambisonics) binaural rendering approaches.

\begin{sphinxadmonition}{note}{Note:}
These classes might be moved outside the \sphinxcode{\sphinxupquote{visr\_bst}} module in the future, and might also be reimplemented in C++.
\end{sphinxadmonition}


\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{HoaObjectEncoder}}}
\label{\detokenize{binaural-synthesis-toolkit:component-hoaobjectencoder}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{HoaCoefficientRotation}}}
\label{\detokenize{binaural-synthesis-toolkit:component-hoacoefficientrotation}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{HoaRotationMatrixCalculator}}}
\label{\detokenize{binaural-synthesis-toolkit:component-hoarotationmatrixcalculator}}

\subsection{Trackers}
\label{\detokenize{binaural-synthesis-toolkit:trackers}}
Tracker classes receive data from headtracking devices and create \sphinxcode{\sphinxupquote{pml.ListenerPosition}} parameters.
Tracker objects can be used either in custom signal flows or passed as optional arguments to the {\hyperref[\detokenize{binaural-synthesis-toolkit:visr-bst-reference-realtime-renderers}]{\sphinxcrossref{\DUrole{std,std-ref}{Realtime rendering components}}}}.


\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{RazorAHRS}}}
\label{\detokenize{binaural-synthesis-toolkit:component-razorahrs}}

\subsubsection{Component \sphinxstyleliteralintitle{\sphinxupquote{RazorAHRSWithUdpCalibrationTrigger}}}
\label{\detokenize{binaural-synthesis-toolkit:component-razorahrswithudpcalibrationtrigger}}

\chapter{References}
\label{\detokenize{references:references}}\label{\detokenize{references::doc}}


\begin{sphinxthebibliography}{CFJ+17}
\bibitem[T1]{\detokenize{T1}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-wilson-et-al2014-best-practices-for-scientific-computing}} 
Greg Wilson, D. A. Aruliah, C Brown, and others. Best practices for scientific computing. \sphinxstyleemphasis{PLoS Biology}, 12(1):e1001745, January 2014.
}
\bibitem[T2]{\detokenize{T2}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-cannam-figueira-plumbley2012-sound-software-towards-software-research-in-audio-and-music-research}} 
Chris Cannam, Lu’ıs Figueira, and Mark D. Plumbley. Sound software: towards software reuse in audio and music research. In \sphinxstyleemphasis{IEEE Int. Conf. Acoust., Speech Signal Process.}, 2745\textendash{}2748. March 2012.
}
\bibitem[T3]{\detokenize{T3}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-coleman-et-al2018-an-audio-visual-system-for-object-based-audio}} 
Philip Coleman, Andreas Franck, Jon Francombe, and others. An audio-visual system for object-based audio: From recording to listening. \sphinxstyleemphasis{IEEE Transactions on Multimedia}, 2018.
}
\bibitem[T4]{\detokenize{T4}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-orlarey-fober-letz2004-syntactical-and-semantic-aspects-of-faust}} 
Yann Orlarey, Dominique Fober, and Stéphane Letz. Syntactical and semantical aspects of Faust. \sphinxstyleemphasis{Soft Computing}, 8(9):623\textendash{}632, 2004.
}
\bibitem[T5]{\detokenize{T5}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-boulanger2000-the-csound-book}} 
Richard Charles Boulanger, editor. \sphinxstyleemphasis{The Csound Book}. MIT Press, 2000.
}
\bibitem[T6]{\detokenize{T6}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-wilson-cottle-collins2011-the-supercollider-book}} 
Scott Wilson, David Cottle, and Nick Collins. \sphinxstyleemphasis{The SuperCollider Book}. MIT Press, 2011.
}
\bibitem[T7]{\detokenize{T7}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-carpentier-noisternig-warusfel2015-twenty-years-of-ircam-spat-looking-back-looking-forward}} 
Thibaut Carpentier, Markus Noisternig, and Olivier Warusfel. Twenty years of ircam Spat: looking back, looking forward. In \sphinxstyleemphasis{Proc. Int. Computer Music Conf.} Denton, TX, USA, September 2015.
}
\bibitem[T8]{\detokenize{T8}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-amatriain-arumi-garcia2008-a-platform-for-efficient-and-rapid-development-of-cross-platform-audio-applications}} 
Xavier Amatriain, Pau Arumi, and David Garcia. A framework for efficient and rapid development of cross-platform audio applications. \sphinxstyleemphasis{Multimedia Systems}, 14(1):15\textendash{}32, June 2008. URL: \sphinxurl{https://doi.org/10.1007/s00530-007-0109-6}.
}
\bibitem[T9]{\detokenize{T9}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-geier-hohn-spors2012-an-open-source-c-framework-for-multithreaded-realtime-multichannel-applications}} 
Matthias Geier, Torben Hohn, and Sascha Spors. An open-source C++ framework for multithreaded realtime multichannel audio applications. In \sphinxstyleemphasis{Proc. Linux Audio Conf.}, 183\textendash{}188. Stanford, California, USA, April 2012.
}
\bibitem[T10]{\detokenize{T10}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-oliphant2007-python-for-scientific-computing}} 
Travis E. Oliphant. Python for scientific computing. \sphinxstyleemphasis{Computing in Science Engineering}, 9(3):10\textendash{}20, May 2007.
}
\bibitem[T11]{\detokenize{T11}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-s3a2018-visr-download-site}} 
Visr download web site. http://cvssp.org/data/s3a/public/VISR/, August 2018.
}
\bibitem[T12]{\detokenize{T12}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-mackensen-et-al1999-binaural-room-scanning-a-new-tool-for-acoustic-and-psychoacoustic-research}} 
Philip Mackensen, Uwe Felderhof, Günther Theile, and others. Binaural room scanning — a new tool for acoustic and psychoacoustic research. \sphinxstyleemphasis{J. Acoust. Soc. Amer.}, 105(2):1343\textendash{}1344, 1999.
}
\bibitem[T13]{\detokenize{T13}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-pike-romanov2017-an-impulse-response-dataset-for-dynamic-data-based-auralization-of-advanced-sound-systems}} 
Chris Pike and Michael Romanov. An impulse response dataset for dynamic data-based auralization of advanced sound systems. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 142nd Conv.} Berlin, Germany, May 2017. Engineering Brief. URL: \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=18709}.
}
\bibitem[T14]{\detokenize{T14}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-franck-et-al2018-an-open-realtime-binaural-synthesis-toolkit-for-audio-research}} 
Andreas Franck, Giacomo Costantini, Chris Pike, and Filippo Maria Fazi. An open realtime binaural synthesis toolkit for audio research. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 144th Conv.} Milano, Italy, May 2018. Engineering Brief.
}
\bibitem[T15]{\detokenize{T15}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-hughes-et-al2018-dual-frequency-amplitude-panning-for-multichannel-audio-systems}} 
Richard James Hughes, Andreas Franck, Trevor J. Cox, Ben G. Shirley, and Filippo Maria Fazi. Dual frequency band amplitude panning for multichannel audio systems. In \sphinxstyleemphasis{Proc. AES Int. Conf Sound Reproduction}. Tokyo, Japan, August 2018.
}
\bibitem[T16]{\detokenize{T16}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-diamond-boyd2016-cvxpy}} 
Steven Diamond and Stephen Boyd. CVXPY: a Python-embedded modeling language for convex optimization. \sphinxstyleemphasis{J. Mach. Learn. Res.}, 17(83):1\textendash{}5, 2016. http://www.cvxpy.org.
}
\bibitem[T17]{\detokenize{T17}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-itu2017-itu-r-bs2051-1}} 
ITU. Itu-r bs.2051-1, advanced sound system for programme production. 2017.
}
\bibitem[T18]{\detokenize{T18}}{\phantomsection\label{\detokenize{visr-python-tutorial:tut-franck-wang-fazi2017-sparse-l1-optimal-multiloudspeaker-panning-and-its-equivalence-to-vector-based-amplitude-panning}} 
Andreas Franck, Wenwu Wang, and Filippo Maria Fazi. Sparse, \$\textbackslash{}ell \_1\$-optimal multi-loudspeaker panning and its relation to vector base amplitude panning. \sphinxstyleemphasis{IEEE Transactions on Audio, Speech, and Language Processing}, 25(5):996\textendash{}1010, May 2017.
}
\bibitem[B1]{\detokenize{B1}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-nicol2010-binaural-technology}} 
Rozenn Nicol. \sphinxstyleemphasis{Binaural Technology}. AES Monographs. AES, New York, NY, 2010.
}
\bibitem[B2]{\detokenize{B2}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-lindau-weinzierl2012-assessing-the-plausibility-of-virtual-acoustic-environments}} 
Alexander Lindau and Stefan Weinzierl. Assessing the plausibility of virtual acoustic environments. \sphinxstyleemphasis{Acta Acoustica United with Acoustica}, 98(5):804\textendash{}810, September 2012.
}
\bibitem[B3]{\detokenize{B3}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-jot-larcher-warusfel-1995-digital-signal-processing-issues-in-the-context-of-binaural-and-transaural-stereophony}} 
Jean-Marc Jot, Véronique Larcher, and Olivier Warusfel. Digital signal processing issues in the context of binaural and transaural stereophony. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 98th Conv.} Paris, France, February 1995.
}
\bibitem[B4]{\detokenize{B4}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-algazi-duda2011-headphone-based-spatial-sound}} 
V. Ralph Algazi and Richard O.he Duda. Headphone-based spatial sound. \sphinxstyleemphasis{IEEE Signal Processing Magazine}, 28(1):33\textendash{}42, January 2011.
}
\bibitem[B5]{\detokenize{B5}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-cannam-figueira-plumbley2012-sound-software-towards-software-research-in-audio-and-music-research}} 
Chris Cannam, Lu’ıs Figueira, and Mark D. Plumbley. Sound software: towards software reuse in audio and music research. In \sphinxstyleemphasis{Proc. IEEE Int. Conf. Acoust., Speech, Signal Process.}, 2745\textendash{}2748. Kyoto, Japan, March 2012.
}
\bibitem[B6]{\detokenize{B6}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-wilson-et-al2014-best-practices-for-scientific-computing}} 
Greg Wilson, D. A. Aruliah, C Brown, and others. Best practices for scientific computing. \sphinxstyleemphasis{PLoS Biology}, 12(1):e1001745, January 2014.
}
\bibitem[B7]{\detokenize{B7}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-franck-et-al2018-an-open-software-rendering-framework-for-audio-reproduction-and-reproducible-research}} 
Andreas Franck and Filippo Maria Fazi. VISR \textendash{} a versatile open software framework for audio signal processing. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 2018 Int. Conf. Spatial Reproduction}. Tokyo, Japan, August 2018.
}
\bibitem[B8]{\detokenize{B8}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-mackensen-et-al1999-binaural-room-scanning-a-new-tool-for-acoustic-and-psychoacoustic-research}} 
Philip Mackensen, Uwe Felderhof, Günther Theile, and others. Binaural room scanning — a new tool for acoustic and psychoacoustic research. \sphinxstyleemphasis{J. Acoust. Soc. Amer.}, 105(2):1343\textendash{}1344, 1999.
}
\bibitem[B9]{\detokenize{B9}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-daniel-rault-polack1998-ambisonics-encoding-of-other-audio-format-for-multiple-listening-conditions}} 
Jérôme Daniel, Jean-Bernard Rault, and Jean-Dominique Polack. Ambisonics encoding of other audio formats for multiple listening conditions. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 105th Conv.} San Francisco, CA, USA, September 1998. URL: \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=8385}.
}
\bibitem[B10]{\detokenize{B10}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-aes2015-aes69-sofa-standard}} 
Audio Engineering Society. Aes69:2015 AES standard for file exchange \textendash{} Spatial acoustic data file format. 2015.
}
\bibitem[B11]{\detokenize{B11}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-geier-spors2012-spatial-audio-with-the-soundscape-renderer}} 
Matthias Geier and Sascha Spors. Spatial audio with the SoundScape renderer. In \sphinxstyleemphasis{Proc. 27th Tonmeistertagung / VDT Int. Conv.} Cologne, Germany, November 2012.
}
\bibitem[B12]{\detokenize{B12}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-coleman-et-al2018-an-audio-visual-system-for-object-based-audio}} 
Philip Coleman, Andreas Franck, Teofilo de Campos, and others. An audio-visual system for object-based audio: From recording to listening. \sphinxstyleemphasis{IEEE Transactions on Multimedia}, 2018. Accepted for publication.
}
\bibitem[B13]{\detokenize{B13}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-oliphant2007-python-for-scientific-computing}} 
Travis E. Oliphant. Python for scientific computing. \sphinxstyleemphasis{Computing in Science Engineering}, 9(3):10\textendash{}20, May 2007.
}
\bibitem[B14]{\detokenize{B14}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-jot-walsh-philp2006-binaural-simulation-of-complex-acoustic-scenes-for-interactive-audio}} 
Jean-Marc Jot, Adam Philp, and Martin Walsh. Binaural simulation of complex acoustic scenes for interactive audio. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 121st Conv.} San Francisco, CA, USA, October 2006. URL: \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=13784}.
}
\bibitem[B15]{\detokenize{B15}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-gamper2013-selection-and-interpolation-of-hrtf-for-rendering-moving-virtual-sources}} 
Hannes Gamper. Selection and interpolation of head-related transfer functions for rendering moving virtual sound sources. In \sphinxstyleemphasis{Proc. 16th Int. Conf. Digital Audio Effects}. Maynooth, Ireland, September 2013.
}
\bibitem[B16]{\detokenize{B16}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-lindau-estrella-weinzierl2010-individualization-of-dynamic-binaural-synthesis-by-real-time-manipulation-of-the-itd}} 
Alexander Lindau, Jorgos Estrella, and Stefan Weinzierl. Individualization of dynamic binaural synthesis by real time manipulation of ITD. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 128th Conv.} London, UK, May 2010. URL: \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=15385}.
}
\bibitem[B17]{\detokenize{B17}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-mckeag-mcgrath1996-sound-field-format-to-binaural-decoder-with-head-tracking}} 
Adam McKeag and David S. McGrath. Sound field format to binaural decoder with head tracking. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 6th Australian Regional Conv.} Melbourne, Australia, August 1996. URL: \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=7477}.
}
\bibitem[B18]{\detokenize{B18}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-jot-wardle-larcher1998-approaches-to-binaural-synthesis}} 
Jean-Marc Jot, Scott Wardle, and Veronique Larcher. Approaches to binaural synthesis. In \sphinxstyleemphasis{Proc. AES 105th Conv.} San Francisco, CA, USA, September 1998. URL: \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=8319}.
}
\bibitem[B19]{\detokenize{B19}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-bernschuetz-et-al2014-binaural-reproduction-of-plane-waves-with-reduced-modal-order}} 
Benjamin Bernschutz, A. Vazquez Giner, C. Porschmann, and J. Arend. Binaural reproduction of plane waves with reduced modal order. \sphinxstyleemphasis{Acta Acoustica United with Acoustica}, 100(5):972\textendash{}983, September 2014. URL: \sphinxurl{https://doi.org/10.3813/aaa.918777}.
}
\bibitem[B20]{\detokenize{B20}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-ivanic-ruedenberg1996-rotation-matrices-for-real-spherical-harmonics-direct-determination-by-recursion}} 
Joseph Ivanic and Klaus Ruedenberg. Rotation matrices for real spherical harmonics. direct determination by recursion. \sphinxstyleemphasis{J. Phys. Chem}, 100(15):6342\textendash{}6347, April 1996.
}
\bibitem[B21]{\detokenize{B21}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-pike-melchior-tew2014-assessing-the-plausibility-of-non-individualised-dynamic-binaural-synthesis-in-a-small-room}} 
Chris Pike, Frank Melchior, and Tony Tew. Assessing the plausibility of non-individualised dynamic binaural synthesis in a small room. In \sphinxstyleemphasis{AES 55th Int. Conf. Spatial Audio}. Helsinki, Finland, August 2014.
}
\bibitem[B22]{\detokenize{B22}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-pike-romanov2017-an-impulse-response-dataset-for-dynamic-data-based-auralization-of-advanced-sound-systems}} 
Chris Pike and Michael Romanov. An impulse response dataset for dynamic data-based auralization of advanced sound systems. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 142nd Conv.} Berlin, Germany, May 2017. Engineering Brief. URL: \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=18709}.
}
\bibitem[B23]{\detokenize{B23}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-laitinen-pulkki2009-binaural-rendering-for-directional-audio-coding}} 
Mikko-Ville Laitinen and Ville Pulkki. Binaural reproduction for directional audio coding. In \sphinxstyleemphasis{Proc. IEEE Workshop Applicat. Signal Process. Audio Acoust.}, 337\textendash{}340. New Paltz, NY, October 2009.
}
\bibitem[B24]{\detokenize{B24}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-franck2014-efficient-frequency-domain-crossfading-for-fast-convolution-with-application-to-binaural-synthesis}} 
Andreas Franck. Efficient frequency-domain filter crossfading for fast convolution with application to binaural synthesis. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 55th Int. Conf. Spatial Audio}. Helsinki, Finland, August 2014.
}
\bibitem[B25]{\detokenize{B25}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-franck2008-efficient-algorithms-and-structures-for-fractional-delay-filtering-based-on-lagrange-interpolation}} 
Andreas Franck. Efficient algorithms and structures for fractional delay filtering based on Lagrange interpolation. \sphinxstyleemphasis{J. Audio Eng. Soc.}, 56(12):1036\textendash{}1056, December 2008.
}
\bibitem[B26]{\detokenize{B26}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-woodcock-et-al2016-presenting-the-s3a-object-based-audio-drama-dataset}} 
James Woodcock, Chris Pike, Frank Melchior, and others. Presenting the s3a object-based audio drama dataset. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 140th Conv.} Paris, France, May 2016. Engineering Brief. URL: \sphinxurl{http://www.aes.org/e-lib/browse.cfm?elib=18159}.
}
\bibitem[B27]{\detokenize{B27}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-itu2017-itu-r-2076-1-adm}} 
ITU. Itu-r bs.2076-1 : audio definition model. 2017.
}
\bibitem[B28]{\detokenize{B28}}{\phantomsection\label{\detokenize{binaural-synthesis-toolkit:bst-simon-galvez-fazi2015-loudspeaker-arrays-for-transaural-reproduction}} 
Marcos Simón-Gálvez and Maria Fazi, Filippo. Loudspeaker arrays for transaural reproduction. In \sphinxstyleemphasis{Proc. 22nd Int. Congr. Sound Vibration}. Florence, Italy, July 2015.
}
\bibitem[CFJ+17]{\detokenize{CFJ+17}}{\phantomsection\label{\detokenize{references:coleman2017reverb}} 
Philip Coleman, Andreas Franck, P. J. B. Jackson, Richard Hughes, Luca Remaggi, and Frank Melchior. Object-based reverberation for spatial audio. \sphinxstyleemphasis{J. Audio Eng. Soc.}, 2017.
}
\bibitem[FCPF18]{\detokenize{FCPF18}}{\phantomsection\label{\detokenize{references:franck-et-al2018-an-open-realtime-binaural-synthesis-toolkit-for-audio-research}} 
Andreas Franck, Giacomo Costantini, Chris Pike, and Filippo Maria Fazi. An open realtime binaural synthesis toolkit for audio research. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 144th Conv.} Milano, Italy, May 2018. Engineering Brief.
}
\bibitem[FF18]{\detokenize{FF18}}{\phantomsection\label{\detokenize{references:franck-et-al2018-an-open-software-rendering-framework-for-audio-reproduction-and-reproducible-research}} 
Andreas Franck and Filippo Maria Fazi. VISR \textendash{} a versatile open software framework for audio signal processing. In \sphinxstyleemphasis{Proc. Audio Eng. Soc. 2018 Int. Conf. Spatial Reproduction}. Tokyo, Japan, August 2018.
}
\end{sphinxthebibliography}



\renewcommand{\indexname}{Index}
\printindex
\end{document}