1 /*
2  csound_standard_types.c:
3 
4  Copyright (C) 2012,2013 Steven Yi
5 
6  This file is part of Csound.
7 
8  The Csound Library is free software; you can redistribute it
9  and/or modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  Csound is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with Csound; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  02110-1301 USA
22  */
23 
24 #include "csoundCore.h"
25 #include "csound_standard_types.h"
26 #include "pstream.h"
27 #include <stdlib.h>
28 
29 
30 /* MEMORY COPYING FUNCTIONS */
31 
myflt_copy_value(void * csound,void * dest,void * src)32 void myflt_copy_value(void* csound, void* dest, void* src) {
33   IGN(csound);
34     MYFLT* f1 = (MYFLT*)dest;
35     MYFLT* f2 = (MYFLT*)src;
36     *f1 = *f2;
37 }
38 
asig_copy_value(void * csound,void * dest,void * src)39 void asig_copy_value(void* csound, void* dest, void* src) {
40     IGN(csound);
41     memcpy(dest, src, sizeof(MYFLT) * ((CSOUND*)csound)->ksmps);
42 }
43 
wsig_copy_value(void * csound,void * dest,void * src)44 void wsig_copy_value(void* csound, void* dest, void* src) {
45     IGN(csound);
46     memcpy(dest, src, sizeof(SPECDAT));
47     //TODO - check if this needs to copy SPECDAT's DOWNDAT member and AUXCH
48 }
49 
fsig_copy_value(void * csound,void * dest,void * src)50 void fsig_copy_value(void* csound, void* dest, void* src) {
51     PVSDAT *fsigout = (PVSDAT*) dest;
52     PVSDAT *fsigin = (PVSDAT*) src;
53     int N = fsigin->N;
54     memcpy(dest, src, sizeof(PVSDAT) - sizeof(AUXCH));
55     if(fsigout->frame.auxp == NULL ||
56        fsigout->frame.size < (N + 2) * sizeof(float))
57       ((CSOUND *)csound)->AuxAlloc(csound,
58                                    (N + 2) * sizeof(float), &fsigout->frame);
59     memcpy(fsigout->frame.auxp, fsigin->frame.auxp, (N + 2) * sizeof(float));
60 }
61 
62 
string_copy_value(void * csound,void * dest,void * src)63 void string_copy_value(void* csound, void* dest, void* src) {
64     STRINGDAT* sDest = (STRINGDAT*)dest;
65     STRINGDAT* sSrc = (STRINGDAT*)src;
66     CSOUND* cs = (CSOUND*)csound;
67 
68     if (UNLIKELY(src == NULL)) return;
69     if (UNLIKELY(dest == NULL)) return;
70 
71     if (sSrc->size > sDest->size) {
72       if (sDest->data != NULL) {
73         cs->Free(cs, sDest->data);
74       }
75       sDest->data = cs_strdup(csound, sSrc->data);
76       sDest->size = strlen(sDest->data)+1;
77     } else {
78       if (sDest->data == NULL) {
79         sDest->data = cs_strdup(csound, sSrc->data);
80         sDest->size = strlen(sDest->data)+1;
81       } else {//breaks here
82         //fprintf(stderr, "\n in:src %p size=%d >>>%s<<<dstsize=%d dst->data=%p\n",
83         //   sSrc->data, sSrc->size, sSrc->data, sDest->size, sDest->data);
84         //memcpy(sDest->data, sSrc->data, sDest->size);
85         //memset(sDest->data,0,sDest->size);
86         strncpy(sDest->data, sSrc->data, sDest->size-1);
87 
88         //cs->Free(cs, sDest->data); sDest->data = cs_strdup(csound, sSrc->data);
89         //sDest->size = strlen(sDest->data)+1;
90       }
91     }
92     //sDest->size = sSrc->size;
93     //fprintf(stderr, "out:srcsize=%d >>>%s<<<dstsize=%d dst->data=%p\n",
94     //        sSrc->size, sSrc->data, sDest->size, sDest->data);
95 }
96 
array_get_num_members(ARRAYDAT * aSrc)97 static size_t array_get_num_members(ARRAYDAT* aSrc) {
98     int i, retVal = 0;
99 
100     if (aSrc->dimensions <= 0) {
101       return retVal;
102     }
103 
104     retVal = aSrc->sizes[0];
105 
106     for (i = 1; i < aSrc->dimensions; i++) {
107       retVal *= aSrc->sizes[i];
108     }
109     return (size_t)retVal;
110 }
111 
array_copy_value(void * csound,void * dest,void * src)112 void array_copy_value(void* csound, void* dest, void* src) {
113     ARRAYDAT* aDest = (ARRAYDAT*)dest;
114     ARRAYDAT* aSrc = (ARRAYDAT*)src;
115     CSOUND* cs = (CSOUND*)csound;
116     size_t j;
117     int memMyfltSize;
118     size_t arrayNumMembers;
119 
120     arrayNumMembers = array_get_num_members(aSrc);
121     memMyfltSize = aSrc->arrayMemberSize / sizeof(MYFLT);
122 
123     if(aDest->data == NULL ||
124        aSrc->arrayMemberSize != aDest->arrayMemberSize ||
125        aSrc->dimensions != aDest->dimensions ||
126        aSrc->arrayType != aDest->arrayType ||
127        arrayNumMembers != array_get_num_members(aDest)) {
128 
129         aDest->arrayMemberSize = aSrc->arrayMemberSize;
130         aDest->dimensions = aSrc->dimensions;
131         if(aDest->sizes != NULL) {
132             cs->Free(cs, aDest->sizes);
133         }
134         aDest->sizes = cs->Malloc(cs, sizeof(int) * aSrc->dimensions);
135         memcpy(aDest->sizes, aSrc->sizes, sizeof(int) * aSrc->dimensions);
136         aDest->arrayType = aSrc->arrayType;
137 
138         if(aDest->data != NULL) {
139             cs->Free(cs, aDest->data);
140         }
141         aDest->data = cs->Calloc(cs, aSrc->arrayMemberSize * arrayNumMembers);
142     }
143 
144     for (j = 0; j < arrayNumMembers; j++) {
145         int index = j * memMyfltSize;
146         aDest->arrayType->copyValue(csound,
147                                     aDest->data + index, aSrc->data + index);
148     }
149 
150 }
151 
152 /* MEM SIZE UPDATING FUNCTIONS */
153 
updateAsigMemBlock(void * csound,CS_VARIABLE * var)154 void updateAsigMemBlock(void* csound, CS_VARIABLE* var) {
155     CSOUND* cs = (CSOUND*)csound;
156     int ksmps = cs->ksmps;
157     var->memBlockSize = CS_FLOAT_ALIGN(ksmps * sizeof (MYFLT));
158 }
159 
varInitMemory(void * csound,CS_VARIABLE * var,MYFLT * memblock)160 void varInitMemory(void *csound, CS_VARIABLE* var, MYFLT* memblock) {
161     IGN(csound);
162     memset(memblock, 0, var->memBlockSize);
163 }
164 
arrayInitMemory(void * csound,CS_VARIABLE * var,MYFLT * memblock)165 void arrayInitMemory(void *csound, CS_VARIABLE* var, MYFLT* memblock) {
166     IGN(csound);
167     ARRAYDAT* dat = (ARRAYDAT*)memblock;
168     dat->arrayType = var->subType;
169 }
170 
varInitMemoryString(void * csound,CS_VARIABLE * var,MYFLT * memblock)171 void varInitMemoryString(void *csound, CS_VARIABLE* var, MYFLT* memblock) {
172     IGN(var);
173     STRINGDAT *str = (STRINGDAT *)memblock;
174     CSOUND* cs = (CSOUND*)csound;
175     str->data = (char *) cs->Calloc(csound, 8);
176     str->size = 8;
177     //printf("initialised %s %p %s %d\n", var->varName, str,  str->data, str->size);
178 }
179 
varInitMemoryFsig(void * csound,CS_VARIABLE * var,MYFLT * memblock)180 void varInitMemoryFsig(void *csound, CS_VARIABLE* var, MYFLT* memblock) {
181     IGN(var);
182     PVSDAT *fsig = (PVSDAT *)memblock;
183     IGN(csound);
184     memset(fsig, 0, sizeof(PVSDAT));  /* VL: clear memory for now */
185 }
186 
187 
188 /* CREATE VAR FUNCTIONS */
189 
createAsig(void * cs,void * p)190 CS_VARIABLE* createAsig(void* cs, void* p) {
191     int ksmps;
192     CSOUND* csound = (CSOUND*)cs;
193     IGN(p);
194 
195    //FIXME - this needs to take into account local ksmps, once
196     //context work is complete
197 //    if (instr != NULL) {
198 //      OPDS* p = (OPDS*)instr;
199 //      ksmps = CS_KSMPS;
200 //    } else {
201     ksmps = csound->ksmps;
202 //    }
203 
204     CS_VARIABLE* var = csound->Calloc(csound, sizeof (CS_VARIABLE));
205     var->memBlockSize = CS_FLOAT_ALIGN(ksmps * sizeof (MYFLT));
206     var->updateMemBlockSize = &updateAsigMemBlock;
207     var->initializeVariableMemory = &varInitMemory;
208     return var;
209 }
210 
createMyflt(void * cs,void * p)211 CS_VARIABLE* createMyflt(void* cs, void* p) {
212     CSOUND* csound = (CSOUND*)cs;
213     CS_VARIABLE* var = csound->Calloc(csound, sizeof (CS_VARIABLE));
214     IGN(p);
215     var->memBlockSize = CS_FLOAT_ALIGN(sizeof (MYFLT));
216     var->initializeVariableMemory = &varInitMemory;
217     return var;
218 }
219 
createBool(void * cs,void * p)220 CS_VARIABLE* createBool(void* cs, void* p) {
221     CSOUND* csound = (CSOUND*)cs;
222     CS_VARIABLE* var = csound->Calloc(csound, sizeof (CS_VARIABLE));
223     IGN(p);
224     var->memBlockSize = CS_FLOAT_ALIGN(sizeof (MYFLT));
225     var->initializeVariableMemory = &varInitMemory;
226     return var;
227 }
228 
createWsig(void * cs,void * p)229 CS_VARIABLE* createWsig(void* cs, void* p) {
230     CSOUND* csound = (CSOUND*)cs;
231     CS_VARIABLE* var = csound->Calloc(csound, sizeof (CS_VARIABLE));
232     IGN(p);
233     var->memBlockSize = CS_FLOAT_ALIGN(sizeof(SPECDAT));
234     var->initializeVariableMemory = &varInitMemory;
235     return var;
236 }
237 
createFsig(void * cs,void * p)238 CS_VARIABLE* createFsig(void* cs, void* p) {
239     CSOUND* csound = (CSOUND*)cs;
240     CS_VARIABLE* var = csound->Calloc(csound, sizeof (CS_VARIABLE));
241     IGN(p);
242     var->memBlockSize = CS_FLOAT_ALIGN(sizeof(PVSDAT));
243     var->initializeVariableMemory = &varInitMemoryFsig;
244     return var;
245 }
246 
247 
createString(void * cs,void * p)248 CS_VARIABLE* createString(void* cs, void* p) {
249     CSOUND* csound = (CSOUND*)cs;
250     CS_VARIABLE* var = csound->Calloc(csound, sizeof (CS_VARIABLE));
251     IGN(p);
252     var->memBlockSize = CS_FLOAT_ALIGN(sizeof(STRINGDAT));
253     var->initializeVariableMemory = &varInitMemoryString;
254     return var;
255 }
256 
createArray(void * csnd,void * p)257 CS_VARIABLE* createArray(void* csnd, void* p) {
258     CSOUND* csound = (CSOUND*)csnd;
259     ARRAY_VAR_INIT* state = (ARRAY_VAR_INIT*)p;
260 
261 
262     CS_VARIABLE* var = csound->Calloc(csound, sizeof (CS_VARIABLE));
263     var->memBlockSize = CS_FLOAT_ALIGN(sizeof(ARRAYDAT));
264     var->initializeVariableMemory = &arrayInitMemory;
265 
266     if (state) { // NB: this function is being called with p=NULL
267       CS_TYPE* type = state->type;
268       var->subType = type;
269       var->dimensions = state->dimensions;
270     }
271     return var;
272 }
273 
274 /* FREE VAR MEM FUNCTIONS */
275 
string_free_var_mem(void * csnd,void * p)276 void string_free_var_mem(void* csnd, void* p ) {
277     CSOUND* csound = (CSOUND*)csnd;
278     STRINGDAT* dat = (STRINGDAT*)p;
279 
280     if(dat->data != NULL) {
281         csound->Free(csound, dat->data);
282     }
283 }
284 
array_free_var_mem(void * csnd,void * p)285 void array_free_var_mem(void* csnd, void* p) {
286     CSOUND* csound = (CSOUND*)csnd;
287     ARRAYDAT* dat = (ARRAYDAT*)p;
288 
289     if(dat->data != NULL) {
290         CS_TYPE* arrayType = dat->arrayType;
291 
292         if (arrayType->freeVariableMemory != NULL) {
293             MYFLT* mem = dat->data;
294             size_t memMyfltSize = dat->arrayMemberSize / sizeof(MYFLT);
295             int i, size = dat->sizes[0];
296             for (i = 1; i < dat->dimensions; i++) {
297                 size *= dat->sizes[i];
298             }
299             //size = MYFLT2LRND(size); // size is not a float  but int
300             for (i = 0; i < size; i++) {
301                 arrayType->freeVariableMemory(csound,
302                                               mem+ (i * memMyfltSize));
303             }
304         }
305 
306         csound->Free(csound, dat->data);
307     }
308 
309     if (dat->sizes != NULL) {
310         csound->Free(csound, dat->sizes);
311     }
312 }
313 
314 /* STANDARD TYPE DEFINITIONS */
315 const CS_TYPE CS_VAR_TYPE_A = {
316   "a", "audio rate vector", CS_ARG_TYPE_BOTH, createAsig, asig_copy_value,
317   NULL, NULL
318 };
319 
320 const CS_TYPE CS_VAR_TYPE_K = {
321   "k", "control rate var", CS_ARG_TYPE_BOTH, createMyflt, myflt_copy_value,
322   NULL, NULL
323 };
324 
325 const CS_TYPE CS_VAR_TYPE_I = {
326   "i", "init time var", CS_ARG_TYPE_BOTH, createMyflt, myflt_copy_value,
327   NULL, NULL
328 };
329 
330 const CS_TYPE CS_VAR_TYPE_S = {
331     "S", "String var", CS_ARG_TYPE_BOTH, createString, string_copy_value,
332     NULL, string_free_var_mem
333 };
334 
335 const CS_TYPE CS_VAR_TYPE_P = {
336   "p", "p-field", CS_ARG_TYPE_BOTH, createMyflt, myflt_copy_value,
337   NULL, NULL
338 };
339 
340 const CS_TYPE CS_VAR_TYPE_R = {
341   "r", "reserved symbol", CS_ARG_TYPE_BOTH, createMyflt, myflt_copy_value,
342   NULL, NULL
343 };
344 
345 const CS_TYPE CS_VAR_TYPE_C = {
346   "c", "constant", CS_ARG_TYPE_IN, createMyflt, myflt_copy_value, NULL, NULL
347 };
348 
349 const CS_TYPE CS_VAR_TYPE_W = {
350   "w", "spectral", CS_ARG_TYPE_BOTH, createWsig, wsig_copy_value, NULL, NULL
351 };
352 
353 const CS_TYPE CS_VAR_TYPE_F = {
354   "f", "f-sig", CS_ARG_TYPE_BOTH, createFsig, fsig_copy_value, NULL, NULL
355 };
356 
357 const CS_TYPE CS_VAR_TYPE_B = {
358   "B", "boolean", CS_ARG_TYPE_BOTH, createBool, myflt_copy_value, NULL, NULL
359 };
360 
361 const CS_TYPE CS_VAR_TYPE_b = {
362   "b", "boolean", CS_ARG_TYPE_BOTH, createBool, myflt_copy_value, NULL, NULL
363 };
364 
365 const CS_TYPE CS_VAR_TYPE_ARRAY = {
366    "[", "array", CS_ARG_TYPE_BOTH, createArray, array_copy_value,
367     NULL, array_free_var_mem
368 };
369 
370 
371 
csoundAddStandardTypes(CSOUND * csound,TYPE_POOL * pool)372 void csoundAddStandardTypes(CSOUND* csound, TYPE_POOL* pool) {
373 
374     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_A);
375     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_K);
376     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_I);
377     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_S);
378     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_P);
379     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_R);
380     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_C);
381     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_W);
382     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_F);
383     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_B);
384     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_b);
385     csoundAddVariableType(csound, pool, (CS_TYPE*)&CS_VAR_TYPE_ARRAY);
386 
387 }
388 
389 
390 /* Type maps for poly, optional, and var arg types
391  * format is in pairs of specified type and types it can resolve into,
392  * termintated by a NULL */
393 const char* POLY_IN_TYPES[] = {
394     "x", "kacpri",              /* ***Deprecated*** */
395     "T", "Sicpr",
396     "U", "Sikcpr",
397     "i", "cpri",
398     "k", "cprki",
399     "B", "Bb", NULL};
400 const char* OPTIONAL_IN_TYPES[] = {
401     "o", "icpr",
402     "p", "icpr",
403     "q", "icpr",
404     "v", "icpr",
405     "j", "icpr",
406     "h", "icpr",
407     "O", "kicpr",
408     "J", "kicpr",
409     "V", "kicpr",
410     "P", "kicpr", NULL
411 };
412 const char* VAR_ARG_IN_TYPES[] = {
413     "m", "icrp",
414     "M", "icrpka",
415     "N", "icrpkaS",
416     "n", "icrp",   /* this one requires odd number of args... */
417     "W", "S",
418     "y", "a",
419     "z", "kicrp",
420     "Z", "kaicrp",  NULL  /* this one needs to be ka alternatating... */
421 };
422 
423 const char* POLY_OUT_TYPES[] = {
424     "s", "ka",                  /* ***Deprecated*** */
425     "i", "pi", NULL
426 };
427 
428 const char* VAR_ARG_OUT_TYPES[] = {
429     "m", "a",
430     "z", "k",
431     "I", "Sip", /* had comment of (not implemented yet) in entry1.c */
432     "X", "akip",
433     "N", "akipS",
434     "F", "f", NULL
435 };
436