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