%Copyright (C) 2007-2015  Brian Langenberger
%This work is licensed under the
%Creative Commons Attribution-Share Alike 3.0 United States License.
%To view a copy of this license, visit
%http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to
%Creative Commons,
%171 Second Street, Suite 300,
%San Francisco, California, 94105, USA.

\section{WavPack Encoding}

{\relsize{-1}
  \input{wavpack/algorithms/encode_wavpack}
}

\clearpage

\subsection{Determine Block Split}
\label{wavpack:block_split}
\ALGORITHM{input stream's channel assignment}{number of blocks per set, list of channel counts per block}
\SetKwData{BLOCKCOUNT}{block count}
\SetKwData{BLOCKCHANNELS}{block channels}
\Switch(\tcc*[f]{split channels by left/right pairs}){channel assignment}{
  \uCase{mono}{
    $\text{\BLOCKCOUNT} \leftarrow 1$\;
    $\text{\BLOCKCHANNELS} \leftarrow \texttt{[1]}$\;
  }
  \uCase{front left, front right}{
    $\text{\BLOCKCOUNT} \leftarrow 1$\;
    $\text{\BLOCKCHANNELS} \leftarrow \texttt{[2]}$\;
  }
  \uCase{front left, front right, front center}{
    $\text{\BLOCKCOUNT} \leftarrow 2$\;
    $\text{\BLOCKCHANNELS} \leftarrow \texttt{[2, 1]}$\;
  }
  \uCase{front left, front right, back left, back right}{
    $\text{\BLOCKCOUNT} \leftarrow 2$\;
    $\text{\BLOCKCHANNELS} \leftarrow \texttt{[2, 2]}$\;
  }
  \uCase{front left, front right, front center, back center}{
    $\text{\BLOCKCOUNT} \leftarrow 3$\;
    $\text{\BLOCKCHANNELS} \leftarrow \texttt{[2, 1, 1]}$\;
  }
  \uCase{front left, front right, front center, back left, back right}{
    $\text{\BLOCKCOUNT} \leftarrow 3$\;
    $\text{\BLOCKCHANNELS} \leftarrow \texttt{[2, 1, 2]}$\;
  }
  \uCase{front left, front right, front center, LFE, back left, back right}{
    $\text{\BLOCKCOUNT} \leftarrow 4$\;
    $\text{\BLOCKCHANNELS} \leftarrow \texttt{[2, 1, 1, 2]}$\;
  }
  \Other(\tcc*[f]{save them independently}){
    $\text{\BLOCKCOUNT} \leftarrow$ channel count\;
    $\text{\BLOCKCHANNELS} \leftarrow$ 1 per channel\;
  }
}
\Return \BLOCKCOUNT and \BLOCKCHANNELS
\EALGORITHM
\vskip 1ex
\par
\noindent
One could invent alternate channel splits for other obscure assignments.
WavPack's only requirement is that all channels must be in
Wave order\footnote{see page \pageref{wave_channel_assignment}}
and each block must contain 1 or 2 channels.

\begin{figure}[h]
\includegraphics{wavpack/figures/block_channels.pdf}
\end{figure}

\clearpage

\subsection{Encoding Parameters}
\label{wavpack:encoding_parameters}
{\relsize{-1}
  \input{wavpack/algorithms/encoding_parameters}
}

\clearpage

\subsection{Encoding Block}
\label{wavpack:encode_block}
{\relsize{-2}
  \input{wavpack/algorithms/encode_block}
}

\clearpage

\subsection{Calculating Maximum Magnitude}
\label{wavpack:calc_maximum_magnitude}
{\relsize{-1}
  \input{wavpack/algorithms/calculate_max_magnitude}
}

\subsection{Calculating Wasted Bits Per Sample}
\label{wavpack:calc_wasted_bps}
{\relsize{-1}
  \input{wavpack/algorithms/calculate_wasted_bps}
where the \texttt{wasted} function is defined as:
\begin{equation*}
\texttt{wasted}(x) =
\begin{cases}
\infty & \text{if } x = 0 \\
0 & \text{if } x \bmod 2 = 1 \\
1 + \texttt{wasted}(x \div 2) & \text{if } x \bmod 2 = 0 \\
\end{cases}
\end{equation*}
}

\clearpage

\subsection{Joint Stereo Conversion}
\label{wavpack:calc_joint_stereo}
\input{wavpack/algorithms/apply_joint_stereo}

\subsubsection{Joint Stereo Example}
\begin{table}[h]
{\relsize{-1}
\begin{tabular}{|r|r|r||>{$}r<{$}|>{$}r<{$}|}
$i$ & $\textsf{left}_i$ & $\textsf{right}_i$ & \textsf{mid}_i & \textsf{side}_i \\
\hline
0 & 0 & 64 & 0 - 64 = -64 & \lfloor(0 + 64) \div 2\rfloor = 32 \\
1 & 16 & 62 & 16 - 62 = -46 & \lfloor(16 + 62) \div 2\rfloor = 39 \\
2 & 31 & 56 & 31 - 56 = -25 & \lfloor(31 + 56) \div 2\rfloor = 43 \\
3 & 44 & 47 & 44 - 47 = -3 & \lfloor(44 + 47) \div 2\rfloor = 45 \\
4 & 54 & 34 & 54 - 34 = 20 & \lfloor(54 + 34) \div 2\rfloor = 44 \\
5 & 61 & 20 & 61 - 20 = 41 & \lfloor(61 + 20) \div 2\rfloor = 40 \\
6 & 64 & 4 & 64 - 4 = 60 & \lfloor(64 + 4) \div 2\rfloor = 34 \\
7 & 63 & -12 & 63 - -12 = 75 & \lfloor(63 + -12) \div 2\rfloor = 25 \\
8 & 58 & -27 & 58 - -27 = 85 & \lfloor(58 + -27) \div 2\rfloor = 15 \\
9 & 49 & -41 & 49 - -41 = 90 & \lfloor(49 + -41) \div 2\rfloor = 4 \\
\end{tabular}
}
\end{table}

\clearpage

\subsection{Writing Block Parameters}
\label{wavpack:write_block_parameters}
{\relsize{-1}
  \input{wavpack/algorithms/write_block_parameters}
}

\clearpage

\subsection{Writing Sub Block Header}
\label{wavpack:write_sub_block_header}
\input{wavpack/algorithms/write_sub_block_header}

\clearpage

\input{wavpack/encode/terms}

\clearpage

\input{wavpack/encode/weights}

\clearpage

\input{wavpack/encode/samples}

\clearpage

\input{wavpack/encode/entropy}

\clearpage

\input{wavpack/encode/correlation}

\clearpage

\input{wavpack/encode/bitstream}

\clearpage

\subsection{Writing RIFF WAVE Header and Footer}
\label{wavpack:write_wave_header}
\begin{figure}[h]
  \includegraphics{wavpack/figures/pcm_sandwich.pdf}
\end{figure}


\subsection{Writing MD5 Sum}
\label{wavpack:write_md5}
MD5 sum is calculated as if the PCM data had been read from
a wave file's \texttt{data} chunk.
That is, the samples are converted to little-endian format
and are signed if the stream's bits-per-sample is greater than 8.
\begin{figure}[h]
  \includegraphics{wavpack/figures/md5sum.pdf}
\end{figure}

\subsection{Writing Extended Integers}
\label{wavpack:write_extended_integers}
\begin{figure}[h]
  \includegraphics{wavpack/figures/extended_integers.pdf}
\end{figure}

\clearpage

\subsection{Writing Channel Info}
\label{wavpack:write_channel_info}
\begin{figure}[h]
  \includegraphics{wavpack/figures/channel_info.pdf}
\end{figure}


\subsection{Writing Sample Rate}
\label{wavpack:write_sample_rate}
\begin{figure}[h]
  \includegraphics{wavpack/figures/sample_rate.pdf}
\end{figure}

\clearpage

\subsection{Writing Block Header}
\label{wavpack:write_block_header}
{\relsize{-1}
  \input{wavpack/algorithms/write_block_header}
}

\clearpage

\subsection{Round-Tripping Correlation Weights}
\label{wavpack:roundtrip_weights}
Because the final weight values of one block
may not be exactly representable in a correlation weights sub-block,
it's necessary to ``round-trip'' the weight values
so that the starting values for the next block
are the same as the values stored in the sub-block.

\input{wavpack/algorithms/roundtrip_weights}

\clearpage

\subsection{Round-Tripping Correlation Samples}
\label{wavpack:roundtrip_samples}

\input{wavpack/algorithms/roundtrip_samples}
