Flake: use new window functions (partial_tukey, punchout_tukey).

This commit is contained in:
Grigory Chudov
2014-08-26 23:48:16 -04:00
parent 5e784881f1
commit 52879ed70c
15 changed files with 1314 additions and 214 deletions

View File

@@ -5,8 +5,9 @@ namespace CUETools.Codecs
public class lpc
{
public const int MAX_LPC_ORDER = 32;
public const int MAX_LPC_WINDOWS = 2;
public const int MAX_LPC_WINDOWS = 8;
public const int MAX_LPC_PRECISIONS = 4;
public const int MAX_LPC_SECTIONS = 32;
public unsafe static void window_welch(float* window, int L)
{
@@ -21,7 +22,7 @@ namespace CUETools.Codecs
}
}
public unsafe static void window_bartlett(float* window, int L)
public unsafe static void window_bartlett(float* window, int L)
{
int N = L - 1;
double N2 = (double)N / 2.0;
@@ -33,35 +34,65 @@ namespace CUETools.Codecs
}
}
public unsafe static void window_rectangle(float* window, int L)
public unsafe static void window_rectangle(float* window, int L)
{
for (int n = 0; n < L; n++)
window[n] = 1.0F;
}
public unsafe static void window_flattop(float* window, int L)
public unsafe static void window_flattop(float* window, int L)
{
int N = L - 1;
for (int n = 0; n < L; n++)
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)
{
window_rectangle(window, L);
double p = 0.5;
int Np = (int)(p / 2.0 * L) - 1;
int z = 0;
int Np = (int)(p / 2.0 * L) - z;
if (Np > 0)
{
for (int n = 0; n <= Np; n++)
{
window[n] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * n / Np));
window[L - Np - 1 + n] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * (n + Np) / Np));
}
for (int n = 0; n < z; n++)
window[n] = window[L - n - 1] = 0;
for (int n = 0; n < Np - 1; n++)
window[n + z] = window[L - n - 1 - z] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * (n + 1) / Np));
for (int n = z + Np - 1; n < L - z - Np + 1; n++)
window[n] = 1.0F;
}
}
public unsafe static void window_hann(float* window, int L)
public unsafe static void window_punchout_tukey(float* window, int L, double p, double start, double end)
{
int start_n = (int)(start * L);
int end_n = (int)(end * L);
int Np = (int)(p / 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++)
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 (; 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 (; n < L - Np; n++)
window[n] = 1.0f;
for (i = Np; n < L; n++, i--)
window[n] = (float)(0.5 - 0.5 * Math.Cos(Math.PI * i / Np));
}
}
public unsafe static void window_hann(float* window, int L)
{
int N = L - 1;
for (int n = 0; n < L; n++)
@@ -73,6 +104,7 @@ namespace CUETools.Codecs
return (short)((val >> 31) + ((val - 1) >> 31) + 1);
}
#if XXX
static public unsafe void
compute_corr_int(/*const*/ short* data1, short* data2, int len, int min, int lag, int* autoc)
{
@@ -92,13 +124,14 @@ namespace CUETools.Codecs
autoc[i] = temp + temp2;
}
}
#endif
/**
* Calculates autocorrelation data from audio samples
* A window function is applied before calculation.
*/
static public unsafe void
compute_autocorr(/*const*/ int* data, int len, int min, int lag, double* autoc, float* window)
compute_autocorr(/*const*/ int* data, float* window, int len, int min, int lag, double* autoc, int prev, int next)
{
#if FPAC
short* data1 = stackalloc short[len + 1];
@@ -125,30 +158,224 @@ namespace CUETools.Codecs
for (int coeff = min; coeff <= lag; coeff++)
autoc[coeff] = (c1[coeff] * (double)(1 << 18) + (c2[coeff] + c3[coeff]) * (double)(1 << 9) + c4[coeff]);
#else
double* data1 = stackalloc double[(int)len + 16];
int i;
#if XXX
if (min == 0 && lag >= 4)
{
int* pdata = data;
float* pwindow = window;
for (i = 0; i < len; i++)
data1[i] = data[i] * window[i];
data1[len] = 0;
double temp0 = 1.0;
double temp1 = 1.0;
double temp2 = 1.0;
double temp3 = 1.0;
double temp4 = 1.0;
for (i = min; i <= lag; ++i)
double c0 = *(pdata++) * *(pwindow++);
float c1 = *(pdata++) * *(pwindow++);
float c2 = *(pdata++) * *(pwindow++);
float c3 = *(pdata++) * *(pwindow++);
float c4 = *(pdata++) * *(pwindow++);
int* finish = data + len;
while (pdata <= finish)
{
temp0 += c0 * c0;
temp1 += c0 * c1;
temp2 += c0 * c2;
temp3 += c0 * c3;
temp4 += c0 * c4;
c0 = c1;
c1 = c2;
c2 = c3;
c3 = c4;
c4 = *(pdata++) * *(pwindow++);
}
temp0 += c0 * c0;
temp1 += c0 * c1;
temp2 += c0 * c2;
temp3 += c0 * c3;
c0 = c1;
c1 = c2;
c2 = c3;
temp0 += c0 * c0;
temp1 += c0 * c1;
temp2 += c0 * c2;
c0 = c1;
c1 = c2;
temp0 += c0 * c0;
temp1 += c0 * c1;
c0 = c1;
temp0 += c0 * c0;
autoc[0] += temp0;
autoc[1] += temp1;
autoc[2] += temp2;
autoc[3] += temp3;
autoc[4] += temp4;
min = 5;
if (lag < min) return;
}
#endif
double* data1 = stackalloc double[lag + len + lag];
int i;
for (i = 0; i < lag; i++)
data1[i] = prev != 0 ? data[i - lag] : 0;
for (i = 0; i < len; i++)
data1[lag + i] = data[i] * window[i];
for (i = 0; i < lag; i++)
data1[lag + len + i] = next != 0 ? data[len + i] : 0;
for (i = min; i <= lag; ++i)
{
double temp = 1.0;
double temp2 = 1.0;
double* finish = data1 + len - i;
double temp = 0;
double temp2 = 0;
double* pdata = data1 + lag - i;
double* finish = data1 + lag + len - 1;
for (double* pdata = data1; pdata < finish; pdata += 2)
{
temp += pdata[i] * pdata[0];
temp2 += pdata[i + 1] * pdata[1];
}
autoc[i] = temp + temp2;
while (pdata < finish)
{
temp += pdata[i] * (*pdata++);
temp2 += pdata[i] * (*pdata++);
}
if (pdata <= finish)
temp += pdata[i] * (*pdata++);
autoc[i] += temp + temp2;
}
#endif
}
/**
static public unsafe void
compute_autocorr_windowless(/*const*/ int* data, int len, int min, int lag, double* autoc)
{
// if databits*2 + log2(len) <= 64
#if !XXX
#if XXX
if (min == 0 && lag >= 4)
{
long temp0 = 0;
long temp1 = 0;
long temp2 = 0;
long temp3 = 0;
long temp4 = 0;
int* pdata = data;
int* finish = data + len - 4;
while (pdata < finish)
{
long c0 = *(pdata++);
temp0 += c0 * c0;
temp1 += c0 * pdata[0];
temp2 += c0 * pdata[1];
temp3 += c0 * pdata[2];
temp4 += c0 * pdata[3];
}
{
long c0 = *(pdata++);
temp0 += c0 * c0;
temp1 += c0 * pdata[0];
temp2 += c0 * pdata[1];
temp3 += c0 * pdata[2];
}
{
long c0 = *(pdata++);
temp0 += c0 * c0;
temp1 += c0 * pdata[0];
temp2 += c0 * pdata[1];
}
{
long c0 = *(pdata++);
temp0 += c0 * c0;
temp1 += c0 * pdata[0];
}
{
long c0 = *(pdata++);
temp0 += c0 * c0;
}
autoc[0] += temp0;
autoc[1] += temp1;
autoc[2] += temp2;
autoc[3] += temp3;
autoc[4] += temp4;
min = 5;
if (lag < min) return;
}
#endif
for (int i = min; i <= lag; ++i)
{
long temp = 0;
long temp2 = 0;
int* pdata = data;
int* finish = data + len - i - 1;
while (pdata < finish)
{
temp += (long)pdata[i] * (*pdata++);
temp2 += (long)pdata[i] * (*pdata++);
}
if (pdata <= finish)
temp += (long)pdata[i] * (*pdata++);
autoc[i] += temp + temp2;
}
#else
for (int i = min; i <= lag; ++i)
{
double temp = 0;
double temp2 = 0;
int* pdata = data;
int* finish = data + len - i - 1;
while (pdata < finish)
{
temp += (double)pdata[i] * (double)(*pdata++);
temp2 += (double)pdata[i] * (double)(*pdata++);
}
if (pdata <= finish)
temp += (double)pdata[i] * (double)(*pdata++);
autoc[i] += temp + temp2;
}
#endif
}
static public unsafe void
compute_autocorr_windowless_large(/*const*/ int* data, int len, int min, int lag, double* autoc)
{
for (int i = min; i <= lag; ++i)
{
double temp = 0;
double temp2 = 0;
int* pdata = data;
int* finish = data + len - i - 1;
while (pdata < finish)
{
temp += (long)pdata[i] * (*pdata++);
temp2 += (long)pdata[i] * (*pdata++);
}
if (pdata <= finish)
temp += (long)pdata[i] * (*pdata++);
autoc[i] += temp + temp2;
}
}
static public unsafe void
compute_autocorr_glue(/*const*/ int* data, int min, int lag, double* autoc)
{
for (int i = min; i <= lag; ++i)
{
long temp = 0;
int* pdata = data - i;
int* finish = data;
while (pdata < finish)
temp += (long)pdata[i] * (*pdata++);
autoc[i] += temp;
}
}
/**
* Levinson-Durbin recursion.
* Produces LPC coefficients from autocorrelation data.
*/