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