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