1 // This file is part of the FXT library.
2 // Copyright (C) 2010, 2011 Joerg Arndt
3 // License: GNU General Public License version 3 or later,
4 // see the file COPYING.txt in the main directory.
5
6 #include "fxttypes.h"
7
8 //#include "jjassert.h"
9
10 #include <cmath>
11
sinc(double x)12 static inline double sinc(double x)
13 // return sin(pi*x)/(pi*x)
14 {
15 if ( x==0 ) return 1.0;
16 else
17 {
18 x *= M_PI;
19 return sin(x) / x;
20 }
21 }
22 // -------------------------
23
24 ulong
resample_sinc(const double * a,ulong an,double af,double * b,double bf,ulong bn)25 resample_sinc(const double *a, ulong an, double af, double *b, double bf, ulong bn)
26 // Input: an samples with freq af.
27 // Output: bn samples with freq bf.
28 // Return number of samples produced (<=bn).
29 // Must have: v>0
30 {
31 const double v = af/bf; // freq ratio
32 // jjassert( v>0 );
33
34 const double dan = (double)an;
35 ulong n = 1 + (ulong)floor(dan/v); // # of samples produced ??? correct
36 if ( n>bn ) n = bn;
37
38 for (ulong j=0; j<n; j++)
39 {
40 double s = (double)j * v;
41 ulong i = (ulong)s;
42 double r = s - (double)i;
43 // const double r = frac( j*v ); // ??
44
45 b[j]=
46 (a[i] *sinc(2+r)+
47 a[i+1]*sinc(1+r)+
48 a[i+2]*sinc(r)+
49 a[i+3]*sinc(1-r)+
50 a[i+4]*sinc(2-r)+
51 a[i+5]*sinc(3-r)); //*0.5;
52 }
53
54 return n;
55 }
56 // -------------------------
57
58
59 ulong
sample_up_linear(const double * f,ulong nf,double v,double * g,ulong ng)60 sample_up_linear(const double *f, ulong nf, double v, double *g, ulong ng)
61 //
62 // Uses linear interpolation (if noninteger v).
63 // Return number of values produced.
64 // Must have: v<=1.0
65 //
66 {
67 // jjassert( v<=1.0 );
68
69 ulong n = (ulong)floor( (double)nf / v); // n values will be produced
70 if ( n>ng ) n = ng;
71
72 ulong gi,fi;
73 if ( v==floor(0.5+v) ) // ----- integer value
74 {
75 const ulong vi=ulong(floor(0.5+v));
76 for (fi=0,gi=0; gi<n; gi++,fi+=vi) g[gi] = f[fi];
77 }
78 else // ----- non integer value
79 {
80 double dfi, frac;
81 for (dfi=0,gi=0; gi<n; gi++,dfi+=v)
82 {
83 fi = ulong(dfi);
84 frac = dfi-double(fi);
85
86 // linear interpolation:
87 g[gi] = f[fi] + (f[fi+1]-f[fi])*frac;
88 }
89 }
90
91 return n;
92 }
93 // -------------------------
94
95
96 ulong
sample_down_linear(const double * f,ulong nf,double v,double * g,ulong ng)97 sample_down_linear(const double *f, ulong nf, double v, double *g, ulong ng)
98 //
99 // Uses linear interpolation (if noninteger v).
100 // Return number of values produced.
101 // Must have: v>=1.0
102 //
103 {
104 // jjassert( v>=1.0 );
105
106 ulong n = (ulong)floor( (double)nf / v ); // n values will be produced
107 if ( n>ng ) n = ng;
108
109 ulong gi,fi;
110 if ( v==floor(0.5+v) ) // ----- integer value
111 {
112 const ulong vi = ulong(floor(0.5+v));
113 for (fi=0,gi=0; gi<n; gi++,fi+=vi) g[gi] = f[fi];
114 }
115 else // ----- non integer value
116 {
117 double dfi, frac;
118 for (dfi=0,gi=0; gi<n; gi++,dfi+=v)
119 {
120 fi = ulong(dfi);
121 frac = dfi-double(fi);
122
123 // linear interpolation:
124 g[gi] = f[fi] + (f[fi+1]-f[fi])*frac;
125 }
126 }
127
128 return n;
129 }
130 // -------------------------
131
132
133 ulong
resample_linear(const double * f,ulong nf,double v,double * g,ulong ng)134 resample_linear(const double *f, ulong nf, double v, double *g, ulong ng)
135 //
136 // Use linear interpolation (if noninteger v).
137 // Return number of values produced.
138 //
139 {
140 if ( v>=1.0 ) return sample_down_linear(f,nf,v,g,ng);
141 else return sample_up_linear(f,nf,v,g,ng);
142 }
143 // -------------------------
144