libdspl-2.0
Библиотека алгоритмов цифровой обработки сигналов
farrow_lagrange.c
1/*
2* Copyright (c) 2015-2022 Sergey Bakhurin
3* Digital Signal Processing Library [http://dsplib.org]
4*
5* This file is part of libdspl-2.0.
6*
7* is free software: you can redistribute it and/or modify
8* it under the terms of the GNU Lesser General Public License as published by
9* the Free Software Foundation, either version 3 of the License, or
10* (at your option) any later version.
11*
12* DSPL is distributed in the hope that it will be useful,
13* but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15* GNU General Public License for more details.
16*
17* You should have received a copy of the GNU Lesser General Public License
18* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21
22
23#include <stdlib.h>
24#include <string.h>
25#include <math.h>
26#include "dspl.h"
27
28#define DSPL_FARROW_LAGRANGE_COEFF 0.16666666666666666666666666666667
29
30
31#ifdef DOXYGEN_ENGLISH
32
33#endif
34#ifdef DOXYGEN_RUSSIAN
35/*!*****************************************************************************
36\ingroup RESAMPLING_GROUP
37\fn int farrow_lagrange(double *s, int n, double p, double q,
38 double frd, double **y, int *ny)
39\brief Передискретизация вещественного сигнала на основе
40полиномиальной Лагранжевой интерполяции.
41
42Данная функция осуществляет передискретизацию входного сигнала `s` в `p/q` раз
43со смещением дробной задержки `frd`. \n
44
45Для передискретизации используется
46<a href = "http://ru.dsplib.org/content/resampling_lagrange/resampling_lagrange.html">
47полиномиальная Лагранжева интерполяция
48</a> (структура Фарроу для полиномиальной интерполяции). \n
49
50\param [in] s
51Указатель на вектор входного вещественного сигнала. \n
52Размер вектора `[n x 1]`. \n \n
53
54\param [in] n
55Размер вектора входного сигнала. \n \n
56
57\param [in] p
58Числитель коэффициента передискретизации. \n \n
59
60\param [in] q
61Знаменатель коэффициента передискретизации. \n\n
62
63\param [in] frd
64Значение смещения дробной задержки в пределах одного отсчета. \n
65Значение должно быть от 0 до 1. \n
66\n
67
68\param [out] y
69Указатель на адрес результата передискретизации. \n
70По данному адресу будет произведено динамическое выделение памяти
71для результата передискретизации. \n
72Будет выделено памяти под `n*q/p` отсчетов выходного сигнала. \n
73Данный указатель не может быть `NULL`. \n\n
74
75\param [in] ny
76Указатель на переменную, в которую будет записан
77размер вектора `(*y)` после выделения памяти. \n \n
78
79\return
80`RES_OK` --- передискретизация рассчитана успешно. \n
81В противном случае \ref ERROR_CODE_GROUP "код ошибки". \n
82
83\author Бахурин Сергей. www.dsplib.org
84***************************************************************************** */
85#endif
86int DSPL_API farrow_lagrange(double *s, int n, double p, double q,
87 double frd, double **y, int *ny)
88{
89 double a[4];
90 double t, x, dt;
91 int ind, k, res;
92 double g[4];
93 double *z;
94
95 if(!s || !y)
96 return ERROR_PTR;
97
98 if(n<1)
99 return ERROR_SIZE;
100
101 if(p <= 0.0 || q <= 0.0)
103
104 if(frd <= -1.0 || frd >= 1.0)
106
107 dt = q/p;
108
109 if((*ny) != (int)((double)(n-1)/dt)+1 || !(*y))
110 {
111
112 *ny = (int)((double)(n-1)/dt)+1;
113 (*y) = (double*)realloc((*y), (*ny)*sizeof(double));
114 }
115
116 t = -frd;
117 k = 0;
118 while(k < (*ny))
119 {
120 ind = (int)floor(t)+1;
121 x = t - (double)ind;
122 ind-=2;
123 if(ind < 0)
124 {
125 memset(g, 0, 4*sizeof(double));
126 if(ind > (-3))
127 memcpy(g-ind, s, (4+ind)*sizeof(double));
128 z = g;
129 }
130 else
131 {
132 if(ind < n-3)
133 z = s+ind;
134 else
135 {
136 memset(g, 0, 4*sizeof(double));
137 if((n-ind)>0)
138 memcpy(g, s+ind, (n-ind)*sizeof(double));
139 z = g;
140 }
141 }
142 a[0] = z[2];
143 a[3] = DSPL_FARROW_LAGRANGE_COEFF*(z[3] -z[0]) + 0.5*(z[1] - z[2]);
144 a[1] = 0.5*(z[3] - z[1])-a[3];
145 a[2] = z[3] - z[2] -a[3]-a[1];
146
147 res = polyval(a, 3, &x, 1, (*y)+k);
148
149 if(res != RES_OK)
150 goto exit_label;
151 t+=dt;
152 k++;
153 }
154
155exit_label:
156 return res;
157}
158
#define RES_OK
Функция завершилась корректно. Ошибки отсутствуют.
Definition: dspl.h:558
#define ERROR_RESAMPLE_RATIO
Коэффициент передискретизации задан неверно. Коэффициент передискретизации задается отношением ,...
Definition: dspl.h:615
#define ERROR_RESAMPLE_FRAC_DELAY
Неверное значение дробной задержки. Дробная задержка может принимать значения от -1 до 1,...
Definition: dspl.h:616
#define ERROR_PTR
Ошибка указателя. Данная ошибка означает, что один из обязательных указателей (память под который дол...
Definition: dspl.h:610
#define ERROR_SIZE
Ошибка при передаче размера массива. Данная ошибка возникает когда помимо указателя на массив входных...
Definition: dspl.h:618
int farrow_lagrange(double *s, int n, double p, double q, double frd, double **y, int *ny)
Передискретизация вещественного сигнала на основе полиномиальной Лагранжевой интерполяции.
int polyval(double *a, int ord, double *x, int n, double *y)
Расчет вещественного полинома
Definition: polyval.c:77