CUETools.Flake: better use of new window functions

This commit is contained in:
Grigory Chudov
2014-12-08 22:18:34 -05:00
parent c671f200df
commit 6201101ccf
14 changed files with 679 additions and 707 deletions

View File

@@ -81,11 +81,23 @@ namespace CUETools.Codecs
if (attribute is DefaultValueForModeAttribute)
{
var defaultValueForMode = attribute as DefaultValueForModeAttribute;
res &= (int)property.GetValue(this) == defaultValueForMode.m_values[index];
res &= property.GetValue(this).Equals(defaultValueForMode.m_values[index]);
}
return res;
}
public int GuessEncoderMode()
{
string defaultMode;
string[] modes = this.GetSupportedModes(out defaultMode).Split(' ');
if (modes == null || modes.Length < 1)
return -1;
for (int i = 0; i < modes.Length; i++)
if (HasDefaultValuesForMode(i))
return i;
return -1;
}
[Browsable(false)]
[XmlIgnore]
public AudioPCMConfig PCM

View File

@@ -11,21 +11,32 @@ namespace CUETools.Codecs
return log2i((uint)v);
}
public static readonly byte[] MultiplyDeBruijnBitPosition = new byte[32]
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
public static int log2i(ulong v)
{
int n = 0;
if (0 != (v & 0xffffffff00000000)) { v >>= 32; n += 32; }
if (0 != (v & 0xffff0000)) { v >>= 16; n += 16; }
if (0 != (v & 0xff00)) { v >>= 8; n += 8; }
return n + byte_to_log2_table[v];
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
if (v >> 32 == 0)
return MultiplyDeBruijnBitPosition[(uint)((uint)v * 0x07C4ACDDU) >> 27];
return 32 + MultiplyDeBruijnBitPosition[(uint)((uint)(v >> 32) * 0x07C4ACDDU) >> 27];
}
public static int log2i(uint v)
{
int n = 0;
if (0 != (v & 0xffff0000)) { v >>= 16; n += 16; }
if (0 != (v & 0xff00)) { v >>= 8; n += 8; }
return n + byte_to_log2_table[v];
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
return MultiplyDeBruijnBitPosition[(uint)(v * 0x07C4ACDDU) >> 27];
}
public static readonly byte[] byte_to_unary_table = new byte[]
@@ -48,26 +59,6 @@ namespace CUETools.Codecs
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
public static readonly byte[] byte_to_log2_table = new byte[]
{
0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};
#endregion
private byte* buffer_m;

View File

@@ -108,6 +108,12 @@ namespace CUETools.Codecs
writebits(8, (byte)s[i]);
}
public void write(byte[] s)
{
for (int i = 0; i < s.Length; i++)
writebits(8, s[i]);
}
public void writebits_signed(int bits, int val)
{
writebits(bits, val & ((1 << bits) - 1));

View File

@@ -13,13 +13,13 @@ namespace CUETools.Codecs
/// <summary>
/// Resource manager to use;
/// </summary>
public int[] m_values;
public object[] m_values;
/// <summary>
/// Construct the description attribute
/// </summary>
/// <param name="text"></param>
public DefaultValueForModeAttribute(params int[] values)
public DefaultValueForModeAttribute(params object[] values)
{
this.m_values = values;
}

View File

@@ -5,9 +5,9 @@ namespace CUETools.Codecs
public class lpc
{
public const int MAX_LPC_ORDER = 32;
public const int MAX_LPC_WINDOWS = 8;
public const int MAX_LPC_WINDOWS = 16;
public const int MAX_LPC_PRECISIONS = 4;
public const int MAX_LPC_SECTIONS = 32;
public const int MAX_LPC_SECTIONS = 128;
public unsafe static void window_welch(float* window, int L)
{
@@ -47,9 +47,8 @@ namespace CUETools.Codecs
window[n] = (float)(1.0 - 1.93 * Math.Cos(2.0 * Math.PI * n / N) + 1.29 * Math.Cos(4.0 * Math.PI * n / N) - 0.388 * Math.Cos(6.0 * Math.PI * n / N) + 0.0322 * Math.Cos(8.0 * Math.PI * n / N));
}
public unsafe static void window_tukey(float* window, int L)
public unsafe static void window_tukey(float* window, int L, double p)
{
double p = 0.5;
int z = 0;
int Np = (int)(p / 2.0 * L) - z;
if (Np > 0)
@@ -63,28 +62,29 @@ namespace CUETools.Codecs
}
}
public unsafe static void window_punchout_tukey(float* window, int L, double p, double start, double end)
public unsafe static void window_punchout_tukey(float* window, int L, double p, double p1, double start, double end)
{
int start_n = (int)(start * L);
int end_n = (int)(end * L);
int Np = (int)(p / 2.0 * L);
int Np1 = (int)(p1 / 2.0 * L);
int i, n = 0;
if (start_n != 0)
{
for (i = 1; n < Np; n++, i++)
window[n] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * i / Np));
for (; n < start_n - Np; n++)
for (; n < start_n - Np1; n++)
window[n] = 1.0f;
for (i = Np; n < start_n; n++, i--)
window[n] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * i / Np));
for (i = Np1; n < start_n; n++, i--)
window[n] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * i / Np1));
}
for (; n < end_n; n++)
window[n] = 0.0f;
if (end_n != L)
{
for (i = 1; n < end_n + Np; n++, i++)
window[n] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * i / Np));
for (i = 1; n < end_n + Np1; n++, i++)
window[n] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * i / Np1));
for (; n < L - Np; n++)
window[n] = 1.0f;
for (i = Np; n < L; n++, i--)
@@ -358,11 +358,11 @@ namespace CUETools.Codecs
}
static public unsafe void
compute_autocorr_glue(/*const*/ int* data, float* window, int offs, int sz, int min, int lag, double* autoc)
compute_autocorr_glue(/*const*/ int* data, float* window, int offs, int offs1, int min, int lag, double* autoc)
{
double* data1 = stackalloc double[lag + lag];
for (int i = -lag; i < lag; i++)
data1[i + lag] = offs + i >= 0 && offs + i < sz ? data[offs + i] * window[offs + i] : 0;
data1[i + lag] = offs + i >= 0 && offs + i < offs1 ? data[offs + i] * window[offs + i] : 0;
for (int i = min; i <= lag; ++i)
{
double temp = 0;

View File

@@ -83,7 +83,7 @@ namespace CUETools.Codecs
else if (m_type == SectionType.Data)
lpc.compute_autocorr(data + m_start, window + m_start, m_end - m_start, min_order, order, autoc);
else if (m_type == SectionType.Glue)
lpc.compute_autocorr_glue(data, window, m_start, blocksize, min_order, order, autoc);
lpc.compute_autocorr_glue(data, window, m_start, m_end, min_order, order, autoc);
else if (m_type == SectionType.OneGlue)
lpc.compute_autocorr_glue(data + m_start, min_order, order, autoc);
}
@@ -109,6 +109,7 @@ namespace CUETools.Codecs
&& w == window_segment[i1 * stride + x])
alias[i1, boundaries.Count] = i;
}
if (boundaries.Count >= lpc.MAX_LPC_SECTIONS * 2) throw new IndexOutOfRangeException();
types[i, boundaries.Count] =
boundaries.Count >= lpc.MAX_LPC_SECTIONS * 2 - 2 ?
LpcWindowSection.SectionType.Data : w == 0.0 ?
@@ -143,6 +144,7 @@ namespace CUETools.Codecs
// leave room for glue
if (secs[i] >= lpc.MAX_LPC_SECTIONS - 1)
{
throw new IndexOutOfRangeException();
window_sections[secs[i] - 1].m_type = LpcWindowSection.SectionType.Data;
window_sections[secs[i] - 1].m_end = boundaries[j + 1];
continue;
@@ -165,6 +167,7 @@ namespace CUETools.Codecs
secs[i]--;
continue;
}
if (section_id >= lpc.MAX_LPC_SECTIONS) throw new IndexOutOfRangeException();
if (alias_set[i, j] != 0
&& types[i, j] != SectionType.Zero
&& section_id < lpc.MAX_LPC_SECTIONS)
@@ -174,7 +177,7 @@ namespace CUETools.Codecs
sections[i1 * lpc.MAX_LPC_SECTIONS + secs[i1] - 1].m_id = section_id;
section_id++;
}
// TODO: section_id for glue?
// TODO: section_id for glue? nontrivial, must be sure next sections are the same size
if (sec > 0
&& (window_sections[sec].m_type == SectionType.One || window_sections[sec].m_type == SectionType.OneLarge)
&& window_sections[sec].m_end - window_sections[sec].m_start >= lpc.MAX_LPC_ORDER
@@ -203,6 +206,15 @@ namespace CUETools.Codecs
}
for (int i = 0; i < _windowcount; i++)
{
for (int s = 0; s < secs[i]; s++)
{
LpcWindowSection* window_sections = sections + i * lpc.MAX_LPC_SECTIONS;
if (window_sections[s].m_type == SectionType.Glue
|| window_sections[s].m_type == SectionType.OneGlue)
{
window_sections[s].m_end = window_sections[s + 1].m_end;
}
}
while (secs[i] < lpc.MAX_LPC_SECTIONS)
{
LpcWindowSection* window_sections = sections + i * lpc.MAX_LPC_SECTIONS;