diff --git a/Codecs/Codec.Dts/DtsCodec.cs b/Codecs/Codec.Dts/DtsCodec.cs index 7087b57a4..fb3badd3d 100644 --- a/Codecs/Codec.Dts/DtsCodec.cs +++ b/Codecs/Codec.Dts/DtsCodec.cs @@ -9,11 +9,10 @@ public sealed record DtsStreamInfo( int SampleRate, int Channels, int Bitrate, int Amode, bool Lfe, long DurationSamples); /// -/// Clean-room DTS Coherent Acoustics (DCA) core codec. The decoder is a faithful managed port of -/// the FFmpeg reference decoder (libavcodec/dcadec.c + dcadata.c + -/// dcahuff.h) and the encoder lives in the companion partial source file. The core decoder -/// emits interleaved little-endian signed 16-bit PCM at the stream's native channel count (the -/// AMODE full-bandwidth channels in document order, with the LFE channel last when present). +/// Clean-room DTS Coherent Acoustics (DCA) core codec; the encoder lives in the companion partial +/// source file. The core decoder emits interleaved little-endian signed 16-bit PCM at the stream's +/// native channel count, in the ITU/WAVE interleave order — front left, front right, front centre, +/// LFE, then the surrounds — rather than the centre-first AMODE order the bit stream uses. /// /// Scope: only the standard 16-bit big-endian framing (sync 0x7FFE8001) is decoded; the 14-bit and /// byte-swapped framings throw . DTS-HD extension substreams @@ -44,7 +43,7 @@ public static DtsStreamInfo ReadStreamInfo(Stream input) { /// /// Decodes a DTS stream into raw interleaved little-endian signed 16-bit PCM on - /// . Channels are emitted in AMODE document order with LFE last. + /// . Channels are emitted in the ITU/WAVE interleave order. /// Throws for the unsupported 14-bit / LE framings. /// public static void Decompress(Stream input, Stream output) { diff --git a/Codecs/Codec.Dts/DtsFrameDecoder.cs b/Codecs/Codec.Dts/DtsFrameDecoder.cs index 339616ea7..a961ed848 100644 --- a/Codecs/Codec.Dts/DtsFrameDecoder.cs +++ b/Codecs/Codec.Dts/DtsFrameDecoder.cs @@ -5,7 +5,7 @@ namespace Codec.Dts; /// /// Decodes a single DTS Coherent Acoustics (DCA) core frame to per-channel float PCM. One instance /// is reused across the stream so the QMF synthesis memory and the ADPCM predictor history persist -/// between frames. The decode follows the DTS core bitstream / FFmpeg's dcadec.c: +/// between frames. The decode follows the DTS core bitstream: /// the primary audio coding header (subband activity, VQ start, joint intensity, the bit-allocation /// / scale-factor / transient / quantization-index code-book selections and scale-factor adjusts), /// then per subframe a set of sub-subframes carrying bit allocation, scale factors, the quantized @@ -23,6 +23,8 @@ internal sealed class DtsFrameDecoder { private const int MaxPrimChannels = 7; // DCA_PRIM_CHANNELS_MAX private const int Subbands = 32; // DCA_SUBBANDS private const int MaxSubsubframes = 4; + private const int MaxAbits = 32; // DCA_ABITS_MAX: bit-allocation index range + private const int CodeBooks = 10; // bit-allocation indices that can carry a sample code book // ── Code books (built once) ─────────────────────────────────────────────── private static readonly DtsBitAllocBook BitAllocIndex = BuildBitAllocIndex(); @@ -62,6 +64,7 @@ public DtsFrameDecoder() { private int _subframes; private int _bitRateIndex; private bool _perfectReconstruction; + private int[] _channelMap = []; private readonly int[] _subbandActivity = new int[MaxPrimChannels]; private readonly int[] _vqStartSubband = new int[MaxPrimChannels]; @@ -69,8 +72,11 @@ public DtsFrameDecoder() { private readonly int[] _transientHuffman = new int[MaxPrimChannels]; private readonly int[] _scalefactorHuffman = new int[MaxPrimChannels]; private readonly int[] _bitallocHuffman = new int[MaxPrimChannels]; - private readonly int[][] _quantIndexHuffman = NewIntMatrix(MaxPrimChannels, 11); - private readonly float[][] _scalefactorAdj = NewFloatMatrix(MaxPrimChannels, 11); + // Indexed by the bit-allocation index, which the subframe header allows up to 26 even though only + // groups 1..10 carry a transmitted code-book selector and scale-factor adjustment. Sizing these to + // the group count alone puts every wide-band subband out of bounds. + private readonly int[][] _quantIndexHuffman = NewIntMatrix(MaxPrimChannels, MaxAbits); + private readonly float[][] _scalefactorAdj = NewFloatMatrix(MaxPrimChannels, MaxAbits); // Per-subframe header state. private readonly int[][] _predictionMode = NewIntMatrix(MaxPrimChannels, Subbands); @@ -85,13 +91,15 @@ public DtsFrameDecoder() { // LFE decimated samples (history + current frame). Sized for the worst case. private readonly float[] _lfeData = new float[64 * 2 + 256]; private float _lfeScaleFactor; + private int _lfeWritten; + private int _lfeHistoryLfe = -1; // Subband samples for the whole frame: [block][chan][subband][8]. private float[][][][]? _subbandSamples; /// /// Decodes the core frame at . On success - /// is the native channel count (AMODE channels + LFE last when present) and the return value is + /// is the native channel count and the return value is, in ITU/WAVE interleave order, /// [channel][sample] float PCM (normalised to roughly ±1). Returns /// when the frame cannot be decoded. /// @@ -112,6 +120,7 @@ public DtsFrameDecoder() { // MULTIRATE_INTER selects the perfect-reconstruction prototype; it is bit 0 of the field that // immediately follows the (optional) header CRC. Re-read it from the parsed header position. this._perfectReconstruction = ReadMultirateInter(data, offset, header); + this._channelMap = DtsFrameHeader.ChannelMap(header.Amode, header.Lfe > 0); // Seek the reader to the end of the parsed frame header (which is byte-exact in bits). r.SkipBits(header.HeaderBitLength); @@ -120,12 +129,19 @@ public DtsFrameDecoder() { return null; var totalChannels = this._primChannels + (this._lfe > 0 ? 1 : 0); + // The audio coding header carries its own channel count; when it disagrees with AMODE the + // arrangement is unknown, so fall back to bit-stream order rather than shuffle blindly. + if (this._channelMap.Length != totalChannels) { + this._channelMap = new int[totalChannels]; + for (var c = 0; c < totalChannels; ++c) + this._channelMap[c] = c; + } var blocks = this._sampleBlocks / 8; if (blocks <= 0) return null; this._subbandSamples = NewSubbandSamples(blocks, this._primChannels); - Array.Clear(this._lfeData, 0, this._lfeData.Length); + this.CarryLfeHistory(blocks); var currentSubframe = 0; var currentSubsubframe = 0; @@ -163,6 +179,20 @@ public DtsFrameDecoder() { } } + // The interpolation FIR reaches back past the first decimated sample of the frame, so the tail of + // the previous frame has to stay in place; clearing the whole buffer restarts the filter from + // silence once per frame and leaves a periodic artefact on the LFE channel. + private void CarryLfeHistory(int blocks) { + var history = 8 * this._lfe; + if (this._lfeHistoryLfe == this._lfe && this._lfeWritten >= history) + Array.Copy(this._lfeData, this._lfeWritten - history, this._lfeData, 0, history); + else + Array.Clear(this._lfeData, 0, Math.Max(history, 0)); + Array.Clear(this._lfeData, history, this._lfeData.Length - history); + this._lfeWritten = history + 2 * this._lfe * blocks; + this._lfeHistoryLfe = this._lfe; + } + // The MULTIRATE_INTER flag sits right after the optional 16-bit header CRC. Re-parse minimally. private static bool ReadMultirateInter(byte[] data, int offset, DtsFrameHeader header) { var buffer = data.AsSpan(offset, Math.Min(data.Length - offset, 32)).ToArray(); @@ -196,14 +226,13 @@ private bool ParseAudioCodingHeader(DtsBitReader r) { for (var i = 0; i < this._primChannels; ++i) this._bitallocHuffman[i] = (int)r.ReadBits(3); for (var i = 0; i < this._primChannels; ++i) - this._quantIndexHuffman[i][0] = 0; + Array.Clear(this._quantIndexHuffman[i]); for (var j = 1; j < 11; ++j) for (var i = 0; i < this._primChannels; ++i) this._quantIndexHuffman[i][j] = (int)r.ReadBits(QuantIndexBitLen[j]); - for (var j = 0; j < 11; ++j) - for (var i = 0; i < this._primChannels; ++i) - this._scalefactorAdj[i][j] = 1f; + for (var i = 0; i < this._primChannels; ++i) + Array.Fill(this._scalefactorAdj[i], 1f); for (var j = 1; j < 11; ++j) for (var i = 0; i < this._primChannels; ++i) if (this._quantIndexHuffman[i][j] < QuantIndexThreshold[j]) @@ -257,7 +286,7 @@ private bool ParseSubframeHeader(DtsBitReader r, int blockIndex, int currentSubf for (var j = 0; j < this._primChannels; ++j) { uint[] scaleTable; int logSize; - if (this._scalefactorHuffman[j] == 6) { scaleTable = DtsTables.ScaleFactorQuant7; logSize = 7; } + if (this._scalefactorHuffman[j] > 5) { scaleTable = DtsTables.ScaleFactorQuant7; logSize = 7; } else { scaleTable = DtsTables.ScaleFactorQuant6; logSize = 6; } for (var k = 0; k < this._subbandActivity[j]; ++k) { @@ -355,25 +384,30 @@ private bool DecodeSubsubframe(DtsBitReader r, int blockIndex, int currentSubfra rscale[l] = 0f; Array.Clear(block, 8 * l, 8); } else { + // A code book is only in play when the transmitted selector falls inside that group's + // size; otherwise the samples are block codes (abits <= 7) or plain fixed-width values. + var book = abits <= CodeBooks ? SampleBitAlloc[abits] : null; + var huffman = book != null && sel < QuantIndexThreshold[abits] && book.Vlc[sel] != null; + var sfi = this._transitionMode[k][l] != 0 && subsubframe >= this._transitionMode[k][l] ? 1 : 0; - rscale[l] = quantStepSize * this._scaleFactor[k][l][sfi] * this._scalefactorAdj[k][sel]; - - var book = abits < SampleBitAlloc.Length ? SampleBitAlloc[abits] : null; - if (abits >= 11 || book == null || book.Vlc[sel] == null) { - if (abits <= 7) { - var size = DtsBlockCode.Sizes[abits - 1]; - var levels = DtsBlockCode.Levels[abits - 1]; - var code1 = (int)r.ReadBits(size); - var code2 = (int)r.ReadBits(size); - if (DtsBlockCode.DecodeBlockCodes(code1, code2, levels, block, 8 * l) != 0) - return false; - } else { - for (var m = 0; m < 8; ++m) - block[8 * l + m] = r.ReadSigned(abits - 3); - } + // The scale-factor adjustment belongs to the bit-allocation index, and it applies only + // when the samples were Huffman coded. + var adj = huffman ? this._scalefactorAdj[k][abits] : 1f; + rscale[l] = quantStepSize * this._scaleFactor[k][l][sfi] * adj; + + if (huffman) { + for (var m = 0; m < 8; ++m) + block[8 * l + m] = book!.Get(r, sel); + } else if (abits <= 7) { + var size = DtsBlockCode.Sizes[abits - 1]; + var levels = DtsBlockCode.Levels[abits - 1]; + var code1 = (int)r.ReadBits(size); + var code2 = (int)r.ReadBits(size); + if (DtsBlockCode.DecodeBlockCodes(code1, code2, levels, block, 8 * l) != 0) + return false; } else { for (var m = 0; m < 8; ++m) - block[8 * l + m] = book.Get(r, sel); + block[8 * l + m] = r.ReadSigned(abits - 3); } } } @@ -432,21 +466,20 @@ private bool DecodeSubsubframe(DtsBitReader r, int blockIndex, int currentSubfra // ── QMF synthesis + LFE interpolation → per-channel PCM ─────────────────── private void FilterChannels(int blocks, float[][] pcm) { - var totalChannels = this._primChannels + (this._lfe > 0 ? 1 : 0); - // Output ordering: decoded prim channels in document (AMODE) order, LFE last. The QMF scale - // 1/sqrt(2) / 32768 matches the reference; we keep ±1-normalised floats (no /32768) for WAV. - var qmfScale = (float)(1.0 / Math.Sqrt(2.0)); + // The QMF output is scaled to the +/-1 float domain the caller quantizes from; the reference + // filterbank gain is 1/sqrt(2) over a 15-bit sample range. + var qmfScale = (float)(1.0 / Math.Sqrt(2.0) / 32768.0); + var map = this._channelMap; for (var blk = 0; blk < blocks; ++blk) { var subbandSamples = this._subbandSamples![blk]; for (var k = 0; k < this._primChannels; ++k) - this._qmf[k].Process(subbandSamples[k], this._subbandActivity[k], pcm[k], blk * 256, + this._qmf[k].Process(subbandSamples[k], this._subbandActivity[k], pcm[map[k]], blk * 256, this._perfectReconstruction, qmfScale); - if (this._lfe > 0) { - var lfeChannel = totalChannels - 1; - DtsLfe.Interpolate(this._lfe, this._lfeData, 2 * this._lfe * (blk + 4), pcm[lfeChannel], blk * 256); - } + if (this._lfe > 0) + DtsLfe.Interpolate(this._lfe, this._lfeData, 2 * this._lfe * (blk + 4), + pcm[map[this._primChannels]], blk * 256); } } diff --git a/Codecs/Codec.Dts/DtsFrameHeader.cs b/Codecs/Codec.Dts/DtsFrameHeader.cs index 666887e3d..e700c6991 100644 --- a/Codecs/Codec.Dts/DtsFrameHeader.cs +++ b/Codecs/Codec.Dts/DtsFrameHeader.cs @@ -64,6 +64,35 @@ public readonly record struct DtsFrameHeader( _ => $"user-defined ({amode})", }; + /// + /// Maps a channel's position in the bit stream to its position in the decoded interleaved PCM. + /// The DTS core transmits the front channels centre-first (C, L, R) and carries the LFE channel + /// last, while interleaved PCM uses the ITU/WAVE order — front left, front right, front centre, + /// LFE, then the surrounds. The returned array is indexed by bit-stream channel (AMODE channels in + /// document order, LFE appended) and yields the interleave slot. AMODE codes above 9 describe + /// arrangements the core decoder does not reconstruct, and keep the bit-stream order. + /// + internal static int[] ChannelMap(int amode, bool lfe) => (amode, lfe) switch { + (0, false) => [0], (0, true) => [0, 1], + (1, false) => [0, 1], (1, true) => [0, 1, 2], + (2, false) => [0, 1], (2, true) => [0, 1, 2], + (3, false) => [0, 1], (3, true) => [0, 1, 2], + (4, false) => [0, 1], (4, true) => [0, 1, 2], + (5, false) => [2, 0, 1], (5, true) => [2, 0, 1, 3], + (6, false) => [0, 1, 2], (6, true) => [0, 1, 3, 2], + (7, false) => [2, 0, 1, 3], (7, true) => [2, 0, 1, 4, 3], + (8, false) => [0, 1, 2, 3], (8, true) => [0, 1, 3, 4, 2], + (9, false) => [2, 0, 1, 3, 4], (9, true) => [2, 0, 1, 4, 5, 3], + _ => Identity(AmodeChannelCount(amode) + (lfe ? 1 : 0)), + }; + + private static int[] Identity(int count) { + var map = new int[count]; + for (var i = 0; i < count; ++i) + map[i] = i; + return map; + } + /// Channel count implied by an AMODE code (excluding the LFE channel). public static int AmodeChannelCount(int amode) => amode switch { 0 => 1, 1 => 2, 2 => 2, 3 => 2, 4 => 2, 5 => 3, 6 => 3, 7 => 4, diff --git a/Codecs/Codec.Dts/DtsQmf.cs b/Codecs/Codec.Dts/DtsQmf.cs index bdca95c47..fd8236cd8 100644 --- a/Codecs/Codec.Dts/DtsQmf.cs +++ b/Codecs/Codec.Dts/DtsQmf.cs @@ -4,13 +4,12 @@ namespace Codec.Dts; /// /// 32-band cosine-modulated QMF synthesis filterbank for the DCA core, reconstructing 256 PCM -/// samples per channel per block from 8 sub-subframe vectors of 32 subband samples each. This is a -/// faithful port of FFmpeg's dca_qmf_32_subbands + synth_filter_float -/// (libavcodec/dcadsp.c, synth_filter.c): the per-subband sign flip -/// ((i-1)&2), a direct (matrix-multiply) 64→32 imdct_half, and the 512-tap -/// polyphase window/overlap stage driven by the perfect- or non-perfect-reconstruction prototype -/// ( / ). The direct -/// IMDCT replaces FFmpeg's FFT path; the task permits a direct matrix multiply for the transform. +/// samples per channel per block from 8 sub-subframe vectors of 32 subband samples each. The stage +/// is the per-subband sign flip ((i-1)&2), the second half of a 64-point IMDCT over the +/// 32 subband values, and a 512-tap polyphase window/overlap driven by the perfect- or +/// non-perfect-reconstruction prototype +/// ( / ). The IMDCT is +/// evaluated as a direct matrix multiply, which is exact and cheap enough at this size. /// public sealed class DtsQmf { @@ -20,9 +19,14 @@ public sealed class DtsQmf { private readonly float[] _synthBuf2 = new float[32]; private int _synthBufOffset; - // Pre-computed imdct_half cosine matrix: out[k] = sum_n in[n] * Cos[k][n], k,n in 0..31. - // FFmpeg's MDCT-half of size 64 produces 32 outputs; the equivalent direct kernel is - // cos(pi/64 * (2k+1) * (n + 0.5)) scaled to match the synth_filter window convention. + // Pre-computed half-IMDCT cosine matrix: out[k] = sum_n in[n] * Cos[k][n], k,n in 0..31. + // + // The filterbank stage is the second half of a 64-point IMDCT over 32 coefficients: + // full[i] = -sum_n in[n] * cos(pi * (2i + 1 + 32) * (2n + 1) / 128), i = 0..63 + // of which the synthesis window consumes full[16..47]. Substituting i = k + 16 leaves + // out[k] = -sum_n in[n] * cos(pi * (2k + 65) * (2n + 1) / 128). + // The phase term is what places each subband at its own centre frequency; getting it wrong + // still yields a full-amplitude signal, just one built from the wrong modulation images. private static readonly float[][] ImdctCos = BuildImdctCos(); private static float[][] BuildImdctCos() { @@ -30,7 +34,7 @@ private static float[][] BuildImdctCos() { for (var k = 0; k < 32; ++k) { m[k] = new float[32]; for (var n = 0; n < 32; ++n) - m[k][n] = (float)Math.Cos(Math.PI / 64.0 * (2 * k + 1) * (2 * n + 1)); + m[k][n] = (float)-Math.Cos(Math.PI * (2 * k + 65) * (2 * n + 1) / 128.0); } return m; } diff --git a/Codecs/Codec.Dts/DtsTables.cs b/Codecs/Codec.Dts/DtsTables.cs index 63d0ae6b9..7a740cad0 100644 --- a/Codecs/Codec.Dts/DtsTables.cs +++ b/Codecs/Codec.Dts/DtsTables.cs @@ -80,25 +80,38 @@ public static class DtsTables { ]; /// - /// Provides the lossy quant value. + /// Quantizer step sizes for the lossy (constant bit rate) core, as the Q22 fixed-point integers + /// the format defines. Rounding them to short decimals loses up to 0.14 percent on the finest + /// steps, and that shows up as a level error on any content the encoder codes at high resolution. /// - public static readonly float[] LossyQuant = [ - 0f, 1.6f, 1.0f, 0.8f, 0.59f, 0.50f, 0.42f, 0.34f, - 0.19f, 0.11f, 0.06f, 0.035f, 0.019f, 0.011f, 0.0065f, 0.0040f, - 0.0025f, 0.0014f, 0.0008f, 0.00045f, 0.00030f, 0.00017f, 0.00008f, 0.00004f, - 0.00002f, 0.00001f, 0.000005f, 0f, 0f, 0f, 0f, 0f, + private static readonly int[] LossyQuantQ22 = [ + 0, 6710886, 4194304, 3355443, 2474639, 2097152, 1761608, 1426063, + 796918, 461373, 251658, 146801, 79692, 46137, 27263, 16777, + 10486, 5872, 3355, 1887, 1258, 713, 336, 168, + 84, 42, 21, 0, 0, 0, 0, 0, ]; - /// - /// Provides the lossless quant value. - /// - public static readonly float[] LosslessQuant = [ - 0f, 1.0f, 0.5f, 0.33f, 0.25f, 0.166f, 0.125f, 0.083f, - 0.0625f, 0.03125f, 0.0156f, 7.874E-3f, 3.922E-3f, 1.957E-3f, 9.775E-4f, 4.885E-4f, - 2.442E-4f, 1.221E-4f, 6.104E-5f, 3.052E-5f, 1.526E-5f, 7.629E-6f, 3.815E-6f, 1.907E-6f, - 9.537E-7f, 4.768E-7f, 2.384E-7f, 0f, 0f, 0f, 0f, 0f, + /// Quantizer step sizes for the lossless (variable bit rate) core, Q22 fixed point. + private static readonly int[] LosslessQuantQ22 = [ + 0, 4194304, 2097152, 1384120, 1048576, 696254, 524288, 348127, + 262144, 131072, 65431, 33026, 16450, 8208, 4100, 2049, + 1024, 512, 256, 128, 64, 32, 16, 8, + 4, 2, 1, 0, 0, 0, 0, 0, ]; + /// Lossy-core quantizer step size indexed by the bit-allocation index. + public static readonly float[] LossyQuant = FromQ22(LossyQuantQ22); + + /// Lossless-core quantizer step size indexed by the bit-allocation index. + public static readonly float[] LosslessQuant = FromQ22(LosslessQuantQ22); + + private static float[] FromQ22(int[] q22) { + var result = new float[q22.Length]; + for (var i = 0; i < q22.Length; ++i) + result[i] = q22[i] / 4194304f; + return result; + } + private static short[][]? _adpcmVb; /// /// Gets the adpcm vb. diff --git a/Compression.Tests/Codecs/Dts/DtsForeignStreamTests.cs b/Compression.Tests/Codecs/Dts/DtsForeignStreamTests.cs new file mode 100644 index 000000000..1be917634 --- /dev/null +++ b/Compression.Tests/Codecs/Dts/DtsForeignStreamTests.cs @@ -0,0 +1,808 @@ +#pragma warning disable CS1591 +using System.IO.Compression; +using Codec.Dts; + +namespace Compression.Tests.Codecs.Dts; + +/// +/// Decodes DTS Coherent Acoustics core streams produced by libavcodec and compares the result +/// against libavcodec's own decode of the same bytes, sample by sample. +/// +/// The core has no dither and no other implementation-defined stage, so the two decoders have to +/// agree to within the rounding of the final 16-bit conversion — one least significant bit. Any +/// looser bound would hide the faults these streams exist to catch: an out-of-range table index +/// that killed every real stream outright, a filterbank modulation phase that put the signal in the +/// wrong sub-bands, a quantizer step table rounded to short decimals, and an interpolation filter +/// that restarted from silence once per frame. +/// +/// +[TestFixture] +public class DtsForeignStreamTests { + + /// Pink noise, 48 kHz stereo, 384 kbit/s, encoded by libavcodec. + private const string StereoPinkStream = + "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"; + + /// libavcodec's decode of : interleaved 16-bit PCM, deflated. + private const string StereoPinkReference = + "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" + + "9x35vnzf957vPZnxmfEnqBNUNpvNXuAucCu9K703mBvMh54PPb3je8fPds92v054nZDKpXJnPGc8pVQp9R0AmH5qLbGWqEPXoXM8" + + "OR64xu8Qd4jp2HTsPn4fv0PeIZuZzUxe4IUcLAc7i5/FhyBDkCQiiegGaO9p7xnrGuuC+wzelynGFGMFvYLuinfFM5VMRQXtHnOP" + + "OY4dxxY6FzpbeFp4+nj7eAvYAvZr9Gu0Hl4Pf2Q8MgrMAhP6mF3WLusceY5Mp9KpcrQczaPyqLnMXOYV9Yrq5OzkTPOmeU+4TrjS" + + "4tLitlTYUmGpY6ljHb2Obko2JfMS8hLO+s76miY3Tb4SfyX+cqXLlQ5UPVD1SpUrVer76vs2ezd7WzpbOpeTy8lD9iE7zhnn/Cju" + + "ozg+no+PY+PYKCANT8Nro7XRk/ZJe4priqtyXOW4q4lXE6t7q3tv0bfoV9wrbiQxknjseex5hDxCZnOzuVX4KjzNSrMea4+1YrVY" + + "faY9074G3Jfvy2WxshgaRIPbte3aNGIaAf1YZ7Wz+rH5sVkJq4TVIeoQf+p/6g20Btq39Lf0feu+NUwYJkCfOkgeJDflm/LZWrbW" + + "TGwm9kR6IpekS5Iz5oxlBjIDPfw9/Mel49IR/gif6c/0k0EyCM8dEB4QFmNiDPoKPIyHoX/NNDPNy/hlvACwR9+jx9lx9mXxsvgb" + + "8hsC57pN2Cacl8/Lpm7qG62N1hpljQJ9XQOuAafSKv2W9ZYFff8T7YlWbBQb16nr1HZsO9bB6mC9I70jcRiHybiMX6Ov0d/I38h7" + + "xb3ieHO8eVW4KiRryVp7ob2w1lxrntBP6I2txtYl/ZI+iB3EwjU+h55DawYA13AYt4xHx6NtlbbKWn4tvwZZg6wV14p3w3fDP+o/" + + "6qiFWluRrcgr7BW2l95LL2OWMc/R5+g6dZ16Vb+qZ1AZVEdfR18XVxfXtrhtcdUSqyVWrFSxUnmF8gr7qf3UWewsNtQ51LkncU9i" + + "f6Y/Y+EWPoYaQz2mH9NZepYOA9wSrUTrpnRT5ovzxQ5IB2S5vFz+gfiB2CXtkpaHlocOxQ7FKoYrhlsFWwUXhxaHrvuv+7OD2cEh" + + "yhBlB2CwPFiG8e9Yaiz1tvi2mG1kG62F1sIJ6YQEfVt1s7rpUl3qzOjMKPSVA5WBSr6er49GRiMwzrZpm+5h9DAmYBOwNEeaA8Z5" + + "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" + + "tlpblRRJ2apv1SNoBL1KX6UH64P1ZkIz4afwT2GZl/mQElKGmEPMA9IBCdbFHkYfRpPNZDOiR3RYNl4vrBeexZ7FirQi7d+xf8e+" + + "0L/QQ3JI7hntGX1Y/rB8bHhseHlseeyaeE1s5G/kb6g2VOG4SeGkcGexs7g6sjriU30qzL3DaljdEdsR+zr0dSgjmhE9xB/i4bsa" + + "BEqgjMIoS4QlAqx3fI19jd2l7lKrjdUGrG28rbytLI4tjiUqicoeY48B9yL0QxPKJ5RLqqTKiqzcEm4Ja621FtRn/8X/i88P54eh" + + "7TsNaBtrG1uqLlXv6ff0D4QPBBZwQb4gP5eeS9AnnuZP89XF6mJuLDc2s2xm2W5+N78kvCScFcgKdOY78/dK75W+H3w/qAiKsEZd" + + "o+4Ud4o91Z4qfG9ADagBWLcfy4/lK6oV1TnaHK071h2D703A9yBgvbC70d2oRdWioK+ZpExSrpvXTagV/Ez/TDdnmjM4gROMg3FA" + + "2/y9+b3pR/3oBeYC80h/pH+FfoVC/wvXy9v42ziMP2Hs+G/i30SBt8D7nvM9ZyqWilVBqiD/Cx7DPC0="; + + /// A 997 Hz tone, 48 kHz mono, 1411 kbit/s, encoded by libavcodec. + private const string ToneStream = + "f/6AAfw8dbA2wAE4AAHvg2////QAAAAAa1rWta1rWta1rWta1rWta1rWta0AAAAAS6kuXLly5cuXLly5cuXLly5cuXLly5cuXLly" + + "5YAAAP/6LgA/E/8uqA90T5MMQfS2cP4PAAAAAADsACGf/yTgBzbf6QCgnrG/elIAAAD//6//v7P/JJ/13B/9hB+rnIG3XAAAAAAB" + + "X//tIAB8x/wngBMcv7jeAeHBAAAAAAB7//YMABcf/sqABt2/93pA3+mAAAAAAHH/+BAAI3f+oqAFPD/qkoCJTQAAAAAAV//8ZAAS" + + "R/+OAAPr3/yXwHh0gAAAAAAv//t4AA7n/0MgAjN/9TIAOm0AAAAAADv//kgADPf/yyACjt/+aABM/4AAAAAAF//9CAAHf/+F8AEW" + + "f/lGABzRgAAAAAAt//8sAAm3/+ZAAdP//0aANneAAAAAAAn//dAAA+f/qHAAjt/7SoAOkIAAAAAAIf//kAAHf//0YAFj///EACkk" + + "gAAAAAAH//5cAAIX/71QAEWf/HRABt+AAAAAAB///9wABhf//SABGeAAGUAgfYAAAAAAAf/+qAAA3//LQAAZX/0+gAIpAAAAAAAX" + + "///4AATwAAHAAOagAD/AGn4AAAAAAAH//uwAAD//1H///h/9uX//RgAAAAAAFAAAHAAESAAFgADDQABkABZngAAA///7//8P//+v" + + "/9sP/+q//hR//SmAAAAAABAAACgAA6AAB/AAp4AAeoATK4AAAP///f//O///Z//gD//b3/5U//uRgAAAAAAQAABEAAMwAAqgAJEg" + + "AJ3AEKeAAAD///v//0///wf/5F//z3/+lz/6OQAAAAAADAAARAACwAAL0AB/oACkAA6qgAAA///7//9r//7n/+ef/8ef/r1/+UUA" + + "AAAAAA4AAFgAAogADZAAcKAAt0AM4gAAAP//+f//c//+l//qH/+9f/7d//g9AAAAAAAKAABYAAIwAA7wAGTgAMyAC46AAAD///v/" + + "/4v//n//7J//tr//AL/3hAAAAAAADAAAbAACCAAQMABawADXwApygAAA///3//+L//4v/+2//6w//wi/9mKys8oPWkQxV9/jwkgX" + + "SdB5Pn8y97/GPxHjz5DkCElFyTVdrDZAMuSAaSKO4b+5cRkd5rTx8efv8F0v+Ifv++Af/zS//054buf9UEn93M//OQf8dsAAhB/+" + + "HUAAFv03Gvrv9f5Be/z/V/6i//7lP/+NAABd/RRu/uFL/x+v/4UX/rrf/9Y//2xAAAz+7mX9rt//ZBP+rUf/eJ//bMAACb//8f5f" + + "v/95C/96+//GL/9E4AAjoAAA//+yf39u/p/7/7cb/zRv/9av/8Lf/+HAAA3+7s//v2//p7P/4Ef/jo//8b//ywAAlv+/6f8Nz//e" + + "U/+C///n7//bf//xAAAGfzrY/+PD/8Fr/+83/6WgABDf/+e//9n/4i3/T+H/7u//nz//6U//z2AAEP//hX9ovv/3Of/PJ//29/+n" + + "D//dP/+7P/+Sf/cr/3UH//Jf/7g4AAIP/+bgAAwAABJ/iCQABCX/2jwABB//ul//5b//1AAACoACbP+RXgAA9//E1//pIAAJYABy" + + "//+l/5yQAAqR/9tsAAnP/9ZP//q//9A//8WACz7/o5YAAUf/whgAGW///KAADj//UP+rmAATu//nGAAFp//YL//0P//JgABMgBE4" + + "/7GKAAQH/9poAANP/9igAAGAABn/tqMAF4X/5kf//4//4q//9mAALoAAW4AXdP+55AAMa//QWAAbv//lQAAlf//Mf8FHABqb/+zQ" + + "ABAH/+KwAB8gAAeAAJ4AGnP/wsoAB1//17gACo//4v//1wAAav/IEwAi4//wLAAK5//VX//e3/+3///QAB4x/8lWAAtH/9wH//uv" + + "/+hAAFo//8l/zgYAIVX/8BwAE2f/5J///N//wn//s4Ah+P/RZAAPH//kn//2AAAmv//awAAT/9OpACPV/+2MAA13/+g//+mgABX/" + + "/9CAJMD/0moADqv/6ggAFW//6J///n//7v/WTQAkM//x4AATr//10AAv3//Rf/9O//+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAf/6AAfw8dbA2wAE4AAHvg2////QAAAAAa1rWta1rWta1rWta1rWta1rWta0AAAAAS6kuXLly5cuXLly5cuXLly5c" + + "uXLly5cuXLly5YPS6/kXQ/7P4B4Rz8dpP/ueAOvNfi9+GT6sRW41DSeY2oHSDOO4ZWOnVfiPbOV//voAAPf//0P/+7AAAl//8GAA" + + "BL//yX//Lf/+4AABtAAB8AABT//uwAABP//0gAAY///gAAR0AALX//EAABEf//ZAADIAAKP//4oAAYf//DAACVAAISAAIIAAb3//" + + "pQABxAAE4AAA3//sf//nH//4AAA1gAA8AADwAALwAAAv/+ff/9X//7v//97//73//+v/+4P/9KgAAJ//+WAAOP//tf//uQABAf//" + + "sAAA1//rsAAGIABDf/+3f/7y//6z//6kAA4oAAVwAAfgACA//85///UAAEQAAjv///AAAB//6B//1z//qn/+vAAA2f/+kAAD1//0" + + "3//4X//1f//+gACo//8b///EAAeYABBf//1gADw//9x//9kAAMAAAjAAAi//7x//07//wD//aAAAOwACbAAB8AAD0AAR0AApX//6" + + "wABGf/+I//+z//r4AATP///QAAsAAGm//3Z//24AATP//3//+ff/+X//9r//47//un//fv/+3//+aAABn//9EAARv//mgABogADB" + + "AADGAADsAAg3//z///E//9B//7sAADr//lIAAPAABI//9b//+5//8UAAa3//5v/+uf/8bAAHn//7cAAWP//NQABh//9t//9Z//+k" + + "AAgP/+6P//6//+zAADr//egAAP///fgADFf/3B///J//4QAAWoAAOgACef/+4AADYAACsAAMn//yQAAZgABxAAM2AAIoAAFf//J/" + + "/7v//+CAAJf//+X//gv//1P//7//96AAD8AAAEAAPgAAgQAAdgAAF//8n///b//5oAA0QAA0AABcAABX//30AALoAACQACUAACT/" + + "/54AALgAATQAA6f/+EAAEPAANgAAKj///3//xP//7//+iAABJ//yMAADn/+2f//hf/9UAAAyAABkAADX//3wAAA///9//+qABVoH" + + "NP/xK1QBaEA4Tm+HMGAVbIG3TkMjHD6qBnNmnhmHihRr01nl8NUZ0ZZe//+oAAAP///z//hP//nQABrf//h//6kAAHP//xQABF//" + + "/i///9//+b//4L//0P//+P//zf/8z///IAAK4AAIP/+1gAAx///S///7//i7//yn//bwAAWAABiAABl//4D//n4ABRv//6AABXAA" + + "FUAAQ0AAPX//1f//Pf//o//0QAAGX//y4AAHAABHf/+e//+r///wAAUgAARgAAof/+gAAFt//8AAAoX//dv//j//9e//69//wj//" + + "uv/+wwAANf//qAADJ//5YAAGP//uwAAhf//N//7v//9gAAF3//z//9A//9p//7l///MAAOn//5//+EgAA/AADYAAAL//ff//R//8" + + "7//9K//77//pcAALQAADv/9qf//3//9EAAJ///1oABCwAAHf/+DAAAn//sgAAH3//7AABNgADsAABT//4j//zIAADgABnAAAi//0" + + "d//3IAAHwAABP/9KgAApAAAt//pb//2n//Sv//Df/87AAEJ//v3//pn//Qv//m//5b//7kAAHIAAOf/+OgAAsAACgAACqAASAAAf" + + "P//u//+SAAAG///3//34AAJQAAav/+4gABIAANX//7cAAJH//lv/+Q//9VAABKAAL8AAF3//0f/+Xf/8ZAAJ9//gj//8X//jgAAQ" + + "AAB+//4KAAXz/+7IABIv/7uAABe//4wAAEoAAKAAAdgAArAABH//8r///4AAJgAByQACFf//w//7B//hT//HX//mgAAtAAA8AADv" + + "//5gAArIAAHf/9MgABW//6N//5UAAYwAARAAAJgAB6//8N//2gAAZv//Qv//+gAAyAAAJ//+j//pAAAWv//QgADkAAGp//9j//j/" + + "//ff//egAAXAABn//yQAAPwAA7//+mAACJ//9d//18AAIn//ugAArAABy//8J//9L//04AAQAABu//+AAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAf/6AAfw8dbA2wAE4AAHvg2////QAAAAAa1rWta1rWta1rWta1rWta1rWta0AAAAAS6kuXLly5cuX" + + "Lly5cuXLly5cuXLly5cuXLly5fwnwAD9sg1eP+DHyAp10GernwLLgGclGLt4hxz8lBYstPPsPedk2hQlHkJiIlF//00AAR4AAWgA" + + "DCgAC+AABMAAMsAAFf//Iv/8wAAA4//zn///f//cwAAVf//j//8GAAH///68AASQAAsf//x//9x///WAADgAADwAA1AAASf//oAA" + + "H3//+z//SYAA6QACo//8PAAEaAAQkAAYAAAmwAAQgAA6AAKkAAPwAABwACP///+///JAAAL//4gAAO///JgAAY//9+//3yAAJr//" + + "1P//bQAAM///y///aAALQAAfn//Yf//0f/8jAAISAAXEAALoAAYwAAPgAID//8R//2b//tX//igAAuf/9k//0H//7wAAD4ABJAAB" + + "af/+dAABYAAKcAAIAAAvf/8pAADYAAE8AACUAAQgABVf/99//+z//59//9gAAMX//7v/+m///u///R//zr//xf/+u///N//6C//4" + + "aAAJr//1v//vAAAtf/6sAACt//1///woABNAAC/f//tAAA3//usAA3f//RgAA2AACKAACMAAAIAALIAARQAARAADY//6EAAD///5" + + "f//9AABnf//5AADUAAFX//en//iP//+//41AAD2AAJwAABP/++P//ygACa//1x//ncAAQH//wQACRAAEv//+YAAIP///oAAWv//p" + + "gADS//4MAAdL//2gAAlf/9lAAEx//+eAAJH//tQAAPP//p//+XAADJ//60AAuYAAFQAB7f/+qAAE5///X//woAAUf//cgAHTAAJH" + + "//7b//In/+uP/+rgACtAAGsAAG///eIAAVP//lAABC//9L//6gAAcf//6QAA+f/9W//7GAAEn//wP//7QAA7gACXAAAAAAOAAAD/" + + "//X///9AAAfAAB0AAGb//xwAASAADvf/+2//9v//9sAAPwABZv//Z///v//7WAAHr//3gAAKwACRgADtAAF+AALT///X//T//+4g" + + "AAkAACIDIp33/GwD1uwYSH+/G3AjnmC6kL3zjaiOUySY2RL/8VHjyQGI2KoTqvboRu+k///c//8b//5T//+wAAO//96f//0//9UA" + + "AC0AAZf//YgAANgADm//+8AANYAAE3//8v/+of//hAACKAAVz//1oABvAABXAABVAADV//0///xP//nf//YAACg//+x//sT//pX/" + + "/fAAB9AAAXAACr//0z//z//+Sv/9m///gAAHuAADwAAUgAAPAAASAABRAAHgAAjwAAZgAAVv//Q//6kAABb//1YAAYYAA3QAAB//" + + "+w//8l//4T//3f//yAAB5f/9M//86AANsAAP///vP/+6f/79AABmAAJoAAQIAAhQABOAADI///2AAEgAALoAAbwAAGgAB0//9R//" + + "ywAAdwAAGv/+Cf/6j//3t//9gAAYoABAQAAqf//5//4n//ygAAPH//uwAAqAAAjAAAUAAOAAATQAAsgAAsAACaAAMH//0L//cv//" + + "6gAETf/6K//5QAAT0AAIv//4v//egAC7//5GAALr//b3//Mf/+Vf//p//6V//0cAAH3//BQAAEgAAWAAEd//5YAAlf//8v//LAAF" + + "NAAEP//4v//+3//sv/91gAAk//86AAF///9IAASQAA2AAAv//80AAKr//44AAcP/+3f/92//8L//13//0YAAev//gf//s///z//0" + + "QAAPf//hwAABf/7kAAHn//dQAAZH/94gAA4//8BAAFqAAEYAALgAAhAACfgABH//5b//33//rYAA/AACKf/6M//ur//dv//44ACU" + + "QABrAACb//68AAH///0QAAwwABb//8cAAHgAAJoAAZH//kf//VAADvAAHF//4kAAZ4AACv//if/+aAAL7//0H///P//0gAAff/97" + + "AAEf//y0AAu///FwAAzgADe//8QAAJQAAOIABE///w///7AAAB//10AADIAAcwABMAACgAAB8AAJb//83//6wACVf/+AAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/6AAfw8dbA2wAE4AAHvg2////QAAAAAa1rWta1rWta1rWta1rWta1rWta0AAAAA" + + "S6kuXLly5cuXLly5cuXLly5cuXLly5cuXLly5YFEjgWa3+9+pAtdMCrZH3r8oGQtAUcnxfehWtZELoTWNZiy7pyhK9Ox4N5YK6Z/" + + "/lwAAc3//MAABTf/+vAAAF//+///ygAAIwAB3gAEP//85//8r//z3//XQAAz//84//8WAAKf//mYAAGgABAf/+uAAA9//9X//+oA" + + "BEP/+NAABf//6j//+H//lgAATP/+g//9TAAAKAAA///mwAA+AAAV///YAAHGAABMAAE4AA0gAAef/+j//2Z//2wAABv//RwAAb//" + + "/C//5MAAFn//xX//vAABI//+fAACh//+b//yX//aP/+oAABgAAC1//oX//33//3P/9wf/78///SAADf//rAAAmAAA1f/+W//8YAA" + + "CoAAfwAAov/+k//91AADB//57//vv//r///jAAB5AAHL//5MAAgP/+ggAAY//+NAAB5///0AAH4AAM///ugAB9AADyAAO7//9QAA" + + "OgAB4gADP//7YAAH3//t4ABBQAAagAA9//7L//qj//RAAAbAABU//70//9T//tf//5H//dAAAqf//jAAN2AAGUAAEv//WwAAngAF" + + "lAAEmAACv//oAAAf///1gAACAAAOAABH//sIAAqwABQgACbAADJ//8gAAAv//xAADAf/+pAABEAAOv//lX//0v/+0//8s//8wAAK" + + "z//mYAAKv//BgAB1AALF//psAACH//0P//rgAAcAAAV//4j//qAAAT//7egAHM//1uAAOT//DAAAJgACD//+0///sAAJMAAef//5" + + "f/9YgAClAAA9//xj//If//AgAAsAAEIAAISAAPQAAFAAAMgABLAAAYAACsAAHb//8P//EgAAk//8r//+mAAFEAAEQAAZf//TAAAT" + + "AADuAAHAAAVQAAFP//wf//t//9YAAJIAAA//+xv//5gAAw//6n//4MAAeQAADgAA1gABmAAE+AAZj//vn//HgAATf/+7///R//6j" + + "//rIAAuQABBAABU//9h70qEDbLQJtnfedKgdszBJmN7zDoD/zQcYiZDQmMbOQCaBBJYXVl+r4KF/JTdvf/+LAAJaAAM4AAb3//tP" + + "//1AABUAAAaAAEcAAcIAAXP//PAAAk///KAAHMAAHAABMAAAaf/+F//+x//2L//poAAHP//qAAE5AABZ//9gAAmwAAdv/+D//+JA" + + "AFp//4H//vQAAhwAAT///1//5z//9H//sgAAyv//n//96//79//2j//kAABSf/9egAAh///r//5IAAGP//wf/+HgAAuAADcAAIcA" + + "AB///YP/+n//+vAAAAAAGn//mwABUv/+UgABLAAC0AAAL//5n//lQAA5gAA6AAOmAAGgAAPX//3AABFgAAsAAGf//7z//8AAAM//" + + "/M//7R//6+AAOT//0AAAGv//MAAA8///mAAUwAAoQAAbwABIf/8J//1F//vQAAHwAAbwAAPAACH//1///xUAADYAAhf//ef/99AA" + + "ASAAPkAAKoAAHP//EAABB//9yAAAf//2H//rv/+RgACr//8yAAIsAACwAAz///lAADF//5CAALf//ov//xgACrAAAy//63//+0AA" + + "M///mf//o//8I//7+AAAEABDn//3v//UgACr//5x//8v//zIAA6QAA4AADf//5yAAEwAAdn//yAAAO///aAAGp//pf//6YAAvP//" + + "bf//P//98AAPL//egAARP/+xAACx//6UAAMH//zoABMP/+0gACWAABp//0QAAU3/+/gAAKAACS//8L//yUAARgABkQABqf/6Q//x" + + "7//4EAA5YABcP//1gAA3//+4AAK0AAagAASf/+p//7h//4IAAEUAAJv//qf//x///Z//+5//1gAABAABMQAASAAAuAABD//1z//4" + + "X//BgABPAAAq///WAANf//93//6P//sAADQ//+uAAAn//fYAADgAABf/9y//+QAAHcAAIn//h//+5AABGAAKyAALsAACwAAp///i" + + "//+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/6AAfw8dbA2wAE4AAHvg2////QAAAAAa1rWta1rWta1rWta1rWt" + + "a1rWta0AAAAAS6kuXLly5cuXLly5cuXLly5cuXLly5cuXLly5YIpsfeXugiKJBApX7y5QEiKQHiUvebuNDTTAHXDLj5tqsrH3vup" + + "mExNmnl90oH//sP//2YAAG//+y//+rAAB3//6UAAZwAA5v//1//8ZAAEv//vIAARH//cQAA5gABrAAKQAAAr//QP/+oP/9pgAAP/" + + "/99//8UAAKf//3P/84gABd//+0AAH7//0P//uAAAGgABCAAE4AANf//y4AAq//+gAAA7AAKAAATkAAAQAA9f/+ggACc//6AAAXwA" + + "AA3//ywAAOgADNAAAT//yD//u3//mv/+S//+UAAE2AAKX//P3//aP//xf/7y//8oAABn//5gAAkgACgAAEPAAIUAADH//5wAAnv/" + + "9bgABz//1j//8T//8IAALP//yAACR//9Z//4j//7AAAO///3f/69AAF1//xT//koAAE//8S///oAADv///3//xQAAAQAAdf//f//" + + "8D//9oAAA3//+AAAMgACH//7////UAAXwAAXv/+s//88///d//skAAdAAAHP/+5gAA9AABaAACMAAG3//nQABX//8+AAB5//8EAA" + + "PIAAYf/+8//6pAAKL//+b//+3//X////f/+///+2AAEIAAJ4AAIgABSf/9z//2n//3QAANgAAcQAAfgACO//7eAAF7//kn//WAAB" + + "RAAAR//+B//9UAAG4AABAAA9gABl//8cAAJD//34AAbP/+zAAE+//+R///T//i///UQAD6f/5LAAID//qUAA+AAATQABfgADw//7" + + "R//0f//yn//7P//vAAD6//71//sX//84AAqQADBgAEsAAE6AAHgAAbQAADP//ngAAkAAAAAAG0AAEP//+AAAf//62//6iAAAYAAR" + + "f//FwAAo//7oAAFkAANf//jP//+///6///8AACR//+D//ZP//xAABdAABd//4Z//xIAALQAA0gAAGgAC7AAMiAALj//v3//TAAA8" + + "f//G//7x//60AAQQAAfgABwAAAT//9wCZroDe7PvRfwUOYgZgp968mCqMkC5T84JH27PF+VwNnsNu4UE3uKmNDLoXJJuf/+z///j" + + "//1r//uwABLQABcf/+u//7f//+L//z3//1wABJgAEs//9h//23//3gABWP//+//8///9r//xr//z4AA/P//R//9F///gAACgAAno" + + "AABAAA5f//h///x//9IAAcwABPf//hgAAv///IAAPoAAGv//Zf/+Nf//1AAEQAABQAAQP//Vf//Af//SAAC5//7n//qAAAsAAA0/" + + "/+zAAAJ//s0AAGf//pv/+6AAAJAADb//9YAAMoAAPf//LAACO///x//zv//0YABMAAAcAAEs///D//0v//uP/+1QAAN///D//6p/" + + "/y///6gAAGwAAcAAB8//5kAAIIAACP//agABBgAE1AAJQAAcgAAnoAAtv//pgAEx//40AAFwAAHf//+///Rf/6bAAFsAAEv//kf/" + + "/Lf//9///4AAE0AAGn//04AAF//++//+9//6gAAbb//dH//dwAACf/+eAAFCAAJ0AAEn//xv//ogABa//9SAALD//uIAAUgAAD//" + + "8IAAC2AAHX//zX/+bv/+v///f//9KAAREAA5oAA2AACvgAF/AAFB//6gAAGP//twAA2f//+AADT//67//3v///AAD9AADUAAD9//" + + "pf//24AAMQAC0//88AAHb//sAAAMv/+e//+Bf/9CAANh//ooAAKQAAEAABhAACy//4YAAE///ooAAmwAA3gABZ///r//2b//p3//" + + "Pv/8Lf/6CAABCAAOQABUQAA7P//VAAAL//9yAAS8AAGIAAmP/+2f/+nAAB3//6v//oYAAEwAAYgABp//7gAAHcAAdX//JwAAA///" + + "J///+AAKf//23//nAAACAAAmAABl//+QAAUH//ZQAAr///lAAEL//ssAAz4AAvgAAQf//S//+N//s4AAigAAF//+wf/+9//+N//7" + + "3//zn//3gAAlf/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/6AAfw8dbA2wAE4AAHvg2////QAAAAAa1rWta1r" + + "Wta1rWta1rWta1rWta0AAAAAS6kuXLly5cuXLly5cuXLly5cuXLly5cuXLly5fvdTwWMuAUv298xIC5I0CTo3vwSwYCP9NJRpI4S" + + "55KvlJL1PTBXUeKcFh9qt4GAALAAAKv//EwABrgAAH//9GAAPr//nAAA3wAAOgAFS//70AAE7//bAABJQACnf/+pAAAV//skAAZo" + + "ABTgAAxf/9v//8kAAFf//hwAARf/+0gADSAAGcAAD///7P//IwAAl//+aAAFwAAWcAAaP//2AABZf/+tAACGAAAUAAkwABCgAA4A" + + "ACBAAHWAAHAAASgAAmf//Nf//l//zoAADH//tAAAvP/+DAAGs///t//7f//8IABSAACYgABNAAG8AAE3//sIAAWwAAw//90//7AA" + + "AN8AAMP//dP/9zgABb//4MAABP///gAAQv/+r///zAAAIAAG3//0AAARf//lgAA9//4d//pf//+4AAAgAAPAABnAAAL//qj//5YA" + + "AxAAB6AAEAAAF0AAD8AASP//3P/+fAACyAAB+AAHT//7P//rAABF//+u//4f//7AAAZ4AAeP/9+f/+SAACv//1oAAWQAAwf///gA" + + "DI//+b//9sAATX//SP//cAAAHAAAWAAFX//2wAAMwAAogACpAADf//6H//3P//+AABF///E///QAAaP//jwAA0QAAf///G///x//" + + "5kAANP//mQAA4gAArAALF//y8AAfoAAZAAALf/+pAAIR//2H///4ABEP/9ggAAy//6YAABH//OoABzP/+nAACY//yEAAWUAARP//" + + "nAAAMgAAP///1//4wAAIgAAnAAAqf/6g//6mAABwAALAABygACeAADUAABKAAAX//2IAAeAAAaf//EAAAl//1wAATX//2f//zgAB" + + "W//8L//2sAALAAAqv/+SAAEaAAC1//74AAN//+6AAAVAAEi//3OAAKwAAUn/+twABJ//8sAAH7//7YAAW3//WP//xgAAe//4Z//0" + + "f//eoAAiv//Df/+7AAJiAASL//74AANf//yf//6AAPmA/nz39twMdcwGsAfAhQBm9YArxr4KjTskldxH5Vxpud0l9r9YGxqQDwO2" + + "tOdC//9DAAB9//6L//lH//xf/+9AAAgAAG5//+8AAh4AANwAAmgACEAAFWAAIf//5v/+dQAAmf//AAABaAAFP//7X//2QAAof/+b" + + "AABh//9YAAUP//mv//Kf//h//x5//1gAAKX/+7QAAN//83AAAn//2///+P//7QABJ//+lAACp//xr//xn//Z///OAACv///+AAJk" + + "AAVn/+ygABX///r//9MAAQkAAPH//8gAAF///8AAB2AAUT//1wAAWv//pf/9rAABp//44AAaX//HAABx///wAAC8AABv//8n//0f" + + "//OgAB6AAFmAAEv//rX///QACggACsAAAsAAFwAAxAAApAAB9gADc//74AATkAAawAABgACpf//bAAIL//8f//jv//9//88f/+M/" + + "/75//8L//jQAARv//GgAA1//87//+EAAKf//H//9jgADNAAFv//0z//vgAAfAACb///wAAEb///sAAJv//dwAAnf/8XAACyAACb/" + + "/vP//6QABeAAA0//7B//wQAAN3//yv/+z//9w//8WAAQMAAEP//Ef//nf//hAABCAARn//t4ABFwAAy///YAACuAABD//iIAAcgA" + + "Bzf//O///GAALEAAYYABjv/+fAAFT//8gAANX//nX//TAABRgAEnAADiAAAEAAW//98wABu//6mAAMiAAF4AATP//aP/+3gAAD//" + + "7qAADsAABf/+0f/7lgAGMAAGuAAin//zAAAkQACGAADcAAHV//5wAAJ///4gAAz//9JAAAcAAFIAAWAAAxAAALAADNAAAkAAAD//" + + "xYAAbv//bf/9YAACMAAIkAAC3//FwADGf//OAADQAALX//i//+9v/+MgAAo//4KAAIYAAB4AAhQAAQAACP//5AAAFf//zoAAmgAB" + + "GAAAM//9EAAEj//9gAAlQAAz//+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/6AAfw8dbA2wAE4AAHvg2////QA" + + "AAAAa1rWta1rWta1rWta1rWta1rWta0AAAAAS6kuXLly5cuXLly5cuXLly5cuXLly5cuXLly5YNR5QEKr/CSRBtSCAXcb4bPAOAf" + + "ABpzWp2eeMZpnr8a45zDyhvss0A3lb0eZNoAAAUAADwAANP/9tf/+2AAGD//0cAAqAAAIf/+2f/+E//4gAACgAAT4AAyP//+f/9t" + + "//zaAAIQAAA///Qv/+zAAALAAAiAAIL//3P//+AAA9AADr//9eAADYAAIn//VAABF///FAAAqAACEAAJn/+YQAAXf//R//+T//xM" + + "AAngAAbAAA0AAEeAAGUAAAv//8n//mQACAf/8yAACR//5H//63//+gAB0f/+U//5yAAOkAAK3//P///agAF9//5v//zb//yH//v/" + + "/9n//8BAAEQAAPMAAXQAAPv//HAACL///4AAWcAAM3//5gABrAAAUAAE9//pQAAA///mAABB//70//yl//oT//cX/+/v/9IAADq/" + + "/8iAACoAAe///IwAANgABoAACaAARL//4///Tf/+z//83///V//4T//lP//ZAAAk//7t//+0AAHsAASoAAPf/+VAAC0AAC5//98A" + + "ADgAA3f/9/gABA//uZ//7b//0f//dAAAnf/8JAAHuAADwAAEP//BQABQgAAu//8iAANoAAXIABZP//cf//9//8sAAI///toAA9v/" + + "+S//9YAAKD//+MAAK//+5QAAff/6vAABz//9H//hv//y///b//+y///n//2QAAQ///tP//+///k//5H//yUAAfP//eAABEf//wAA" + + "B6AAIQAAEn//agAAJgAFNAAB2AAD3//+QAANgACgf/5n//u4AAJgAATAACCAACG///B//1f//zn//6AAAGv/+3f/8y//+R//8z//" + + "tn//t//////9q//7///qH//4YABbQAA5///kAAAV//xUAAS3//1AAAZf//nAABGAACIAAHv//uP//wgAHU//75//u///zf//4gAC" + + "FAABo//7mAAFP//9X//eAAAX///1//9J//+3//1n//lAAAQf//QAAKB8R9cHLmgAM+Pi6lg6vs/8Vv8cXoHepuON9cCNFvNxOwxb" + + "JiQXJ5sD9+UXsiOmf//w//8///2n//u///DgAAlgABC//7sAABX//3gAAXv/+8///p//5YAAO3//5YAALf//cAAAI//0R//mgAAO" + + "H//PwAAAgABb///AAAHz//vYAAs///QgABk//3MAAHL//k4AAEf//zgAC8AADj//5b//+v//MQAAjAAC7//60AAFL//toAADv/+w" + + "//9EAAGcAAMwAAK///gv/+k//4yAAAr//+8AAOoABDQAAFgABRAABV//3UAAJ3//VQAAS///BAAGF//+P//eQAAlwABuAAEMAAFl" + + "//7IAAHYAAawABhAAD9//+OAAFL//3IAA5f/+iAAAn//+F//58AAMIAA9gACuAAENAAFb//8D//6QAA4v//m//+8//+J//4P//y4" + + "AAB//+0f/9H//8sAAAT//vf/+rv//Of//lAACWAAQ4AAKH/+X///NAADEAADd//6EAAfgAAoAABU//9u//87//wX//q///uAACs/" + + "/9rAADEAAer//7YABYv//s//+MAAAGAANP//vgAAlP//Mf/+d//9v//6L//5IAAJgAB1//99//8sAAI0AAZv//rgAAqf//xAABJ/" + + "/3UAAOgAAAP/9m//91AAGj///T//3v//dwADXf/+E//96AAMoAAEwAAiv/+DgADw//3UAAdH//YYACB//8dAAH0//z9//64AAJv/" + + "/Q///OgAEoAAGKAAIkAAYX/97v/+mAAGxAAOqAAVIAAD///Z//8F///hAACwAAAb//sIAAfAABAAAAx//++AAGP//vX//M//9t//" + + "9PAABWAAFX//9P///P//y//8B//5KAAS3//x///Mf//xAACT//yUAAXf//n4AAqgAACf//cAAE4AACkAAoIAAgv//zAABM//5Z//" + + "5f//0YAAmf/9cAAAhAAHcAAAj//5v//1P/+o//+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/6AAfw8dbA2wAE4" + + "AAHvg2////QAAAAAa1rWta1rWta1rWta1rWta1rWta0AAAAAS6kuXLly5cuXLly5cuXLly5cuXLly5cuXLly5f+7wvkNOA89U/ya" + + "J8nocHwpX9qQPltHPL4Tu1NfmVzx5G79vLU9DgdPEfCs/Kd//xT//4///Dv/+5///XAADf//90AAWP//xv//m//+EAABZ//2YAAR" + + "H//kP//h///h//78AAJQAAUX//rwAAjgAAL//8EAAVH//9X//8v//u//96//+6AABX//1//+zgABV//+KAAG2AAOgAAD4AAJQAET" + + "//8Y//9X///QAAL4ABVwABzAACCAACv//8MAAFP//1gABYAACWAAGIAAGAAATYAAgP/+ggAAO//6j//tQAAP//+0QABQ///KAAIc" + + "AAIsAAHwAACQABdgAB6//7N//7QAAkH//G//+2f/8EAAF1//7b///4ABH//+7//+g//6R//8z//03//Jv/86//7o//zAAAGMAAWf" + + "//tf//2gABCAAA+AAFr//3QABEP//h///rAAHOAAGz//9oAAgQACDAAHqAAAD///MAAUv//bQAA4f/8pAAEV//8cAAJ3//swAARg" + + "ABM//40AAHIAAPAAACQABF//9r///8AAQX//soAACv/9w//++//3T///EAACP//iP//bf/+tAAGf//5UAAEoAAHv/+a//5jAAIeA" + + "ARoAAiX/+yv/82f/9SAABf//8b//ngAAdwAAzgAATAACN//74AATYABc//9mAACq//2z//7MAAAn//tf//A///r//5+AAEj//Hv/" + + "/vgAAzf/+bAAA7//xMAAkoAAEv//3///N//y3//3T//iAAATAABGf/4S//5gAASMAAvIAAB//9E//6z//0uAAAn//6wAATv//QgA" + + "CV///0AAAIAAJP//hv/9sgABHAAFD//24AAIAAAkP//vgABJ//+cAAIb//6gAAFQAATAABOAAEF//7IAAFoAAtP//+//9AAAOCAA" + + "Qr//6wAAfgABlgAEbAAAwAAJ8AAC4AAeP/9lf/74///QAALUAANIABeQAAS//+IAACID73v+gaPzofgdDIAFGV86waIwQ/pKr+qR" + + "s3fWnWEQc2XyC8C/us9G/Iji3Igp///Y//hD/8aP/h2X8VxPoID+tZm2RssAALkAAYQAOAgAUagHdCAZecBKbENNAwAAlv/9If/g" + + "h/9Cr/phb+BkP6hTvJf8f/+kAAJSAB0QAFgQBDFQEhjgLhOCJ7SAAAr//5//7Iv/i1/8Td/sX7/Lf73V9oAAaAAAtAATwABMaALb" + + "UA2SgCJ+wZqa//94//zx/+3r/6fv/Tev8Xsf2cF+Y8T//+oAACAAD4QAPcACU3ALOaAcF8FKmAAAI///3f/1I/+6R/3I3/Rp/+Gl" + + "/rSMAAAIAAEkAAxgACPwAgAACVpgF/4BF1d//97//f//8if/w6f+Ix/2EL/mfH7n0YAAZAAD1gANwAApyAGuUAg5oBTawPSU///t" + + "AAAv//QD/88n/k1/94g/6e2/C49//rX//uYACKwAHmABiuAHciAS08Da4H//Gf//O//6l//Rn/6Av/ho/+ybPyS4AACP//9AAAgo" + + "AB84AWqABtNgEZsAyHGAAEv//63/9U//2Y/+sU/5HN/t/38384AAYAAAygAIvAAimAFC0AZ8IA/BQLqCf/9rAAHN//oD/9tf/s/v" + + "+by/714/Rhh//y4AAaAAB5QAGEgBJhAF4QAPBICvRf//WgAAj//4F//sH/7tT/no3/CRv1F2f/5nAAWEAAaUACx4ARXwBdQADlIA" + + "py5//1X//uX/9/f/4Jf+39/6PV/xYv9Yuv//zgAAWgALuAAniAEikAVcAA2vAKDPf/+c///n//qH/+BX/t2/+nQf8X+/Xut//8T/" + + "/mQADOAAHPABG9AFYGANsoCdAf//0gAA///1q//iP/7n3/qGn/JWv2Jk//+5AAHwAAD8AB8QAQjABVQADW8AmyZ///wAAQf/+JP/" + + "24f+8Y/6nf/yVj9lfoABIQAAKgAIcAAeoAEOQAVLIA09gJm+//+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + /// libavcodec's decode of : interleaved 16-bit PCM, deflated. + private const string ToneReference = + "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" + + "FWfw/wPgd+rS"; + + /// Six distinct tones, 48 kHz 5.1, 768 kbit/s, encoded by libavcodec. + private const string SurroundStream = + "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" + + "FupeMzzto1/g3m9a4uYUO/pG7yf205MHvRmVF6l40M5UYNKQbNqsIZyAGeyAcT1GWmhoN+0VpSXdzLKw6rkIh1o6DXJ5R22j/mgD" + + "5UsyLetGHirg13N4q+cfcidvKM0lS1ED+/+EifPGejo40uChmGkr41X0J56iXZ0CJcte1ExR2C5dzKw+dan4+ubP/2a7ltQh4UPY" + + "oxLs1X5oI6mCjEuzVf7vbNqfRk0pKkpXq6fRmz7f9Pvp9a7b2/V59Prut2d6vavX+/lJMm+n1VVdnb4+n0Sk29vp7lBGrNuc3urD" + + "3dhfFzq+aXpgRX46iYXR1tDkgBmy9d5Aiqo4/njd59Rw5KoYYR5DyN4lveoOKcUWKs5C7EyhZ5uJRCZDzEuOnUN98HDC2KiIfGRv" + + "YG6xfFpGwSaINFF3zxP9RB8lEwLeSKlzrcca9/ofsuZyRJwj89FCvWu3HcI0sXY9Egur2N8a1mzs1CesZEls6EFWMRe8R1gd/QOs" + + "GQKslCezemdwSwHvZcbm9aGOfUWgUcJyiD7ph+Cp0tsTXtA4lwzULN68Ak3tc6T3MuyZ0eQKlo68vVyA7DDyjxkd95k+FELYl020" + + "lDrCUIrVXhj1NU+hGfZ2gKwOIqusUZZccPurH9s/Vam7/v/8Vnbl0hfnAlf/+A=="; + + /// libavcodec's decode of : interleaved 16-bit PCM, deflated. + private const string SurroundReference = + "eNrt2necFUXaOPrqdLr7nNNdQxYlGAZEEMYsCipDEJfsgqASTAioq5LDugqYyIgBFRAToMCCIkkljWQEAUEJ4qASXILAVPc53adP" + + "6rpP9zg+8777272f+8+99w+Hz3Aem57u6uqqp576OoT8+fXn159ff379+fXn159ff379+fX//ZfwZ/xfY/H/x7H0/2Is/z+Ihf8S" + + "K4Tz/3Nc/vnfY+GPdxP5LzH5D3H53QhR/y0Ovv5zrP2XmJB/j/WwPRUx+b+No/8rJn/E5a0M/o79r7ii/fEwFv5HLPyv2Pi998vj" + + "/3m84mfNSiO/Ig7uQf8tLm9DQaX2FPz+6cN3lX+LOQ/iqv8hrvb7k//vuHqluMb/iMU/4poQ+/+HuNbvcdCOi/4tLm9f7d+fKfi+" + + "+I+Y80v+6IcgDo6Wx3VIea8FZ9b9PQ5aUu+P2IfYD8+X4LM+yYf9LEN8aaX4sjAO5kSeXw7fQdsk+LwiPO7DWXleGB7Pw1l53iBs" + + "fQ6+87xheP0cRHl+ZRhnefBfjcI2ZHgW4qtIcL3yuDHEMsQZiJuE8zDN0xBfHc6l8rgpEcLjHlypCJ5C+j2+Jpz95fG1cLbPy+Pr" + + "YCZlefCzOX4DjHoPoiz8uRFGqxsezfKbYPQ54V2zvDmMpiDmEN8CcQo+BbjCrTCagtaL0L6WcDx4vqCtt8GoDPopAvEdMNKDOaBD" + + "3ApmTAG0NQZxa2hDdWifAXEbEownBa6W4e2gb0z4twKI20PLIjCLq0B8F9xVhNiEuAO0MsfV8DqdSPBEEXiKLO9Cgh5T4EpZ3i3s" + + "fxl6I8vvJkFvB32R492hXUGLg7/vITx8kqD/e5Gg9wkJnvi+sDd52Le94Z4piD24Wl+4iwOxC/GD8CwuxA7ED8MTpuEzCd/9Ic6E" + + "MecDfo8TEA+C1gbXS8A9ngiP5yAWyJNhy8vjwdDyHMQ2tG8o9E0QW9DuEdC24PoMnmcUCe7PeRk859/huRz4uQsQ/wOu4sK/X4C+" + + "GAt9kuJaGD8PrXd5jFgQvxiOBYMk4fwJ0AMZHrxLhUwOZ0HQ4wqZFs6OqvCtkBnhrKkBb0Mhr4frVk0YFQp5C85R4e3pEM+CVkrw" + + "5kSI34Hri/A8aWjHe/C3AMcciOeRIBKJDfFHv68GFyBe9HvfnoN4KfSJDc8YHF8Gb9mG48H5K2Ek2HClBLTnc4iD/nAgXgsjJrh2" + + "0P4NcH8PPjPwjJvg/sHYyML3tvBZdIg1spMEoyEKPaaTPdC2CLyPIDvvD3sjDr0dIwch1mBEivB9BGIVjovQlp+IG/5sEB8PW6yG" + + "GfZf4bwO7muS38IRL8GZBikL2yDCFeIkAdcKskKSR4kHbQ5yQhLakINMGbzfJLREEIJ5FLwPmUSEgnCm5uCZY0I0HB3BGKJCkAf8" + + "MItUh9ggQZYRSG0hzwvCVVgi9YSgJVqYGa4QUhDHwtWxkZCAc4zweZsJZbx6uPrEyPXCBYhVuE6MNBdseNNyePw2+Nnq8LQinN8G" + + "YiN8Yyq5S/Cg5Tx8r12ELJwZ5DqR9BBy4fGgN+6D4xKc7cFzPgDtkeCaSZhlj0IchZFkwdM8ITjhHGcQD4G2VYNrn4dzRglu2IYL" + + "8LPPCmloAwnHwYsQBzMsyACT4V4ajIZsMD6FYOSdh6uo5C1BgLf1Gw/e91wh+PtM+M7mC0HLT8HZOlksaJBLzoaVwWdC8OYS0PsR" + + "8oUQvM3geRRSIsgQ5+GZI2QbnB88Ywz6dLdAwvdbDY4cEOKwhuXg+hL5EdpmQbt0+NfjcL5Igpzj8bNCMKd1EowIS5DCsUngfmkh" + + "QoL3L0JMRB36I6hSbK6JIjnNg0yZ5FTM8VPhcYfXgmLRgTjIQPXFNA/mQZANrhRTPMiOeXj6ItHmwVwIMtbNcI4SjnuP3yEGsyIf" + + "Zqz2YhbuGuRBh3eDewV1QBaudq+ohHVGHp7iITEY8QRaz/hjohSuh1nINEPFSDiqcnD879C2IBcFb+8FsXxVi0D7p8J9g/ccvJuZ" + + "ohPmOQpz5V0xCXfM85pw1Y+hPcEqchHceZkYZGaPB1nxS/jZU3C8JhzZLFYnwboRrETfiAI5x4N2J/kBUQ2zkQLHf4Z+i4QZ2uGn" + + "RY3IYdZ2uQ3H5bCnHZ4TL4IaIhM+e0QK8lA+zARUovCMWR6s3bWloFILMiWs3VIVmCFemDmaSmo4T4O1pjmcE7w9A+7XGo4Hebtq" + + "sO7ANb2wzWneU5LDVboA4ockMZz7cfjXJyQxzIvB2jdScsP8rMI546UgNwb38PgUKeiTGAmyxZtSMJ8ovD2LfyClwxbnICMukRLh" + + "GpeBd/G5ZMHxoO/K+CbpfJgT0hDvlmxuhG+ujB+WTvFgvfbgjZyQgjnr8PMwey7AzwaZ9Df4twzcK+jXMniXipyCMz0eZPgqcgH0" + + "G4P/kkkdWYc+OQ35OUIayS5cI8g7Ncj1chPSnPQRbhUXkjvk09JB5TtxnNxO6CgvVtVYd/nLyG9CT9mNzjdXKiu0ieLD8kPGSVpN" + + "nRFtKD0lX02vpb21pvES6e9ykjaOv61PMHrLL8tr6UB1ffQdMyW/Jr9prhC2xPrRqcq78kvxT7Or40foZZHF8jK9mzvdyNMVkdVy" + + "y0hbu5O5n7ZVN8kjxS7slNmB7lP3ys/4o9gjdLTZT/tRnps5Za+l3Y1ftVMyTV2bYvRUbJCelAuS63JKQZvoGVjCvre+Fj06UBsU" + + "jStPs0HaLvpQ5ES0tiKxn+Oj6LVyz1gD5SU2mGrUErbFrlOi9q90uPkObxq/XemXlM3tRo/8q/GOyqhU82g6Xitrx+9VqmRt2Yxb" + + "Xlejv5Lwma/FEu5HxhDlnHhJ+oze0EkazyorIu2TX2rvJO4wJysXRxtYj6m32s+bbylr41bZJZHbrR3mfOVrs5u1Un6BiXSZspu+" + + "mmwvXcxuoOuVQ3RM+kchzh6kOxXXHMSfIl3ZJHpQKTQeUtL+j2wxPaEMjv4jOj2/3dpJmXKr2sGsk2P2zzSvPCudpGszjyYtGo28" + + "xnvSvmnD9WjNyHvZ5+LUS6ay9IqI6KXV3W4k49BrIt8nW4jznNtyZ+ltkfvs63NTk8/7R+hfIp+xVe7UxLdkC+0ZyZZNsBfb9aXF" + + "9JFIK9aOnbTuVSbQpyPPWDez1tZw9UH6j8hHiRH2WjZQv4ZOikxwX3HvY81iOXNmRMjQXC22Mr7R/DByIH+RmC3LGM+bn0a+FX5Q" + + "82VJs4W5NrJYGRK/nL1PLxg7IkX6XfRxlqZzjO8jjeJpepBlaGvjWKSXeZ85yFpK/xU/H1lEV0Wr2Rp9MZ6GUnKcctSuaV4Wj6gD" + + "6Vt8fWJv/ItYVXWbMT9dkuwW6xyrp94b+zS5z3lVL402Vq/X7rRS7vvqoOhN6kw5X9bEG68wvbX6EfHYyHQnaZjeRV2Ta5zcmkmS" + + "09r96lnvsHdd7hO/rzZA/cTZ4H+Yfzi3Sx2qevYSuSa/OnOr+px6kZXVJ5Hq3seRSeqV7LjBhavd6pGZ6rVsHx0ujUyOVd5Xr7KG" + + "0V/krH1aXqKaiePx1pEdVlf5c3Wn84L2pvoLWyVtUuunT4g/an9hF0u71Z9zpblY1C97Vjysfk/apwpjMfaLcELdKCftBvGnWWvh" + + "gvqANpyZRkNrHkmro2LN2A9GIxtWKK3UKLJfMocmHuamNoBe6VahgrPJr63l6Pjss/Rr9zL/Cm02HSt8TTd6z+ebaneanVWL/pw5" + + "kbtZM+JG3KWX5NvlirVqenV6hD7KF2U7atMVj86lywSavUdbIbxltqSWNDrTT1ubrx9bY9aPHE8P0k6la0YuNou0bukh2kj3evKA" + + "US36lfd37e1Eq8yE+KbY9d4L2rNWLeeN2M3G4tRU7W72ojUp+qhZmJqpXcYirL9+O33XfVf7mZWwptpOWtf9SHvD/ixxPCIWvO98" + + "ol3kPOy9rBynjZzV2u3epf6l8hC6KrlB+znbUF4hfmremdymbeZv6cXCPKM0sUdbKi0xdvHO8RGJA1o/dTvt6a+OVk8c1d6Pzqcn" + + "c6e11fZJraVxpzE6ey7Sz/5NU6iiV898LcdsS/uF/kNa700V11uetoUOz49MtSUjLF9bZu5ItXYz+essRV8Wb5W43Pky67KYfkaf" + + "wmolp6ZLWIH+ckRnVyZeSL3Cauprxd1WD/tjpz+ro2/yX3XmWkKymF2m/5LZn1Gst+1C1lDvmvqWTGOjLJM10dsll0RuYfOZX1ak" + + "J6w3Ygq7nDllN+jj2UEzWZYsS5Q112WWpRF2MfPKWsLx783b2NtMYq10x3ozNpMNtGqwNvpdyWURw3rRbsra691TB8l861SiI+ug" + + "H8t8l+lnz3CeZp31rf4M56bEkNTbrJu+SdxjXZl8Lr2D/VV/JVLAmjgfZ/Osh16mv8LudH/N32z11FfG2yVGppqR0da9+nJzV+pL" + + "bzT0z/36bvpcPp5ZJet2b/08nSg9kf0hcr/dR69KTf1A7rC2zO6r/8XoZLT3F0XjiX76suhCuoG3jj8J8WB1B71RmGPsh3iN9LGx" + + "WFxs3pbsp3/N39Avlv9Gl0Jcmi2UxytH6WVOX/0ar65/NJKhsyH2k729xtpGWtPtoz9jL0sM0G+kb7nQHraVTYveZ16Suk83YVy9" + + "G7vWmJfqpXdg06yZMA6beffoz1mFzhCjRnSd111/K9E+c415g9Yp3U0f5t5C9poNIz+nu+j/ShdGulJPGpHpqH+Zvya2lK4S4tm7" + + "9E+FeeZZOogvyLbVJylQdBTUz7fKtdLjMF8y9GSmNHebLsbl+B66xRuTb67farZSx9Nd7kX+DfqrdLhQlYrO536RbtHh2efNYYle" + + "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" + + "n4hssjyWtdSPCbPJADbZv561UceJr5AN1novyhoo9aWXiJdIJ0R2VlwrPUOYe47VZR+QXvJQMjIjs/tZD9+SB5Hu/iPWl6wgN0np" + + "RzqKB5O3WMfS9SM9SP3IsfRh67vU8khH8pq+k8+0y5w2ajF5Kr5WGQxvZZ/anEwwS6OPJvfZvbUisoYONoc7H1sntAbEpS6dBaNn" + + "oF6H3ExvpvtTLdkpvRqZaHSO10mLrH80SqTYPHhbddnRqED2qceF0uxUdnfM44VyabZDvrP1VayM30Secjf4fewm8X/xdrm+9o1k" + + "ReLV+FE+3WvJlgidHDt+gHd27mf1pbqpLsY3fIW9wp4s10nPNzbzc4y555XirGus5VXZ6FwbdWy+tbkc5sA4cZK2k080F/POVlNt" + + "vV5T3GF+wLsmPouXRnvJEqzztd1H6YnY+EhzOoM/lz5D98cnwd5lIu+Qv8qcZzwSfYWO48VCf6jq1PhndBQvVBooZebjxh76NLzd" + + "xvxROsE8SQfykliX9BrakyboA5yaA+CtH6B52pOPp4UWp5ySgi6cU4GVH78zPL6W9qJJejuc/2hyQHidm8LrlJlPwPWbwfWv4uX3" + + "bcgbKIXKfKM/tKcubw0jel98sjaQ1uAd843Mk7Hnof0GHwvtL43eC8+lwHMNoOv1WvC8eT943snaLugHx+9iNdNg9OSLzfMwjsbD" + + "PG+ddYxf/aow4qfIdaE/j/rnoHIq7+fv/aCflwqdof+/8Ts5vdlNZGViRnyLPw3eS4nf124cX+e3zfWxO+a7WCWxlf6N5Em3NDuN" + + "dYst8YP3Owree2l0nr9PPSbUDcfDHF+Mfah+F46T1/0JRqf47HD8TPKD8VM+rp73g3E1AMZbH22MvxbG2+BEKxiHQ/xgHL4Zjs/H" + + "/Kfj65TD1n4Ytw/6r+u7ePl4vtcPxvOXjOYmK139TuKhZG/W3bflO/0eMP7rQl6+V77dHwXzIpgv66QbfQvmS5QVwjy62k/DPArm" + + "13ix0C+B+TWWtdCPC5f4A9gk6Bcx1lqo6gfzMZinHxDdnw1P0QDmLSzBfvBZBvP6QZ7KT04eoMF8L/Ev5OenptODMCLq+7/miyEP" + + "XHAydFy+NH8VvOHyvLE/H+SNPpBP2uW+zp+AfPIJ5JlF2a/yt0KeMSD/0OzqPPydGJ0bGRuVWZovNceyM5CvjqXn5UtpIXsgzGOz" + + "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" + + "n4voz0tF9Od5IvrzbBH9eYaI/vyyiP78DxH9eZiI/vyYiP78gIj+3FNEf+4koj+3EdGfbxHRn68R0Z8bihX+3FerK6I/VxPRn6Mi" + + "+rMgoj97AvrzBQH9+VcB/blUqPDn9dJ3AvrzTgH9eaOA/vylgP68TEB//lhAf35PQH9+U0B/niagP78koD8/K6A/DxfQn/8moD/3" + + "F9Cf+wjozz0E9OdOAvpzWwH9+TYB/flGAf25qYD+3FBAf64noD/XEtCfCwT0Z11AfxYF9OcsQX9OEvTn8wT9+V8E/fkXgv78A0F/" + + "/o6gP39D0J+3EfTnrwj68xqC/rySoD9/QtCfFxL05w8J+vNcgv78FkF/fo2gP08l6M8TCPrz8wT9+VmC/jyaoD8PI+jPTxH058cJ" + + "+vOjBP35IYL+3IegP99L0J97EPTnrgT9uSNBf25P0J/bEPTnVgT9uSVBf25O0J9vJOjP1xL052YE/bkJQX++kjzwx+8/FxL8/efL" + + "CPpzPYL+fAlBf76IoD/XJOjP1Qj6cwFBfzYJ+nOMoD/rBP1ZJejPcqXffxYJ+jMh6M8+R3/OcfTnDEd/9jj6s8vRnx2O/pzg6M8W" + + "R39mHP35Akd/Ps/Rn89x9OezHP35DK/kzxz9+V8c/flXjv58spI/n6jkz8cr+fOxSv78yx/+XBL7uZI///Qffv/5aCV/Lq3kzz9W" + + "8ucjlfz5SCV//qGSP/9QyZ8PV/LnQ5X8+VAlfz5YyZ8PVvLng5X8+UAlfz5QyZ+//w/+/H0lf/6ukj9/V8mfv6vkz99V8uf9HP15" + + "P0d/3l/p95/3V/r9530c/XkfR3/ex9Gf93H0530c/flbjv78LUd//pajP3/L0Z+/5ejP33L05285+vNejv78LUd/3svRn/dy9Oe9" + + "HP15L0d/3svRn/dy9Oe9HP15D0d/3sPRn/dw9Oc9HP15D0d/3sPRn/dw9Oc9HP15N0d/3s3Rn3dz9OfdHP15N0d/3s3Rn3dz9Odv" + + "OPrzNxz9+RuO/vwNR3+G+A9/3sXRn3dx9OddHP15F0d/3sXRn3dy9OedHP15J0d/3snRn3dy9OevOfrz1xz9+WuO/vw1R3/ewdGf" + + "d3D05x0c/XkH7AJe/d2ft3P05+0c/Xk7R3/eztGft3H0520c/XkbR3/extGft3L0560c/XkrR3/eyvH3n7dw9OctHP15C0d/3sLR" + + "nzdz9OfNHP15M0d/3szRnzdz9OfNHP15E0d/3sTRnzdx9OdNHP15E0d/3sTRnzdx9OeNHP15I0d/3sjRnzdy9OeNHP15I0d/3sjR" + + "nzdy9OeNHP15I0d/3sjRnzdy9OdNHP15E0d/3sTRnzdx9OdNHP15E0d/3szRnzdz9OfNHP15C0d/3sLRn7dw9OetHP15Kw/q8LWh" + + "P2/j6M/bOPrzdo7+vJ2jP+/g6M9fc/Tnrzn6806O/ryLoz9/w9Gfv+Hoz7s5+vMejv68l6M/f8vRn/dx9Of9HP35O47+fICjPx/k" + + "6M+HOPrzYY7+fISjP//I0Z+PcvTnnzj68y8c/fkYR38+ydGff+Xoz6c4+vMZjv78G0d/Ps/Rn8s4+rPF0Z8THP3Z4ejPKY7+nOHo" + + "zzmO/sw5+rNA0J9lgv4cIejPOkF/jhP0Z0rQn6sS9OcaBP35IoL+fAlBf65H0J8vJ+jPDQj6cyOC/nw1QX++hqA/X0/Qn28m6M8t" + + "CPrzHQT9uQ1Bf25P0J87EvTnrgT9uQdBf76XoD/3IejPDxH05wEE/flxgv78NEF/Hk7Qn8cQ9OfnCPrzCwT9eRJBf55O0J9fJ+jP" + + "swj683sE/Xk+QX9eTNCflxH059UE/XkdQX/eRNCfdxD0570E/fkAQX8uJYET/l8hjcSA"; + + private static short[] Decode(byte[] stream) { + using var src = new MemoryStream(stream, writable: false); + using var dst = new MemoryStream(); + DtsCodec.Decompress(src, dst); + return ToSamples(dst.ToArray()); + } + + private static short[] Reference(string deflated) { + using var src = new MemoryStream(Convert.FromBase64String(deflated), writable: false); + using var inflate = new ZLibStream(src, CompressionMode.Decompress); + using var dst = new MemoryStream(); + inflate.CopyTo(dst); + return ToSamples(dst.ToArray()); + } + + private static short[] ToSamples(byte[] pcm) { + var samples = new short[pcm.Length / 2]; + Buffer.BlockCopy(pcm, 0, samples, 0, samples.Length * 2); + return samples; + } + + private static void AssertMatchesReference(string streamBase64, string referenceBase64, int channels) { + var reference = Reference(referenceBase64); + var ours = Decode(Convert.FromBase64String(streamBase64)); + + Assert.That(ours, Has.Length.EqualTo(reference.Length), + "the decode must cover the whole stream, not stop at the first frame it cannot parse"); + Assert.That(reference.Length % channels, Is.Zero); + + var peak = 0; + var exact = 0; + for (var i = 0; i < reference.Length; ++i) { + var d = Math.Abs(reference[i] - ours[i]); + if (d > peak) peak = d; + if (d == 0) ++exact; + } + + Assert.Multiple(() => { + Assert.That(peak, Is.LessThanOrEqualTo(1), "no sample may differ by more than one LSB"); + Assert.That((double)exact / reference.Length, Is.GreaterThan(0.98), + "at least 98 % of samples must be identical, not merely close"); + }); + } + + /// 0.064 s of pink noise, 48 kHz stereo at 384 kbit/s. + [Test] + [Category("RoundTrip")] + public void StereoMatchesLibavcodec() + => AssertMatchesReference(StereoPinkStream, StereoPinkReference, channels: 2); + + /// + /// 0.08 s of a 997 Hz tone, 48 kHz mono at the full 1411 kbit/s. A single tone at that rate is + /// coded with the finest quantizer steps in the table, the ones whose short-decimal spelling was + /// 0.14 percent off; broadband content never reaches them. + /// + [Test] + [Category("RoundTrip")] + public void FineQuantizedToneMatchesLibavcodec() + => AssertMatchesReference(ToneStream, ToneReference, channels: 1); + + /// + /// 0.05 s of six distinct tones, 48 kHz 5.1 at 768 kbit/s. The core transmits the front channels + /// centre-first and the LFE last, so this covers both the channel map and the LFE interpolation + /// filter, whose history has to survive the frame boundary. + /// + [Test] + [Category("RoundTrip")] + public void SurroundMatchesLibavcodec() + => AssertMatchesReference(SurroundStream, SurroundReference, channels: 6); + + /// Stream info has to agree with libavcodec's view of the same stream. + [Test] + [Category("HappyPath")] + public void SurroundStreamInfoMatchesLibavcodec() { + using var src = new MemoryStream(Convert.FromBase64String(SurroundStream), writable: false); + var info = DtsCodec.ReadStreamInfo(src); + + Assert.Multiple(() => { + Assert.That(info.SampleRate, Is.EqualTo(48_000)); + Assert.That(info.Channels, Is.EqualTo(6)); + Assert.That(info.Amode, Is.EqualTo(9)); + Assert.That(info.Lfe, Is.True); + }); + } +} diff --git a/Hawkynt.FileFormats.Audio/REFERENCE.md b/Hawkynt.FileFormats.Audio/REFERENCE.md index 3bd57ed98..ed4625ab6 100644 --- a/Hawkynt.FileFormats.Audio/REFERENCE.md +++ b/Hawkynt.FileFormats.Audio/REFERENCE.md @@ -1081,11 +1081,11 @@ DCA "block code" sample unpacking for low bit-allocation indexes (abits 1..7 whe #### `DtsCodec` -Clean-room DTS Coherent Acoustics (DCA) core codec. The decoder is a faithful managed port of the FFmpeg reference decoder (`libavcodec/dcadec.c` + `dcadata.c` + `dcahuff.h`) and the encoder lives in the companion partial source file. The core decoder emits interleaved little-endian signed 16-bit PCM at the stream's native channel count (the AMODE full-bandwidth channels in document order, with the LFE channel last when present). Scope: only the standard 16-bit big-endian framing (sync 0x7FFE8001) is decoded; the 14-bit and byte-swapped framings throw `NotSupportedException`. DTS-HD extension substreams (XCH / XXCH / X96 / XBR / XLL and EXSS) are not decoded; an embedded core remains decodable. +Clean-room DTS Coherent Acoustics (DCA) core codec; the encoder lives in the companion partial source file. The core decoder emits interleaved little-endian signed 16-bit PCM at the stream's native channel count, in the ITU/WAVE interleave order — front left, front right, front centre, LFE, then the surrounds — rather than the centre-first AMODE order the bit stream uses. Scope: only the standard 16-bit big-endian framing (sync 0x7FFE8001) is decoded; the 14-bit and byte-swapped framings throw `NotSupportedException`. DTS-HD extension substreams (XCH / XXCH / X96 / XBR / XLL and EXSS) are not decoded; an embedded core remains decodable. | Member | Signature | Summary | | --- | --- | --- | -| `Decompress` | `static void Decompress(Stream input, Stream output)` | Decodes a DTS stream into raw interleaved little-endian signed 16-bit PCM on `output`. Channels are emitted in AMODE document order with LFE last. Throws `NotSupportedException` for the unsupported 14-bit / LE framings. | +| `Decompress` | `static void Decompress(Stream input, Stream output)` | Decodes a DTS stream into raw interleaved little-endian signed 16-bit PCM on `output`. Channels are emitted in the ITU/WAVE interleave order. Throws `NotSupportedException` for the unsupported 14-bit / LE framings. | | `Encode` | `static byte[] Encode(ReadOnlySpan interleaved, DtsEncoderOptions options = null)` | Encodes interleaved PCM16 to standard 16-bit-big-endian DTS Coherent Acoustics core frames. This is a managed adaptation of FFmpeg's LGPL `dcaenc.c` core path: 512 PCM samples per frame, 32-band cosine analysis, direct bit allocation and scale-factor transmission, the no-Huffman quantizer selector, two sub-subframes and the mandatory 0xFFFF DSYNC marker. Prediction, high-frequency VQ and LFE coding are intentionally left off so every coded subband remains independently decodable and the generated core is deterministic. | | `ReadStreamInfo` | `static DtsStreamInfo ReadStreamInfo(Stream input)` | Reads stream-level info (sample rate, native channel count, bitrate, duration) from the first core frame. | @@ -1169,7 +1169,7 @@ DCA Huffman code tables ported verbatim from the FFmpeg reference decoder (`liba #### `DtsQmf` -32-band cosine-modulated QMF synthesis filterbank for the DCA core, reconstructing 256 PCM samples per channel per block from 8 sub-subframe vectors of 32 subband samples each. This is a faithful port of FFmpeg's `dca_qmf_32_subbands` + `synth_filter_float` (`libavcodec/dcadsp.c`, `synth_filter.c`): the per-subband sign flip `((i-1)&2)`, a direct (matrix-multiply) 64→32 `imdct_half`, and the 512-tap polyphase window/overlap stage driven by the perfect- or non-perfect-reconstruction prototype (`Fir32Perfect` / `Fir32NonPerfect`). The direct IMDCT replaces FFmpeg's FFT path; the task permits a direct matrix multiply for the transform. +32-band cosine-modulated QMF synthesis filterbank for the DCA core, reconstructing 256 PCM samples per channel per block from 8 sub-subframe vectors of 32 subband samples each. The stage is the per-subband sign flip `((i-1)&2)`, the second half of a 64-point IMDCT over the 32 subband values, and a 512-tap polyphase window/overlap driven by the perfect- or non-perfect-reconstruction prototype (`Fir32Perfect` / `Fir32NonPerfect`). The IMDCT is evaluated as a direct matrix multiply, which is exact and cheap enough at this size. | Member | Signature | Summary | | --- | --- | --- | @@ -1209,8 +1209,8 @@ Constant numeric tables for the DCA core decoder, ported faithfully from the FFm | `LfeFir128` | `static readonly float[] LfeFir128` | Provides the lfe fir 128 value. | | `LfeFir64` | `static readonly float[] LfeFir64` | Provides the lfe fir 64 value. | | `LfeIndex` | `static readonly int[] LfeIndex` | Provides the lfe index value. | -| `LosslessQuant` | `static readonly float[] LosslessQuant` | Provides the lossless quant value. | -| `LossyQuant` | `static readonly float[] LossyQuant` | Provides the lossy quant value. | +| `LosslessQuant` | `static readonly float[] LosslessQuant` | Lossless-core quantizer step size indexed by the bit-allocation index. | +| `LossyQuant` | `static readonly float[] LossyQuant` | Lossy-core quantizer step size indexed by the bit-allocation index. | | `SampleRates` | `static readonly int[] SampleRates` | Provides the sample rates value. | | `ScaleFactorQuant6` | `static readonly uint[] ScaleFactorQuant6` | Provides the scale factor quant 6 value. | | `ScaleFactorQuant7` | `static readonly uint[] ScaleFactorQuant7` | Provides the scale factor quant 7 value. |