resample_lagrange_ex_frac_delay.c

Пример использования фильтра Фарроу на основе полиномиальной интерполяции для компенсации дробной задержки сигнала.Исходный сигнал \( s(n), \) \( n = 0 \ldots 7, \) содержит 8 отсчетов, как это показано на следующем рисунке.

resample_lagrange_frac_delay_in.png

Данная программа производит пересчет исходного сигнала \( s(n) \) в сигнал \( y(k), \) \( k = 0 \ldots 7, \) задержанный относительно \( s(n) \) на величину \( x_0 = 0.25 \) периода дискретизации.

Процесс передискретизации выводится в таблицу:

 ----------------------------------------------------------------------------------------------------------
 | k     xk    n   delta | s(n-3)  s(n-2)  s(n-1)  s(n) |     a0       a1       a2        a3   |   y(k)   |
 ----------------------------------------------------------------------------------------------------------
 | 0   -0.25   1    0.25 |    0.0     0.0    1.0    2.0 |   1.0000    1.1667   0.0000  -0.1667 |   0.7109 |
 | 1    0.75   2    0.25 |    0.0     1.0    2.0    2.0 |   2.0000    0.6667  -0.5000  -0.1667 |   1.8047 |
 | 2    1.75   3    0.25 |    1.0     2.0    2.0    1.0 |   2.0000   -0.5000  -0.5000   0.0000 |   2.0938 |
 | 3    2.75   4    0.25 |    2.0     2.0    1.0   -0.5 |   1.0000   -1.3333  -0.2500   0.0833 |   1.3164 |
 | 4    3.75   5    0.25 |    2.0     1.0   -0.5   -1.0 |  -0.5000   -1.2500   0.5000   0.2500 |  -0.1602 |
 | 5    4.75   6    0.25 |    1.0    -0.5   -1.0   -2.0 |  -1.0000   -0.5000  -0.2500  -0.2500 |  -0.8867 |
 | 6    5.75   7    0.25 |   -0.5    -1.0   -2.0   -0.5 |  -2.0000   -0.2500   1.2500   0.5000 |  -1.8672 |
 | 7    6.75   8    0.25 |   -1.0    -2.0   -0.5    0.0 |  -0.5000    1.5833  -0.5000  -0.5833 |  -0.9180 |
 ----------------------------------------------------------------------------------------------------------

Таким образом, сигнал после передискретизации показан на рисунке ниже

resample_lagrange_frac_delay_out.png
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "dspl.h"
#define P 1
#define Q 1
#define N 8
#define X0 0.25
int main()
{
HINSTANCE hDSPL; /* dspl handle */
/* input signal vector s = [1 2 2 1 -0.5 -1 -2 -0.5] */
double s[N] = {1.0, 2.0, 2.0, 1.0, -0.5, -1.0, -2.0, -0.5};
/* vector z keeps s and 3 additional zeros
z = [0 0 1 2 2 1 -0.5 -1 -2 -0.5 0]
zeros are necessary for n-3 to be a nonzero. */
double z[N+3];
double y[N]; /*output signal delayed on X0 fractional delay */
double x; /* x_k value */
double delta; /* delta_k value */
double a[4]; /* Polynomial coeff vector */
int k, n;
/* Load dspl.dll */
hDSPL = dspl_load();
if(!hDSPL)
{
printf("dspl.dll loading ERROR!\n");
return 0;
}
/* z = [0 0 1 2 2 1 -0.5 -1 -2 -0.5 0] */
memset(z, 0, (N+3) * sizeof(double));
memcpy(z+2, s, N*sizeof(double));
/* table header print */
printf("\n\n -----------------------------------------------------");
printf("-----------------------------------------------------\n");
printf(" | k xk n delta | s(n-3) s(n-2) s(n-1) s(n) |");
printf(" a0 a1 a2 a3 | y(k) |\n");
printf(" -----------------------------------------------------");
printf("-----------------------------------------------------\n");
for(k = 0; k < N; k++)
{
x = (double)k * Q/P - X0;
n = floor(x)+2;
n+=2;
delta = - floor(x) - 1.0 + x;
/* polynomial coefficients calculation */
a[0] = z[n-1];
a[3] = (z[n] - z[n-3]) / 6.0 + 0.5 * (z[n-2] - z[n-1]);
a[1] = 0.5*(z[n] - z[n-2]) - a[3];
a[2] = z[n] - z[n-1] - a[3] - a[1];
dspl_polyval(a,3,&delta, 1, y+k);
printf(" | %.1d %6.2f %.1d %6.2f |", k, x, n-2, -delta);
printf(" %6.1f %6.1f %6.1f %6.1f |", z[n-3], z[n-2], z[n-1], z[n]);
printf(" %8.4f %8.4f %8.4f %8.4f |", a[0], a[1], a[2], a[3]);
printf(" %8.4f |\n", y[k]);
}
printf(" -----------------------------------------------------");
printf("-----------------------------------------------------\n\n");
/* clear dspl handle */
FreeLibrary(hDSPL);
return 0;
}