1 #include <math.h>
2 #include <cstdlib>
3 #include <cstring>
4 #include "grain.h"
5 #include "sbsms.h"
6 #include "real.h"
7 #include "utils.h"
8
9 #include <map>
10 using namespace std;
11
12 namespace _sbsms_ {
13
GrainAllocator(int N,int N2,int type)14 GrainAllocator :: GrainAllocator(int N, int N2, int type)
15 {
16 this->N = N;
17 this->N2 = N2;
18 this->type = type;
19
20 switch(N) {
21 case 128:
22 fftPlan = &fft128;
23 ifftPlan = &ifft128;
24 break;
25 case 256:
26 fftPlan = &fft256;
27 ifftPlan = &ifft256;
28 break;
29 case 384:
30 fftPlan = &fft384;
31 //ifftPlan = &ifft384;
32 break;
33 case 512:
34 fftPlan = &fft512;
35 //ifftPlan = &ifft512;
36 break;
37 default:
38 abort();
39 break;
40 }
41
42 int k1 = (N-N2)/2;
43
44 w = (float*)calloc(N,sizeof(float));
45 for(int k=0;k<N2;k++) {
46 if(type == hann) {
47 w[k+k1] = 0.5f*(1.0f - cos((float)k/(float)N2*TWOPI));
48 } else if(type == hannpoisson) {
49 w[k+k1] = 0.5f*(1.0f - cos((float)k/(float)N2*TWOPI)) * exp(-2.0f*fabs((float)(k-N2/2))/(float)N2);
50 }
51 }
52
53 W = (audio*) calloc(N,sizeof(audio));
54 for(int k=0;k<N;k++) {
55 W[k][0] = w[k] * 2.638502561913447f/(float)N2;
56 }
57
58 fftPlan(W);
59 }
60
~GrainAllocator()61 GrainAllocator :: ~GrainAllocator()
62 {
63 free(w);
64 free(W);
65 }
66
create()67 grain* GrainAllocator :: create()
68 {
69 grain *g = new grain(N,N2);
70 g->refCount = 0;
71 g->fftPlan = fftPlan;
72 g->ifftPlan = ifftPlan;
73 g->w = w;
74 return g;
75 }
76
reference(grain * g)77 void GrainAllocator :: reference(grain *g)
78 {
79 g->refCount++;
80 }
81
forget(grain * g)82 void GrainAllocator :: forget(grain *g)
83 {
84 g->refCount--;
85 if(g->refCount <= 0) {
86 delete g;
87 }
88 }
89
grain(int N,int N2)90 grain :: grain(int N, int N2)
91 {
92 this->N = N;
93 this->synthScale = 1.0f / (float)N2;
94 x = (audio*) calloc(N,sizeof(audio));
95 }
96
~grain()97 grain :: ~grain()
98 {
99 free(x);
100 }
101
analyze()102 void grain :: analyze()
103 {
104 float *x = (float*)this->x;
105 float *end = x + (N<<1);
106 float *w = this->w;
107 while(x != end) {
108 *(x++) *= *w;
109 *(x++) *= *(w++);
110 }
111
112 fftPlan(this->x);
113 }
114
synthesize()115 void grain :: synthesize()
116 {
117 ifftPlan(x);
118 for(int k=0;k<N;k++) {
119 for(int c=0;c<2;c++) {
120 x[k][c] *= w[k] * synthScale;
121 }
122 }
123 }
124
downsample(grain * g2)125 void grain :: downsample(grain *g2)
126 {
127 grain *g = this;
128
129 int N2 = N/2;
130 int N4 = N/4;
131 for(int c=0;c<2;c++) {
132 for(int k=0;k<N4;k++) {
133 g2->x[k][c] = 0.5f * g->x[k][c];
134 }
135 g2->x[N4][c] = 0.25f * (g->x[N4][c] + g->x[N-N4][c]);
136 for(int k=N4+1;k<N2;k++) {
137 g2->x[k][c] = 0.5f * g->x[k+N2][c];
138 }
139 }
140 }
141
142 }
143