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 
19 #include "csoundCore.h"
20 #include "interlocks.h"
21 
22 /* (Shouldn't there be global decl's for these?) */
23 #define INCR (0.001f)
24 
25 /* -------------------------------------------------------------------- */
26 
27 typedef struct {
28         OPDS    h;
29         MYFLT    *xfn, *outargs[VARGMAX];
30         int32_t nargs;
31         int64_t  pfn;
32         MYFLT   *ftable;
33 } MTABLE1;
34 
35 
mtable1_set(CSOUND * csound,MTABLE1 * p)36 static int32_t  mtable1_set(CSOUND *csound, MTABLE1 *p) /* mtab by G.Maldonado */
37 {
38     FUNC *ftp;
39     if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->xfn)) == NULL))
40       return csound->InitError(csound, Str("vtable1: incorrect table number"));
41     p->ftable = ftp->ftable;
42     p->nargs = p->INOCOUNT-1;
43     p->pfn = (int64_t) *p->xfn;
44     return OK;
45 }
46 
mtable1_k(CSOUND * csound,MTABLE1 * p)47 static int32_t  mtable1_k(CSOUND *csound, MTABLE1 *p)
48 {
49     int32_t j, nargs = p->nargs;
50     MYFLT **out = p->outargs;
51     MYFLT *table;
52     if (p->pfn != (int64_t)*p->xfn) {
53       FUNC *ftp;
54       if (UNLIKELY( (ftp = csound->FTFindP(csound, p->xfn) ) == NULL))
55         return csound->PerfError(csound, &(p->h),
56                                  Str("vtable1: incorrect table number"));
57       p->pfn = (int64_t)*p->xfn;
58       p->ftable = ftp->ftable;
59     }
60     table= p->ftable;
61     for (j=0; j < nargs; j++)
62       *out[j] =  table[j];
63     return OK;
64 }
65 
66 /* -------------------------------------------------------------------- */
67 
68 typedef struct {
69         OPDS    h;
70         MYFLT   *kstartChan, *argums[VARGMAX];
71         int32_t numChans, narg;
72 } INRANGE;
73 
inRange_i(CSOUND * csound,INRANGE * p)74 static int32_t inRange_i(CSOUND *csound, INRANGE *p)
75 {
76     p->narg = p->INOCOUNT-1;
77     if (UNLIKELY(!csound->oparms->sfread))
78       return csound->InitError(csound, Str("inrg: audio input is not enabled"));
79     p->numChans = csound->GetNchnls(csound);
80     return OK;
81 }
82 
inRange(CSOUND * csound,INRANGE * p)83 static int32_t inRange(CSOUND *csound, INRANGE *p)
84 {
85     uint32_t offset = p->h.insdshead->ksmps_offset;
86     uint32_t early  = p->h.insdshead->ksmps_no_end;
87     uint32_t j, nsmps = CS_KSMPS;
88     int32_t i;
89     MYFLT *ara[VARGMAX];
90     int32_t startChan = (int32_t) *p->kstartChan -1;
91     MYFLT *sp = csound->spin + startChan;
92     int32_t narg = p->narg, numchans = p->numChans;
93 
94     if (UNLIKELY(startChan < 0))
95       return csound->PerfError(csound, &(p->h),
96                                Str("inrg: channel number cannot be < 1 "
97                                    "(1 is the first channel)"));
98 
99     if (UNLIKELY(early)) nsmps -= early;
100     for (i = 0; i < narg; i++) {
101       ara[i] = p->argums[i];
102       if (UNLIKELY(offset)) memset(ara[i], '\0', offset*sizeof(MYFLT));
103       if (UNLIKELY(early)) memset(&ara[i][nsmps], '\0', early*sizeof(MYFLT));
104       ara[i] += offset;
105     }
106     for (j=offset; j<nsmps; j++)  {
107       for (i=0; i<narg; i++) {
108         *ara[i]++ = sp[i];
109       }
110       sp += numchans;
111     }
112     return OK;
113 
114 }
115 
116 #include "Opcodes/uggab.h"
117 
lposc_set(CSOUND * csound,LPOSC * p)118 static int32_t lposc_set(CSOUND *csound, LPOSC *p)
119 {
120     FUNC *ftp;
121     MYFLT  loop, end, looplength;
122     if ((ftp = csound->FTnp2Find(csound, p->ift)) == NULL)
123       return csound->InitError(csound, Str("invalid function"));
124     if (UNLIKELY(!(p->fsr=ftp->gen01args.sample_rate))){
125        csound->Message(csound,
126                        Str("lposc: no sample rate stored in function;"
127                            " assuming=sr\n"));
128        p->fsr=CS_ESR;
129     }
130     p->ftp    = ftp;
131     p->tablen = ftp->flen;
132     /* changed from
133        p->phs    = *p->iphs * p->tablen;   */
134 
135     if ((loop = *p->kloop) < 0) loop=FL(0.0);
136     if ((end = *p->kend) > p->tablen || end <=0 ) end = (MYFLT)p->tablen;
137     looplength = end - loop;
138 
139     if (*p->iphs >= 0)
140       p->phs = *p->iphs;
141     while (p->phs >= end)
142       p->phs -= looplength;
143     return OK;
144 }
145 
lposca(CSOUND * csound,LPOSC * p)146 static int32_t lposca(CSOUND *csound, LPOSC *p)
147 {
148     double  *phs= &p->phs;
149     double  si= *p->freq * (p->fsr/CS_ESR);
150     MYFLT   *out = p->out,  *amp=p->amp;
151     MYFLT   *ft =  p->ftp->ftable, *curr_samp;
152     MYFLT   fract;
153     uint32_t offset = p->h.insdshead->ksmps_offset;
154     uint32_t early  = p->h.insdshead->ksmps_no_end;
155     uint32_t n, nsmps = CS_KSMPS;
156     int32   loop, end, looplength /* = p->looplength */ ;
157 
158     if ((loop = (int64_t) *p->kloop) < 0) loop=0;/* gab */
159     else if (loop > p->tablen-3) loop = p->tablen-3;
160     if ((end = (int64_t) *p->kend) > p->tablen-1 ) end = p->tablen - 1;
161     else if (end <= 2) end = 2;
162     if (end < loop+2) end = loop + 2;
163     looplength = end - loop;
164     if (UNLIKELY(offset)) memset(out, '\0', offset*sizeof(MYFLT));
165     if (UNLIKELY(early)) {
166       nsmps -= early;
167       memset(&out[nsmps], '\0', early*sizeof(MYFLT));
168     }
169     for (n=offset; n<nsmps; n++) {
170       curr_samp= ft + (int64_t)*phs;
171       fract= (MYFLT)(*phs - (int64_t)*phs);
172       out[n] = amp[n] * (*curr_samp +(*(curr_samp+1)-*curr_samp)*fract);
173       *phs += si;
174       while (*phs  >= end) *phs -= looplength;
175       while (*phs  < loop) *phs += looplength;
176     }
177     return OK;
178 }
179 
180 /* -------------------------------------------------------------------- */
181 
182 typedef struct  {
183         OPDS    h;
184         MYFLT   *out1, *out2, *amp, *freq, *kloop, *kend, *ift, *iphs;
185         int64_t    tablen;
186         MYFLT   fsr;
187         MYFLT *ft; /*table */
188         double  phs, fsrUPsr /* , looplength */;
189         int64_t    phs_int;
190 } LPOSC_ST;
191 
lposc_stereo_set(CSOUND * csound,LPOSC_ST * p)192 static int32_t lposc_stereo_set(CSOUND *csound, LPOSC_ST *p)
193 {
194     FUNC *ftp;
195     double  loop, end, looplength, fsr;
196     if (UNLIKELY((ftp = csound->FTnp2Find(csound, p->ift)) == NULL))
197       return csound->InitError(csound, Str("invalid function"));
198     if (UNLIKELY(!(fsr = ftp->gen01args.sample_rate))) {
199       csound->Message(csound, Str("lposcil: no sample rate stored in function;"
200                                   " assuming=sr\n"));
201       p->fsr=CS_ESR;
202     }
203     p->fsrUPsr = fsr/CS_ESR;
204     p->ft     = ftp->ftable;
205     p->tablen = ftp->flen/2;
206     /* changed from
207        p->phs    = *p->iphs * p->tablen;   */
208     if ((loop = *p->kloop) < 0) loop=0;/* gab */
209     else if (loop > p->tablen-3) loop = p->tablen-3;
210     if ((end = *p->kend) > p->tablen-1 ) end = p->tablen - 1;
211     else if (end <= 2) end = 2;
212     if (end < loop+2) end = loop + 2;
213     looplength = end - loop;
214 
215     if (*p->iphs >= 0)
216       p->phs_int = (int64_t) (p->phs = *p->iphs);
217 
218     while (p->phs >= end)
219       p->phs_int = (int64_t) (p->phs -= looplength);
220     return OK;
221 }
222 
lposca_stereo(CSOUND * csound,LPOSC_ST * p)223 static int32_t lposca_stereo(CSOUND *csound, LPOSC_ST *p) /* stereo lposcinta */
224 {
225     IGN(csound);
226     double  *phs= &p->phs,   si= *p->freq * p->fsrUPsr;
227     MYFLT   *out1 = p->out1, *out2 = p->out2, *amp=p->amp;
228     MYFLT   *ft =  p->ft;
229     uint32_t offset = p->h.insdshead->ksmps_offset;
230     uint32_t early  = p->h.insdshead->ksmps_no_end;
231     uint32_t n, nsmps = CS_KSMPS;
232     int32    loop, end, looplength /* = p->looplength */ ;
233     if ((loop = (int64_t) *p->kloop) < 0) loop=0;/* gab */
234     else if (loop > p->tablen-3) loop = p->tablen-3;
235     if ((end = (int64_t) *p->kend) > p->tablen-1 ) end = p->tablen - 1;
236     else if (end <= 2) end = 2;
237     if (end < loop+2) end = loop + 2;
238     looplength = end - loop;
239     if (UNLIKELY(offset)) {
240       memset(out1, '\0', offset*sizeof(MYFLT));
241       memset(out2, '\0', offset*sizeof(MYFLT));
242     }
243     if (UNLIKELY(early)) {
244       nsmps -= early;
245       memset(&out1[nsmps], '\0', early*sizeof(MYFLT));
246       memset(&out2[nsmps], '\0', early*sizeof(MYFLT));
247     }
248     for (n=offset; n<nsmps; n++) {
249       double fract;
250       MYFLT *curr_samp1 = ft + (int64_t) *phs * 2;
251       MYFLT *curr_samp2 = curr_samp1 +1;
252       fract= *phs - (int64_t) *phs;
253       out1[n] = amp[n] * (MYFLT)(*curr_samp1 +(*(curr_samp1+2)-*curr_samp1)*fract);
254       out2[n] = amp[n] * (MYFLT)(*curr_samp2 +(*(curr_samp2+2)-*curr_samp2)*fract);
255       *phs += si;
256       while (*phs  >= end) *phs -= looplength;
257       while (*phs  < loop) *phs += looplength;
258     }
259     return OK;
260 }
261 
lposca_stereo_no_trasp(CSOUND * csound,LPOSC_ST * p)262 static int32_t lposca_stereo_no_trasp(CSOUND *csound, LPOSC_ST *p)
263 {    /* transposition is allowed only */
264      /*in integer values (twice, three times etc.) so it is faster */
265     IGN(csound);
266     int64_t    *phs = &p->phs_int, si = (int64_t) *p->freq;
267     MYFLT   *out1 = p->out1, *out2 = p->out2, *amp=p->amp;
268     MYFLT   *ft =  p->ft;
269     uint32_t offset = p->h.insdshead->ksmps_offset;
270     uint32_t early  = p->h.insdshead->ksmps_no_end;
271     uint32_t n, nsmps = CS_KSMPS;
272     int64_t    loop, end, looplength /* = p->looplength */ ;
273     if ((loop = (int64_t) *p->kloop) < 0) loop=0;/* gab */
274     else if (loop > p->tablen-3) loop = p->tablen-3;
275     if ((end = (int64_t) *p->kend) > p->tablen-1 ) end = p->tablen - 1;
276     else if (end <= 2) end = 2;
277     if (end < loop+2) end = loop + 2;
278     looplength = end - loop;
279 
280     if (UNLIKELY(offset)) {
281       memset(out1, '\0', offset*sizeof(MYFLT));
282       memset(out2, '\0', offset*sizeof(MYFLT));
283     }
284     if (UNLIKELY(early)) {
285       nsmps -= early;
286       memset(&out1[nsmps], '\0', early*sizeof(MYFLT));
287       memset(&out2[nsmps], '\0', early*sizeof(MYFLT));
288     }
289     for (n=offset; n<nsmps; n++) {
290       MYFLT *curr_samp1 = ft + *phs * 2;
291       out1[n] = amp[n] * (MYFLT) *curr_samp1 ;
292       out2[n] = amp[n] * (MYFLT) *(curr_samp1+1) ;
293       *phs += si;
294       while (*phs  >= end) *phs -= looplength;
295       while (*phs  < loop) *phs += looplength;
296     }
297     return OK;
298 }
299 
300 
301 /* -------------------------------------------------------------------- */
302 
303 #include "vectorial.h"
304 
305 typedef struct  {       /* gab d5*/
306         OPDS    h;
307         MYFLT   *out, *ktrig, *min, *max;
308         MYFLT   lastvalue;
309 } TRANGERAND;
310 
trRangeRand(CSOUND * csound,TRANGERAND * p)311 static int32_t trRangeRand(CSOUND *csound, TRANGERAND *p)
312 { /* gab d5*/
313     if (*p->ktrig)
314       *p->out = p->lastvalue = randGab * (*p->max - *p->min) + *p->min;
315     else
316       *p->out = p->lastvalue;
317     return OK;
318 }
319 
320 
321 /* -------------------------------------------------------------------- */
322 /* Note: this opcode has been left out because it is undocumented */
323 
324 #if 0
325 typedef struct
326 {
327      OPDS    h;
328      MYFLT   *rcar, *rmod;
329      MYFLT   *kfreq_max, *kfreq_min, *kband_max, *kband_min;
330 } DSH;
331 
332 
333 
334 static int32_t dashow(CSOUND *csound, DSH *p)
335 {
336     MYFLT range = *p->kband_max - *p->kband_min;
337     if (range != FL(0.0))
338       *p->rmod = (*p->kfreq_max - *p->kfreq_min) / range;
339     else
340       *p->rmod = FL(0.0);
341     *p->rcar = (*p->kfreq_max - (*p->kband_max * *p->rmod));
342 
343     if (*p->rmod <= FL(0.0)) *p->rmod = FABS (*p->rmod);
344     if (*p->rcar <= FL(0.0)) *p->rcar = FABS (*p->rcar);
345     return OK;
346 }
347 #endif
348 
349 /* -------------------------------------------------------------------- */
350 
351 
352 #define S(x)    sizeof(x)
353 
354 static OENTRY localops[] = {
355   { "vtable1k",       S(MTABLE1),         TR, 3,  "",  "kz",
356                   (SUBR)mtable1_set,      (SUBR)mtable1_k,        (SUBR) NULL },
357   { "trandom",        S(TRANGERAND),          0,    2,  "k", "kkk",
358                     NULL,                                   (SUBR)trRangeRand },
359   { "lposcila", S(LPOSC),      TR, 3, "a", "akkkio",
360                                            (SUBR)lposc_set, (SUBR)lposca},
361   { "lposcilsa", S(LPOSC_ST),  TR, 3, "aa","akkkio",
362                              (SUBR)lposc_stereo_set, (SUBR)lposca_stereo},
363   { "lposcilsa2", S(LPOSC_ST), TR, 3, "aa","akkkio",
364                     (SUBR)lposc_stereo_set, (SUBR)lposca_stereo_no_trasp},
365   { "inrg", S(INRANGE), WI,3, "", "ky", (SUBR)inRange_i, (SUBR)inRange }
366 
367 
368 };
369 
newgabopc_init_(CSOUND * csound)370 int32_t newgabopc_init_(CSOUND *csound) {
371    return csound->AppendOpcodes(csound, &(localops[0]),
372                                 (int32_t) (sizeof(localops) / sizeof(OENTRY)));
373 }
374 
375 int32_t hvs_init_(CSOUND *csound);
376 int32_t slidertable_init_(CSOUND *csound);
377 int32_t tabmorph_init_(CSOUND *csound);
378 int32_t rbatonopc_init_(CSOUND *csound);
379 
380 
newgabopc_ModuleInit(CSOUND * csound)381 int32_t newgabopc_ModuleInit(CSOUND *csound)
382 {
383         int32_t               err = 0;
384         err |= hvs_init_(csound);
385         err |= newgabopc_init_(csound);
386         err |= slidertable_init_(csound);
387         err |= tabmorph_init_(csound);
388         /*      err |= rbatonopc_init_(csound); */
389 
390 
391         return (err ? CSOUND_ERROR : CSOUND_SUCCESS);
392 }
393 
394 /*
395 PUBLIC  int32_t     csoundModuleDestroy(CSOUND *csound)
396 {
397     return 0;
398 }
399 */
400