#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SOX_INT_MAX(bits) (((unsigned)-1)>>(33-(bits)))
#define SOX_INT_MIN(bits) (1 <<((bits)-1))
#define SOX_SAMPLE_MAX (long)SOX_INT_MAX(32)
#define SOX_SAMPLE_MIN (long)SOX_INT_MIN(32)
#define SOX_FLOAT_32BIT_TO_SAMPLE(d,clips) (long)((d)*(SOX_SAMPLE_MAX+1.)<SOX_SAMPLE_MIN?++(clips),SOX_SAMPLE_MIN:(d)*(SOX_SAMPLE_MAX+1.)>=SOX_SAMPLE_MAX+1.?(d)*(SOX_SAMPLE_MAX+1.)>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:(d)*(SOX_SAMPLE_MAX+1.))
#define SOX_SAMPLE_TO_FLOAT_32BIT(d,clips) (float)((d)>SOX_SAMPLE_MAX-64?++(clips),1:((((d)+64)&~127)*(1./(SOX_SAMPLE_MAX+1.))))
void Spline_CaculateM(const double *arr, const int len, double *M, double *h)
{
// double *h = (double *)calloc(sizeof(double), len);
double *b = (double *)calloc(sizeof(double), len);
double *c = (double *)calloc(sizeof(double), len);
double *d = (double *)calloc(sizeof(double), len);
double *u = (double *)calloc(sizeof(double), len);
double *v = (double *)calloc(sizeof(double), len);
double *y = (double *)calloc(sizeof(double), len);
M[0] = M[len-1] = 0;
h[0] = 1.0;
for (int i = 1; i < len; i++) {
h[i] = 1.0;
b[i] = h[i] / (h[i] + h[i - 1]);
c[i] = 1 - b[i];
d[i] = 6 * ((arr[i + 1]- arr[i]) / h[i] - (arr[i] - arr[i - 1]) / h[i - 1]) / (h[i] + h[i - 1]);
}
d[1] -= c[1] * M[0];
d[len - 1] -= b[len - 1] * M[len - 1];
b[len - 1] = 0; c[1] = 0; v[0] = 0;
for (int i = 1; i < len; i++) {
u[i] = 2 - c[i] * v[i - 1];
v[i] = b[i] / u[i];
y[i] = (d[i] - c[i] * y[i - 1]) / u[i];
}
for (int i = 1; i < len; i++) {
M[len - i] = y[len - i] - v[len - i] * M[len - i + 1];
}
free(b);
free(c);
free(d);
free(u);
free(v);
free(y);
}
double Spline(const double *arr, const double *M, const double *h, double spline_x)
{
double p, q, S;
// while (spline_x >= points[k].x) k++;
int k = ceil(spline_x);
p = k - spline_x;
k = k - 1;
q = spline_x - k;
S = (p* p* p* M[k] + q* q* q* M[k + 1]) / (6 * h[k]) + (p* arr[k] + q*arr[k + 1]) / h[k] - h[k] * (p* M[k] + q* M[k + 1]) / 6;
return S;
}
int main(int argc, char *argv[])
{
FILE *fin = fopen(argv[1], "r");
FILE *fout = fopen(argv[2], "wb+");
double data[6];
double M[6];
double h[6];
short s[6];
int clip = 0;
while (1)
{
int len = fread(s, sizeof(short), 6, fin);
for (int i = 0; i < 6; i++) {
data[i] = SOX_SAMPLE_TO_FLOAT_32BIT(s[i] << 16, clip);
printf("%lf %d ", data[i], s[i]);
}
Spline_CaculateM(data, 6, M, h);
double ret = Spline(data, M, h, 0.5);
short new = (SOX_FLOAT_32BIT_TO_SAMPLE(ret, clip)) >> 16;
printf("(%lf, %d)\n", ret, new);
fwrite(&s[0], sizeof(short), 1, fout);
fwrite(&new, sizeof(short), 1, fout);
if (feof(fin))
break;
fseek(fin, -5*sizeof(short), SEEK_CUR);
}
fclose(fin);
fclose(fout);
return 0;
}
基于三次样条插值(自然边界)实现的上采样
最新推荐文章于 2023-10-16 11:30:12 发布
该程序定义了一系列宏来处理32位浮点数与样本值之间的转换,并使用样条插值方法进行数据计算。通过Spline_CaculateM函数计算样条多项式,然后在Spline函数中应用这些多项式来获取特定x值的插值。主函数中,程序从文件读取样本数据,进行转换和插值计算,然后将结果写入新文件。
摘要由CSDN通过智能技术生成