mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Flake: use new window functions (partial_tukey, punchout_tukey).
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user