further Flake optimizations

This commit is contained in:
chudov
2009-08-28 13:00:27 +00:00
parent 108c9c328c
commit 2b7312e261
8 changed files with 621 additions and 437 deletions

View File

@@ -32,6 +32,8 @@ namespace CUETools.Codecs.FLAKE
public const int MAX_PARTITION_ORDER = 8;
public const int MAX_PARTITIONS = 1 << MAX_PARTITION_ORDER;
public const uint UINT32_MAX = 0xffffffff;
public const int FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */
public const int FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */
public const int FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */
@@ -50,15 +52,16 @@ namespace CUETools.Codecs.FLAKE
}
public static int log2i(uint v)
{
int i;
//int i;
int n = 0;
if (0 != (v & 0xffff0000)) { v >>= 16; n += 16; }
if (0 != (v & 0xff00)) { v >>= 8; n += 8; }
for (i = 2; i < 256; i <<= 1)
{
if (v >= i) n++;
else break;
}
if (0 != v) return n + 7 - BitReader.byte_to_unary_table[v];
//for (i = 2; i < 256; i <<= 1)
//{
// if (v >= i) n++;
// else break;
//}
return n;
}
@@ -122,15 +125,36 @@ namespace CUETools.Codecs.FLAKE
}
}
unsafe struct RiceContext
unsafe class RiceContext
{
public int porder; /* partition order */
public fixed int rparams[Flake.MAX_PARTITIONS]; /* Rice parameters */
public fixed int esc_bps[Flake.MAX_PARTITIONS]; /* bps if using escape code */
public RiceContext()
{
rparams = new int[Flake.MAX_PARTITIONS];
esc_bps = new int[Flake.MAX_PARTITIONS];
}
/// <summary>
/// partition order
/// </summary>
public int porder;
/// <summary>
/// Rice parameters
/// </summary>
public int[] rparams;
/// <summary>
/// bps if using escape code
/// </summary>
public int[] esc_bps;
};
unsafe struct FlacSubframe
unsafe class FlacSubframe
{
public FlacSubframe()
{
rc = new RiceContext();
coefs = new int[lpc.MAX_LPC_ORDER];
}
public SubframeType type;
public int order;
public int* residual;
@@ -139,31 +163,129 @@ namespace CUETools.Codecs.FLAKE
public int cbits;
public int shift;
public fixed int coefs[lpc.MAX_LPC_ORDER];
public int[] coefs;
public int window;
};
unsafe struct FlacSubframeInfo
unsafe class FlacSubframeInfo
{
public FlacSubframeInfo()
{
best = new FlacSubframe();
lpc_ctx = new LpcContext[lpc.MAX_LPC_WINDOWS];
for (int i = 0; i < lpc.MAX_LPC_WINDOWS; i++)
lpc_ctx[i] = new LpcContext();
}
public void Init(int* s, int* r, uint bps, uint w)
{
if (w > bps)
throw new Exception("internal error");
samples = s;
obits = bps - w;
wbits = w;
best.residual = r;
best.type = SubframeType.Verbatim;
best.size = Flake.UINT32_MAX;
for (int iWindow = 0; iWindow < lpc.MAX_LPC_WINDOWS; iWindow++)
lpc_ctx[iWindow].Reset();
done_fixed = 0;
}
public FlacSubframe best;
public uint obits;
public uint wbits;
public int* samples;
public fixed uint done_lpcs[lpc.MAX_LPC_WINDOWS * lpc.MAX_LPC_PRECISIONS];
public uint done_fixed;
public fixed double reflection_coeffs[lpc.MAX_LPC_ORDER * lpc.MAX_LPC_WINDOWS];
public fixed double autocorr_values[(lpc.MAX_LPC_ORDER + 1) * lpc.MAX_LPC_WINDOWS];
public fixed int autocorr_orders[lpc.MAX_LPC_WINDOWS];
public LpcContext[] lpc_ctx;
};
unsafe struct FlacFrame
unsafe class FlacFrame
{
public FlacFrame(int subframes_count)
{
subframes = new FlacSubframeInfo[subframes_count];
for (int ch = 0; ch < subframes_count; ch++)
subframes[ch] = new FlacSubframeInfo();
current = new FlacSubframe();
}
public void InitSize(int bs, bool vbs)
{
int i = 15;
if (!vbs)
{
for (i = 0; i < 15; i++)
{
if (bs == Flake.flac_blocksizes[i])
{
blocksize = Flake.flac_blocksizes[i];
bs_code0 = i;
bs_code1 = -1;
break;
}
}
}
if (i == 15)
{
blocksize = bs;
if (blocksize <= 256)
{
bs_code0 = 6;
bs_code1 = blocksize - 1;
}
else
{
bs_code0 = 7;
bs_code1 = blocksize - 1;
}
}
}
public void ChooseBestSubframe(int ch)
{
if (current.size >= subframes[ch].best.size)
return;
FlacSubframe tmp = subframes[ch].best;
subframes[ch].best = current;
current = tmp;
}
public void SwapSubframes(int ch1, int ch2)
{
FlacSubframeInfo tmp = subframes[ch1];
subframes[ch1] = subframes[ch2];
subframes[ch2] = tmp;
}
/// <summary>
/// Swap subframes according to channel mode.
/// It is assumed that we have 4 subframes,
/// 0 is right, 1 is left, 2 is middle, 3 is difference
/// </summary>
public void ChooseSubframes()
{
switch (ch_mode)
{
case ChannelMode.MidSide:
SwapSubframes(0, 2);
SwapSubframes(1, 3);
break;
case ChannelMode.RightSide:
SwapSubframes(0, 3);
break;
case ChannelMode.LeftSide:
SwapSubframes(1, 3);
break;
}
}
public int blocksize;
public int bs_code0, bs_code1;
public ChannelMode ch_mode;
public int ch_order0, ch_order1;
//public int ch_order0, ch_order1;
public byte crc8;
public FlacSubframeInfo* subframes;
public FlacSubframeInfo[] subframes;
public uint frame_count;
public FlacSubframe current;
public double* window_buffer;
@@ -185,11 +307,11 @@ namespace CUETools.Codecs.FLAKE
public enum PredictionType
{
/// <summary>
/// verbatim
/// Verbatim
/// </summary>
None = 0,
/// <summary>
/// Fixed only
/// Fixed prediction only
/// </summary>
Fixed = 1,
/// <summary>
@@ -199,11 +321,7 @@ namespace CUETools.Codecs.FLAKE
/// <summary>
/// Exhaustive search
/// </summary>
Search = 3,
/// <summary>
/// Internal; Use prediction type from previous estimation
/// </summary>
Estimated = 4
Search = 3
}
public enum StereoMethod
@@ -249,45 +367,44 @@ namespace CUETools.Codecs.FLAKE
public enum MetadataType
{
/// <summary>
/// <A HREF="../format.html#metadata_block_streaminfo">STREAMINFO</A> block
/// </summary>
FLAC__METADATA_TYPE_STREAMINFO = 0,
StreamInfo = 0,
/// <summary>
/// <A HREF="../format.html#metadata_block_padding">PADDING</A> block
/// </summary>
FLAC__METADATA_TYPE_PADDING = 1,
Padding = 1,
/// <summary>
/// <A HREF="../format.html#metadata_block_application">APPLICATION</A> block
/// </summary>
FLAC__METADATA_TYPE_APPLICATION = 2,
Application = 2,
/// <summary>
/// <A HREF="../format.html#metadata_block_seektable">SEEKTABLE</A> block
/// </summary>
FLAC__METADATA_TYPE_SEEKTABLE = 3,
Seektable = 3,
/// <summary>
/// <A HREF="../format.html#metadata_block_vorbis_comment">VORBISCOMMENT</A> block (a.k.a. FLAC tags)
/// </summary>
FLAC__METADATA_TYPE_VORBIS_COMMENT = 4,
VorbisComment = 4,
/// <summary>
/// <A HREF="../format.html#metadata_block_cuesheet">CUESHEET</A> block
/// </summary>
FLAC__METADATA_TYPE_CUESHEET = 5,
CUESheet = 5,
/// <summary>
/// <A HREF="../format.html#metadata_block_picture">PICTURE</A> block
/// </summary>
FLAC__METADATA_TYPE_PICTURE = 6,
Picture = 6,
/// <summary>
/// marker to denote beginning of undefined type range; this number will increase as new metadata types are added
/// </summary>
FLAC__METADATA_TYPE_UNDEFINED = 7
Undefined = 7
};
}