1 /* Copyright (C) 2007 Gabriel Maldonado
2
3 Csound is free software; you can redistribute it
4 and/or modify it under the terms of the GNU Lesser General Public
5 License as published by the Free Software Foundation; either
6 version 2.1 of the License, or (at your option) any later version.
7
8 Csound is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU Lesser General Public License for more details.
12
13 You should have received a copy of the GNU Lesser General Public
14 License along with Csound; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16 02110-1301 USA
17 */
18 //#include "csdl.h"
19 #include "csoundCore.h"
20 #include "interlocks.h"
21
22 typedef struct {
23 OPDS h;
24 MYFLT *out, *xindex, *xinterpoint, *xtabndx1, *xtabndx2,
25 *argums[VARGMAX];
26 MYFLT *table[VARGMAX];
27 int32_t length;
28 int64_t numOfTabs;
29 } TABMORPH;
30
tabmorph_set(CSOUND * csound,TABMORPH * p)31 static int32_t tabmorph_set (CSOUND *csound, TABMORPH *p) /*Gab 13-March-2005 */
32 {
33 int32_t numOfTabs,j;
34 MYFLT **argp, *first_table = NULL;
35
36 FUNC *ftp;
37 int64_t flength = 0;
38
39 numOfTabs = p->numOfTabs =((p->INCOUNT-4)); /* count segs & alloc if nec */
40 argp = p->argums;
41 for (j=0; j< numOfTabs; j++) {
42 if (UNLIKELY((ftp = csound->FTnp2Find(csound, *argp++)) == NULL))
43 return csound->InitError(csound, Str("tabmorph: invalid table number"));
44 if (UNLIKELY(ftp->flen != flength && flength != 0))
45 return
46 csound->InitError(csound,
47 Str("tabmorph: all tables must have the "
48 "same length!"));
49 flength = ftp->flen;
50 if (j==0) first_table = ftp->ftable;
51 p->table[j] = ftp->ftable;
52 }
53 p->table[j] = first_table; /* for interpolation */
54 p->length = flength;
55 return OK;
56 }
57
tabmorph(CSOUND * csound,TABMORPH * p)58 static int32_t tabmorph(CSOUND *csound, TABMORPH *p)
59 {
60 IGN(csound);
61 MYFLT /* index, index_frac, */ tabndx1, tabndx2, tabndx1frac, tabndx2frac;
62 MYFLT tab1val1,tab1val2, tab2val1, tab2val2, interpoint, val1, val2;
63 int64_t index_int;
64 int32_t tabndx1int, tabndx2int;
65 index_int = (int32_t) *p->xindex % p->length;
66
67 tabndx1 = *p->xtabndx1;
68 tabndx1int = (int32_t) tabndx1;
69 tabndx1frac = tabndx1 - tabndx1int;
70 tabndx1int %= p->numOfTabs;
71 tab1val1 = (p->table[tabndx1int ])[index_int];
72 tab1val2 = (p->table[tabndx1int+1])[index_int];
73 val1 = tab1val1 * (1-tabndx1frac) + tab1val2 * tabndx1frac;
74
75 tabndx2 = *p->xtabndx2;
76 tabndx2int = (int32_t) tabndx2;
77 tabndx2frac = tabndx2 - tabndx2int;
78 tabndx2int %= p->numOfTabs;
79 tab2val1 = (p->table[tabndx2int ])[index_int];
80 tab2val2 = (p->table[tabndx2int+1])[index_int];
81 val2 = tab2val1 * (1-tabndx2frac) + tab2val2 * tabndx2frac;
82
83 interpoint = *p->xinterpoint;
84 interpoint = (interpoint < 0 ? 0 : (interpoint > 1.0 ? 1.0 : interpoint));
85 /* interpoint -= (int32_t) interpoint; to limit to zero to 1 range */
86
87 *p->out = val1 * (1 - interpoint) + val2 * interpoint;
88 return OK;
89 }
90
tabmorphi(CSOUND * csound,TABMORPH * p)91 static int32_t tabmorphi(CSOUND *csound, TABMORPH *p) /* interpolation */
92 {
93 IGN(csound);
94 MYFLT index, index_frac, tabndx1, tabndx2, tabndx1frac, tabndx2frac;
95 MYFLT tab1val1a,tab1val2a, tab2val1a, tab2val2a, interpoint, val1, val2;
96 MYFLT val1a, val2a, val1b, val2b, tab1val1b,tab1val2b, tab2val1b, tab2val2b;
97 int64_t index_int;
98 int32_t tabndx1int, tabndx2int;
99
100 index = *p->xindex;
101 index_int = (int32_t) index;
102 index_frac = index - index_int;
103 index_int %= p->length;
104
105 tabndx1 = *p->xtabndx1;
106 tabndx1int = (int32_t) tabndx1;
107 tabndx1frac = tabndx1 - tabndx1int;
108 tabndx1int %= p->numOfTabs;
109
110 tab1val1a = (p->table[tabndx1int ])[index_int];
111 tab1val2a = (p->table[tabndx1int+1])[index_int];
112 val1a = tab1val1a * (1-tabndx1frac) + tab1val2a * tabndx1frac;
113
114 tab1val1b = (p->table[tabndx1int ])[index_int+1];
115 tab1val2b = (p->table[tabndx1int+1])[index_int+1];
116 val1b = tab1val1b * (1-tabndx1frac) + tab1val2b * tabndx1frac;
117
118 val1 = val1a + (val1b-val1a) * index_frac;
119 /*--------------*/
120 tabndx2 = *p->xtabndx2;
121 tabndx2int = (int32_t) tabndx2;
122 tabndx2frac = tabndx2 - tabndx2int;
123 tabndx2int %= p->numOfTabs;
124
125 tab2val1a = (p->table[tabndx2int ])[index_int];
126 tab2val2a = (p->table[tabndx2int+1])[index_int];
127 val2a = tab2val1a * (1-tabndx2frac) + tab2val2a * tabndx2frac;
128
129 tab2val1b = (p->table[tabndx2int ])[index_int+1];
130 tab2val2b = (p->table[tabndx2int+1])[index_int+1];
131 val2b = tab2val1b * (1-tabndx2frac) + tab2val2b * tabndx2frac;
132
133 val2 = val2a + (val2b-val2a) * index_frac;
134
135 interpoint = *p->xinterpoint;
136 interpoint -= (int32_t) interpoint; /* to limit to zero to 1 range */
137
138 *p->out = val1 * (1 - interpoint) + val2 * interpoint;
139 return OK;
140 }
141
142
atabmorphia(CSOUND * csound,TABMORPH * p)143 static int32_t atabmorphia(CSOUND *csound, TABMORPH *p) /* all arguments at a-rate */
144 {
145 IGN(csound);
146 uint32_t offset = p->h.insdshead->ksmps_offset;
147 uint32_t early = p->h.insdshead->ksmps_no_end;
148 uint32_t n, nsmps = CS_KSMPS;
149 int32_t tablen = p->length;
150 MYFLT *out = p->out;
151 MYFLT *index = p->xindex;
152 MYFLT *interpoint = p->xinterpoint;
153 MYFLT *tabndx1 = p->xtabndx1;
154 MYFLT *tabndx2 = p->xtabndx2;
155
156 if (UNLIKELY(offset)) memset(out, '\0', offset*sizeof(MYFLT));
157 if (UNLIKELY(early)) {
158 nsmps -= early;
159 memset(&out[nsmps], '\0', early*sizeof(MYFLT));
160 }
161 for (n=offset; n<nsmps; n++) {
162 MYFLT index_frac,tabndx1frac, tabndx2frac;
163 MYFLT tab1val1a,tab1val2a, tab2val1a, tab2val2a, val1, val2;
164 MYFLT val1a, val2a, val1b, val2b, tab1val1b,tab1val2b, tab2val1b, tab2val2b;
165 int64_t index_int;
166 int32_t tabndx1int, tabndx2int;
167 MYFLT ndx = index[n] * tablen;
168 index_int = (int32_t) ndx;
169 index_frac = ndx - index_int;
170 index_int %= tablen;
171
172 tabndx1int = (int32_t) tabndx1[n];
173 tabndx1frac = tabndx1[n] - tabndx1int;
174 tabndx1int %= p->numOfTabs;
175
176 tab1val1a = (p->table[tabndx1int ])[index_int];
177 tab1val2a = (p->table[tabndx1int+1])[index_int];
178 val1a = tab1val1a * (1-tabndx1frac) + tab1val2a * tabndx1frac;
179
180 tab1val1b = (p->table[tabndx1int ])[index_int+1];
181 tab1val2b = (p->table[tabndx1int+1])[index_int+1];
182 val1b = tab1val1b * (1-tabndx1frac) + tab1val2b * tabndx1frac;
183
184 val1 = val1a + (val1b-val1a) * index_frac;
185 /*--------------*/
186
187 tabndx2int = (int32_t) tabndx2[n];
188 tabndx2frac = tabndx2[n] - tabndx2int;
189 tabndx2int %= p->numOfTabs;
190
191 tab2val1a = (p->table[tabndx2int ])[index_int];
192 tab2val2a = (p->table[tabndx2int+1])[index_int];
193 val2a = tab2val1a * (1-tabndx2frac) + tab2val2a * tabndx2frac;
194
195 tab2val1b = (p->table[tabndx2int ])[index_int+1];
196 tab2val2b = (p->table[tabndx2int+1])[index_int+1];
197 val2b = tab2val1b * (1-tabndx2frac) + tab2val2b * tabndx2frac;
198
199 val2 = val2a + (val2b-val2a) * index_frac;
200
201 interpoint[n] -= (int32_t) interpoint[n]; /* to limit to zero to 1 range */
202
203 out[n] = val1 * (1 - interpoint[n]) + val2 * interpoint[n];
204 }
205 return OK;
206 }
207
208
209 /* all args k-rate except out and table index */
atabmorphi(CSOUND * csound,TABMORPH * p)210 static int32_t atabmorphi(CSOUND *csound, TABMORPH *p)
211 {
212 IGN(csound);
213 uint32_t offset = p->h.insdshead->ksmps_offset;
214 uint32_t early = p->h.insdshead->ksmps_no_end;
215 uint32_t n, nsmps = CS_KSMPS;
216 int32_t tablen = p->length;
217
218 MYFLT *out = p->out;
219 MYFLT *index;
220 MYFLT tabndx1, tabndx2, tabndx1frac, tabndx2frac, interpoint;
221 int32_t tabndx1int, tabndx2int;
222
223 tabndx1 = *p->xtabndx1;
224 tabndx1int = (int32_t) tabndx1;
225 tabndx1frac = tabndx1 - tabndx1int;
226 tabndx1int %= p->numOfTabs;
227 index = p->xindex;
228
229
230 /*--------------*/
231 tabndx2 = *p->xtabndx2;
232 tabndx2int = (int32_t) tabndx2;
233 tabndx2frac = tabndx2 - tabndx2int;
234 tabndx2int %= p->numOfTabs;
235
236 interpoint = *p->xinterpoint;
237 interpoint -= (int32_t) interpoint; /* to limit to zero to 1 range */
238
239 if (UNLIKELY(offset)) memset(out, '\0', offset*sizeof(MYFLT));
240 if (UNLIKELY(early)) {
241 nsmps -= early;
242 memset(&out[nsmps], '\0', early*sizeof(MYFLT));
243 }
244 for (n=offset; n<nsmps; n++) {
245 MYFLT index_frac, tab1val1a,tab1val2a, tab2val1a, tab2val2a, val1, val2;
246 MYFLT val1a, val2a, val1b, val2b, tab1val1b,tab1val2b, tab2val1b, tab2val2b;
247 int64_t index_int;
248 MYFLT ndx = index[n] * tablen;
249
250 index_int = (int32_t) ndx;
251 index_frac = ndx - index_int;
252 index_int %= tablen;
253
254
255 tab1val1a = (p->table[tabndx1int ])[index_int];
256 tab1val2a = (p->table[tabndx1int+1])[index_int];
257 val1a = tab1val1a * (1-tabndx1frac) + tab1val2a * tabndx1frac;
258
259 tab1val1b = (p->table[tabndx1int ])[index_int+1];
260 tab1val2b = (p->table[tabndx1int+1])[index_int+1];
261 val1b = tab1val1b * (1-tabndx1frac) + tab1val2b * tabndx1frac;
262
263 val1 = val1a + (val1b-val1a) * index_frac;
264
265 tab2val1a = (p->table[tabndx2int ])[index_int];
266 tab2val2a = (p->table[tabndx2int+1])[index_int];
267 val2a = tab2val1a * (1-tabndx2frac) + tab2val2a * tabndx2frac;
268
269 tab2val1b = (p->table[tabndx2int ])[index_int+1];
270 tab2val2b = (p->table[tabndx2int+1])[index_int+1];
271 val2b = tab2val1b * (1-tabndx2frac) + tab2val2b * tabndx2frac;
272
273 val2 = val2a + (val2b-val2a) * index_frac;
274
275 out[n] = val1 * (1 - interpoint) + val2 * interpoint;
276 }
277 return OK;
278 }
279
280
281 #define S(x) sizeof(x)
282
283 OENTRY tabmoroph_localops[] = {
284
285 { "tabmorph", S(TABMORPH), TR, 3, "k", "kkkkm",
286 (SUBR) tabmorph_set, (SUBR) tabmorph, NULL},
287 { "tabmorphi", S(TABMORPH), TR, 3, "k", "kkkkm",
288 (SUBR) tabmorph_set, (SUBR) tabmorphi, NULL},
289 { "tabmorpha", S(TABMORPH), TR, 3, "a", "aaaam",
290 (SUBR) tabmorph_set, (SUBR) atabmorphia},
291 { "tabmorphak",S(TABMORPH), TR, 3, "a", "akkkm",
292 (SUBR) tabmorph_set, (SUBR) atabmorphi }
293
294 };
295
tabmorph_init_(CSOUND * csound)296 int32_t tabmorph_init_(CSOUND *csound) {
297 return
298 csound->AppendOpcodes(csound, &(tabmoroph_localops[0]),
299 (int32_t) (sizeof(tabmoroph_localops) / sizeof(OENTRY)));
300 }
301