\begin{hcarentry}[updated]{Audio signal processing}
\label{audiosp}
\report{Henning Thielemann}%05/08
\status{experimental, active development}
\makeheader

In this project, audio signals are processed using pure Haskell code.
The highlights are:
\begin{itemize}
\item a basic signal synthesis backend for Haskore~\cref{haskore},
\item experimental structures for filter networks,
\item basic audio signal processing, including some hard-coded frequency filters,
\item advanced framework for signal processing supported by physical units,
that is, the plain data can be stored in a very simple number format,
even fixed point numbers,
but the sampling parameters rate and amplitude can be complex types,
like numbers with physical units,
\item frameworks for inference of sample rate and amplitude,
that is, sampling rate and amplitude can be omitted in most parts
of a signal processing expression.
They are inferred automatically,
just as types are inferred in Haskell's type system.
Although the inference of signal parameters needs some preprocessing,
the frameworks preserve the functional style of programming
and do not need Arrows and according notation.

We have checked three approaches,
where the last one is the most promising.
\begin{itemize}
\item
Explicitly maintain a dictionary of signal parameters
in a Reader-Writer-State monad,
which must be computed completely
before any signal processing takes place.
This forces all signal parameters to share the same type
and prohibits infinitely many signal processors to be involved
(e.g., concatenation of infinitely many short noises).
\item
Simulation of logic programming
by lazy cycles of function applications
(i.e., tied knots, fixed points).
The main problems are quadratical computation complexity
and a cumbersome and error-prone application.
Namely, for each input you have to handle a parameter output,
and vice versa for propagation of parameters through the network.
You need combinators (infix operators) for combining these functions,
but you will easily run into cases where you must plug manually,
which is a nightmare.
\item
Unify only the sample rate. Use a Reader functor/monad.
Amplitude is propagated from inputs to outputs only.
This is a bit conservative, but is simple and comprehensive
and fulfils our needs so far.
\end{itemize}

\item
We checked several low-level implementations in order to achieve reasonable speed.
The standard list data structure is very convenient for programming
but much too slow for signal processing.
We try to get rid of it in several ways:
\begin{itemize}
\item A fusion framework based on \verb|mapAccumL| and \verb|unfoldr| like functions.
Since in current GHC versions the optimisation rules do not fire reliably
(e.g., rules are not specialised if a function gets specialised to a monomorphic type)
we end up with intermediate list structures too often.
\item A chunky list based on the StorableVector is much faster if higher order functions
like \verb|map| and \verb|unfoldr| are inlined.
However, this data structure is not elementwise lazy (a problem for feedback),
and can store only values of \verb|Storable| type
(e.g., functions are excluded).
\item A data structure analogous to the \verb|Stream| framework,
where a list is represented by a \verb|StateT s Maybe a|
which generates signal values by calling the generator function.
In this approach fusion happens by inlining,
and lists or other data structures can be used for sharing
and feedback including sharing.
\end{itemize}

A combination of the last two approaches seems to be a good choice so far.
However, maintaining all code versions for comparison purposes
led to much code duplication in the meantime.
\end{itemize}

The library comes with basic Cabal support
and requires the Numeric Prelude framework~\cref{numericprelude}
of revised numeric type classes.

\FuturePlans
\begin{itemize}
\item
Design a common API to the Haskell synthesiser code,
CSound support included in Haskore~\cref{haskore},
and the SuperCollider interface.
\item
Connect with the HaskellDSP library \url{http://haskelldsp.sourceforge.net/}.
(As a beginning we have prepared and uploaded it to
Hackage.)
\item
Hope on faster code generated by Haskell compilers.\ \texttt{:-)}
In simple setups GHC generated code can compete with C,
but in more complex ones the performance is not satisfying.
\end{itemize}


\FurtherReading
\begin{compactitem}
\item \url{http://darcs.haskell.org/synthesizer/}
\item \url{http://dafx04.na.infn.it/WebProc/Proc/P_201.pdf}
\end{compactitem}
\end{hcarentry}
