1 /*
2 sfont.c:
3
4 Copyright (C) 2000-7 Gabriel Maldonado, John ffitch, Victor Lazzarini
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 /* WARNING! This file MUST be compiled by setting the structure member
25 alignment (compiler option) to 1 byte. That is: no padding bytes
26 should be present between a structure data member and another.
27 This code will cause memory access faults and crash Csound if
28 compiled with structure member alignment different than 1. See the
29 documentation of your C compiler to choose the appropriate compiler
30 directive switch. */
31
32 // #include "csdl.h"
33 #include "csoundCore.h"
34 #include "interlocks.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <math.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include "sfenum.h"
41 #include "sfont.h"
42
43 #define s2d(x) *((DWORD *) (x))
44
45
46
47 static int32_t chunk_read(CSOUND *, FILE *f, CHUNK *chunk);
48 static void fill_SfPointers(CSOUND *);
49 static int32_t fill_SfStruct(CSOUND *);
50 static void layerDefaults(layerType *layer);
51 static void splitDefaults(splitType *split);
52
53 #define MAX_SFONT (10)
54 #define MAX_SFPRESET (16384)
55 #define GLOBAL_ATTENUATION (FL(0.3))
56
57 #define ONETWELTH (0.08333333333333333333333333333)
58 #define TWOTOTWELTH (1.05946309435929526456182529495)
59
60 typedef struct _sfontg {
61 SFBANK *soundFont;
62 SFBANK *sfArray;
63 int32_t currSFndx;
64 int32_t maxSFndx;
65 presetType **presetp;
66 SHORT **sampleBase;
67 MYFLT pitches[128];
68 } sfontg;
69
sfont_ModuleDestroy(CSOUND * csound)70 int32_t sfont_ModuleDestroy(CSOUND *csound)
71 {
72 int32_t j,k,l;
73 SFBANK *sfArray;
74 sfontg *globals;
75 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
76 if (globals == NULL) return 0;
77 sfArray = globals->sfArray;
78
79 for (j=0; j<globals->currSFndx; j++) {
80 for (k=0; k< sfArray[j].presets_num; k++) {
81 for (l=0; l<sfArray[j].preset[k].layers_num; l++) {
82 csound->Free(csound, sfArray[j].preset[k].layer[l].split);
83 }
84 csound->Free(csound, sfArray[j].preset[k].layer);
85 }
86 csound->Free(csound, sfArray[j].preset);
87 for (l=0; l< sfArray[j].instrs_num; l++) {
88 csound->Free(csound, sfArray[j].instr[l].split);
89 }
90 csound->Free(csound, sfArray[j].instr);
91 csound->Free(csound, sfArray[j].chunk.main_chunk.ckDATA);
92 }
93 csound->Free(csound, sfArray);
94 globals->currSFndx = 0;
95 csound->Free(csound, globals->presetp);
96 csound->Free(csound, globals->sampleBase);
97
98 csound->DestroyGlobalVariable(csound, "::sfontg");
99 return 0;
100 }
101
SoundFontLoad(CSOUND * csound,char * fname)102 static int SoundFontLoad(CSOUND *csound, char *fname)
103 {
104 FILE *fil;
105 void *fd;
106 int i;
107 SFBANK *soundFont;
108 sfontg *globals;
109 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
110 soundFont = globals->soundFont;
111 fd = csound->FileOpen2(csound, &fil, CSFILE_STD, fname, "rb",
112 "SFDIR;SSDIR", CSFTYPE_SOUNDFONT, 0);
113 if (UNLIKELY(fd == NULL)) {
114 csound->ErrorMsg(csound,
115 Str("sfload: cannot open SoundFont file \"%s\" (error %s)"),
116 fname, strerror(errno));
117 return -1;
118 }
119 for (i=0; i<globals->currSFndx-1; i++)
120 if (strcmp(fname, globals->sfArray[i].name)==0) {
121 csound->Warning(csound, "%s already loaded\n", fname);
122 return i;
123 }
124 soundFont = &globals->sfArray[globals->currSFndx];
125 /* if (UNLIKELY(soundFont==NULL)){ */
126 /* csound->ErrorMsg(csound, Str("Sfload: cannot use globals")); */
127 /* return; */
128 /* } */
129 strNcpy(soundFont->name, csound->GetFileName(fd), 256);
130 //soundFont->name[255]='\0';
131 if (UNLIKELY(chunk_read(csound, fil, &soundFont->chunk.main_chunk)<0))
132 csound->Message(csound, Str("sfont: failed to read file\n"));
133 csound->FileClose(csound, fd);
134 globals->soundFont = soundFont;
135 fill_SfPointers(csound);
136 fill_SfStruct(csound);
137 return -1;
138 }
139
compare(presetType * elem1,presetType * elem2)140 static int32_t compare(presetType * elem1, presetType *elem2)
141 {
142 if (elem1->bank * 128 + elem1->prog > elem2->bank * 128 + elem2->prog)
143 return 1;
144 else
145 return -1;
146 }
147
148 /* syntax:
149 ihandle SfLoad "filename"
150 */
151
152 static char *Gfname; /* NOT THREAD SAFE */
153
SfLoad_(CSOUND * csound,SFLOAD * p,int32_t istring)154 static int32_t SfLoad_(CSOUND *csound, SFLOAD *p, int32_t istring)
155 /* open a file and return its handle */
156 { /* the handle is simply a stack index */
157 char *fname;
158 int hand;
159 SFBANK *sf;
160 sfontg *globals;
161 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
162 if (UNLIKELY(globals==NULL)) {
163 return csound->InitError(csound, Str("sfload: could not open globals\n"));
164 }
165 if (istring) fname = csound->Strdup(csound, ((STRINGDAT *)p->fname)->data);
166 else {
167 if (csound->ISSTRCOD(*p->fname))
168 fname = csound->Strdup(csound, get_arg_string(csound,*p->fname));
169 else fname = csound->strarg2name(csound,
170 NULL, p->fname, "sfont.",
171 0);
172 }
173 /* strcpy(fname, (char*) p->fname); */
174 Gfname = fname;
175 hand = SoundFontLoad(csound, fname);
176 if (hand<0) {
177 *p->ihandle = (MYFLT) globals->currSFndx;
178 sf = &globals->sfArray[globals->currSFndx];
179 qsort(sf->preset, sf->presets_num, sizeof(presetType),
180 (int32_t (*)(const void *, const void * )) compare);
181 csound->Free(csound,fname);
182 if (UNLIKELY(++globals->currSFndx>=globals->maxSFndx)) {
183 globals->maxSFndx += 5;
184 globals->sfArray = (SFBANK *)csound->ReAlloc(csound, globals->sfArray,
185 /* JPff fix */ globals->maxSFndx*sizeof(SFBANK));
186 csound->Warning(csound, Str("Extending soundfonts"));
187 if (globals->sfArray == NULL) return NOTOK;
188 }
189 }
190 else *p->ihandle=hand;
191 return OK;
192 }
193
SfLoad(CSOUND * csound,SFLOAD * p)194 static int32_t SfLoad(CSOUND *csound, SFLOAD *p){
195 return SfLoad_(csound,p,0);
196 }
197
SfLoad_S(CSOUND * csound,SFLOAD * p)198 static int32_t SfLoad_S(CSOUND *csound, SFLOAD *p){
199 return SfLoad_(csound,p,1);
200 }
201
filter_string(char * s,char temp_string[24])202 static char *filter_string(char *s, char temp_string[24])
203 {
204 int32_t i=0, j=0;
205 int32_t c;
206 for (i=0; i<22; i++, j++) {
207 c = s[j];
208 if (c=='\0') break;
209 if (isprint(c)) temp_string[i]=c;
210 else if (c<32) {
211 temp_string[i++]='^';
212 temp_string[i] = '@'+c;
213 }
214 else temp_string[i]='?';
215 }
216 temp_string[i] = '\0';
217 return temp_string;
218 }
219
Sfplist(CSOUND * csound,SFPLIST * p)220 static int32_t Sfplist(CSOUND *csound, SFPLIST *p)
221 {
222 sfontg *globals;
223 SFBANK *sf;
224 char temp_string[24];
225 int32_t j;
226 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
227 if (UNLIKELY( *p->ihandle<0 || *p->ihandle>=globals->currSFndx))
228 return csound->InitError(csound, Str("invalid soundfont"));
229 sf = &globals->sfArray[(int32_t) *p->ihandle];
230 /* if (UNLIKELY(sf==NULL)) */
231 /* return csound->InitError(csound, Str("invalid soundfont")); */
232 csound->Message(csound, Str("\nPreset list of \"%s\"\n"), sf->name);
233 for (j =0; j < sf->presets_num; j++) {
234 presetType *prs = &sf->preset[j];
235 csound->Message(csound, Str("%3d) %-20s\tprog:%-3d bank:%d\n"),
236 j, filter_string(prs->name, temp_string),
237 prs->prog, prs->bank);
238 }
239 csound->Message(csound, "\n");
240 return OK;
241 }
242
SfAssignAllPresets(CSOUND * csound,SFPASSIGN * p)243 static int32_t SfAssignAllPresets(CSOUND *csound, SFPASSIGN *p)
244 {
245 sfontg *globals;
246 SFBANK *sf;
247 int32_t pHandle, pnum;
248 int32_t j, enableMsgs;
249
250 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
251 if (UNLIKELY( *p->ihandle<0 || *p->ihandle>=globals->currSFndx))
252 return csound->InitError(csound, Str("invalid soundfont"));
253 sf = &globals->sfArray[(int32_t) *p->ihandle];
254 /* if (UNLIKELY(globals->soundFont==NULL)) */
255 /* return csound->InitError(csound, Str("invalid sound font")); */
256
257 pHandle = (int32_t) *p->startNum;
258 pnum = sf->presets_num;
259 enableMsgs = (*p->msgs==FL(0.0));
260 if (enableMsgs)
261 csound->Message(csound,
262 Str("\nAssigning all Presets of \"%s\" starting from"
263 " %d (preset handle number)\n"), sf->name, pHandle);
264 for (j = 0; j < pnum; j++) {
265 presetType *prs = &sf->preset[j];
266 if (enableMsgs)
267 csound->Message(csound, Str("%3d<--%-20s\t(prog:%-3d bank:%d)\n"),
268 j, prs->name, prs->prog, prs->bank);
269 globals->presetp[pHandle] = &sf->preset[j];
270 globals->sampleBase[pHandle] = sf->sampleData;
271 pHandle++;
272 }
273 if (enableMsgs)
274 csound->Message(csound, Str("\nAll presets have been assigned to preset"
275 " handles from %d to %d\nXS\n"),
276 (int32_t) *p->startNum, pHandle - 1);
277 return OK;
278 }
279
Sfilist(CSOUND * csound,SFPLIST * p)280 static int32_t Sfilist(CSOUND *csound, SFPLIST *p)
281 {
282 sfontg *globals;
283 SFBANK *sf;
284 int32_t j;
285 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
286 if (UNLIKELY( *p->ihandle<0 || *p->ihandle>=globals->currSFndx))
287 return csound->InitError(csound, Str("invalid soundfont"));
288 /* if (UNLIKELY(globals->soundFont==NULL)) */
289 /* return csound->InitError(csound, Str("invalid sound font")); */
290
291 sf = &globals->sfArray[(int32_t) *p->ihandle];
292 csound->Message(csound, Str("\nInstrument list of \"%s\"\n"), sf->name);
293 for (j =0; j < sf->instrs_num; j++) {
294 instrType *inst = &sf->instr[j];
295 csound->Message(csound, "%3d) %-20s\n", j, inst->name);
296 }
297 csound->Message(csound, "\n");
298 return OK;
299 }
300
SfPreset(CSOUND * csound,SFPRESET * p)301 static int32_t SfPreset(CSOUND *csound, SFPRESET *p)
302 {
303 sfontg *globals; SFBANK *sf;
304 int32_t j, presetHandle = (int32_t) *p->iPresetHandle;
305 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
306 sf = &globals->sfArray[(DWORD) *p->isfhandle];
307 if (UNLIKELY( *p->isfhandle<0 || *p->isfhandle>=globals->currSFndx))
308 return csound->InitError(csound, Str("invalid soundfont"));
309
310 if (UNLIKELY(presetHandle >= MAX_SFPRESET || presetHandle<0)) {
311 return csound->InitError(csound,
312 Str("sfpreset: preset handle too big (%d), max: %d"),
313 presetHandle, (int32_t) MAX_SFPRESET - 1);
314 }
315
316 for (j=0; j< sf->presets_num; j++) {
317 if (sf->preset[j].prog == (WORD) *p->iprog &&
318 sf->preset[j].bank == (WORD) *p->ibank )
319 {
320 globals->presetp[presetHandle] = &sf->preset[j];
321 globals->sampleBase[presetHandle] = sf->sampleData;
322 break;
323 }
324 }
325 *p->ipresethandle = (MYFLT) presetHandle;
326
327 if (UNLIKELY(globals->presetp[presetHandle] == NULL)) {
328 // return csound->InitError(csound,
329 csound->Warning(csound,
330 Str("sfpreset: cannot find any preset having prog "
331 "number %d and bank number %d in SoundFont file"
332 " \"%s\""),
333 (int32_t) *p->iprog, (int32_t) *p->ibank,
334 globals->sfArray[(DWORD) *p->isfhandle].name);
335 }
336 return OK;
337 }
338
SfPlay_set(CSOUND * csound,SFPLAY * p)339 static int32_t SfPlay_set(CSOUND *csound, SFPLAY *p)
340 {
341 DWORD index = (DWORD) *p->ipresethandle;
342 presetType *preset;
343 SHORT *sBase;
344 int32_t layersNum, j, spltNum = 0, flag = (int32_t) *p->iflag;
345 sfontg *globals;
346
347 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
348 if (UNLIKELY(index>=MAX_SFPRESET))
349 return csound->InitError(csound, Str("invalid soundfont"));
350 preset = globals->presetp[index];
351 sBase = globals->sampleBase[index];
352
353 if (!UNLIKELY(preset!=NULL)) {
354 return csound->InitError(csound, Str("sfplay: invalid or "
355 "out-of-range preset number"));
356 }
357 layersNum = preset->layers_num;
358 for (j =0; j < layersNum; j++) {
359 layerType *layer = &preset->layer[j];
360 int32_t vel= (int32_t) *p->ivel, notnum= (int32_t) *p->inotnum;
361 if (notnum >= layer->minNoteRange &&
362 notnum <= layer->maxNoteRange &&
363 vel >= layer->minVelRange &&
364 vel <= layer->maxVelRange) {
365 int32_t splitsNum = layer->splits_num, k;
366 for (k = 0; k < splitsNum; k++) {
367 splitType *split = &layer->split[k];
368 if (notnum >= split->minNoteRange &&
369 notnum <= split->maxNoteRange &&
370 vel >= split->minVelRange &&
371 vel <= split->maxVelRange) {
372 sfSample *sample = split->sample;
373 DWORD start=sample->dwStart;
374 MYFLT attenuation;
375 double pan;
376 double freq, orgfreq;
377 double tuneCorrection = split->coarseTune + layer->coarseTune +
378 (split->fineTune + layer->fineTune)*0.01;
379 int32_t orgkey = split->overridingRootKey;
380 if (orgkey == -1) orgkey = sample->byOriginalKey;
381 orgfreq = globals->pitches[orgkey];
382 if (flag) {
383 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection);
384 p->si[spltNum]= (freq/(orgfreq*orgfreq))*
385 sample->dwSampleRate*csound->onedsr;
386 }
387 else {
388 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection) *
389 pow(2.0, ONETWELTH * (split->scaleTuning*0.01) * (notnum-orgkey));
390 p->si[spltNum]= (freq/orgfreq) * sample->dwSampleRate*csound->onedsr;
391 }
392 attenuation = (MYFLT) (layer->initialAttenuation +
393 split->initialAttenuation);
394 attenuation = POWER(FL(2.0), (-FL(1.0)/FL(60.0)) * attenuation )
395 * GLOBAL_ATTENUATION;
396 pan = (double)(split->pan + layer->pan) / 1000.0 + 0.5;
397 if (pan > 1.0) pan = 1.0;
398 else if (pan < 0.0) pan = 0.0;
399 /* Suggested fix from steven yi Oct 2002 */
400 p->base[spltNum] = sBase + start;
401 p->phs[spltNum] = (double) split->startOffset + *p->ioffset;
402 p->end[spltNum] = sample->dwEnd + split->endOffset - start;
403 p->startloop[spltNum] =
404 sample->dwStartloop + split->startLoopOffset - start;
405 p->endloop[spltNum] =
406 sample->dwEndloop + split->endLoopOffset - start;
407 p->leftlevel[spltNum] = (MYFLT) sqrt(1.0-pan) * attenuation;
408 p->rightlevel[spltNum] = (MYFLT) sqrt(pan) * attenuation;
409 p->mode[spltNum]= split->sampleModes;
410 p->attack[spltNum] = split->attack*CS_EKR;
411 p->decay[spltNum] = split->decay*CS_EKR;
412 p->sustain[spltNum] = split->sustain;
413 p->release[spltNum] = split->release*CS_EKR;
414
415 if (*p->ienv > 1) {
416 p->attr[spltNum] = 1.0/(CS_EKR*split->attack);
417 p->decr[spltNum] = pow((split->sustain+0.0001),
418 1.0/(CS_EKR*
419 split->decay+0.0001));
420 if (split->attack != 0.0) p->env[spltNum] = 0.0;
421 else p->env[spltNum] = 1.0;
422 }
423 else if (*p->ienv > 0) {
424 p->attr[spltNum] = 1.0/(CS_EKR*split->attack);
425 p->decr[spltNum] = (split->sustain-1.0)/(CS_EKR*
426 split->decay);
427 if (split->attack != 0.0) p->env[spltNum] = 0.0;
428 else p->env[spltNum] = 1.0;
429 }
430 else {
431 p->env[spltNum] = 1.0;
432 }
433 p->ti[spltNum] = 0;
434 spltNum++;
435 }
436 }
437 }
438 }
439 p->spltNum = spltNum;
440 return OK;
441 }
442
443 #define Linear_interpolation \
444 SHORT *curr_samp = *base + (int32) *phs;\
445 MYFLT fract = (MYFLT) *phs - (MYFLT)((int32)*phs);\
446 MYFLT out = (*curr_samp + (*(curr_samp+1) - *curr_samp)*fract);
447
448 #define Cubic_interpolation \
449 MYFLT phs1 = (MYFLT) *phs -FL(1.0);\
450 int32_t x0 = (int32)phs1 ;\
451 MYFLT fract = (MYFLT)(phs1 - x0);\
452 SHORT *ftab = *base + x0;\
453 MYFLT ym1= *ftab++;\
454 MYFLT y0 = *ftab++;\
455 MYFLT y1 = *ftab++;\
456 MYFLT y2 = *ftab;\
457 MYFLT frsq = fract*fract;\
458 MYFLT frcu = frsq*ym1;\
459 MYFLT t1 = y2 + FL(3.0)*y0;\
460 MYFLT out = y0 + FL(0.5)*frcu + \
461 fract*(y1 - frcu/FL(6.0) - t1/FL(6.0) - ym1/FL(3.0)) + \
462 frsq*fract*(t1/FL(6.0) - FL(0.5)*y1) + frsq*(FL(0.5)* y1 - y0);
463
464 #define Looped \
465 if (*phs >= *startloop) flag = 1; \
466 if (flag) { \
467 while (*phs >= *endloop) *phs -= looplength; \
468 while (*phs < *startloop) *phs += looplength; \
469 }
470
471 #define ExpEnvelope \
472 if (*tinc < *attack) *env += *attr; \
473 else if (*tinc < *decay + *attack) *env *= *decr; \
474 else *env = *sustain; \
475 (*tinc)++; \
476
477 #define LinEnvelope \
478 if (*tinc < *attack) *env += *attr; \
479 else if (*tinc < *decay + *attack) *env += *decr; \
480 else *env = *sustain; \
481 (*tinc)++; \
482
483 #define Unlooped \
484 if (*phs > *end) break; \
485 if (*phs < FL(0.0)) *phs = FL(0.0); \
486
487 #define Mono_out \
488 out1[n] += *attenuation * out * (*env); \
489 *phs += si;
490
491 #define Stereo_out \
492 out1[n] += *left * out * (*env);\
493 out2[n] += *right * out * (*env);\
494 *phs += si;
495
SfPlay(CSOUND * csound,SFPLAY * p)496 static int32_t SfPlay(CSOUND *csound, SFPLAY *p)
497 {
498 IGN(csound);
499 MYFLT *out1 = p->out1, *out2 = p->out2, *env = p->env;
500 uint32_t offset = p->h.insdshead->ksmps_offset;
501 uint32_t early = p->h.insdshead->ksmps_no_end;
502 uint32_t n, nsmps = CS_KSMPS;
503 int32_t j = p->spltNum;
504 SHORT **base = p->base;
505 DWORD *end = p->end, *startloop= p->startloop, *endloop= p->endloop,
506 *tinc = p->ti;
507 SHORT *mode = p->mode;
508 double *sampinc = p->si, *phs = p->phs;
509 MYFLT *left= p->leftlevel, *right= p->rightlevel, *attack = p->attack,
510 *decr = p->decr, *decay = p->decay, *sustain= p->sustain,
511 *release = p->release, *attr = p->attr;
512
513
514 memset(out1, 0, nsmps*sizeof(MYFLT));
515 memset(out2, 0, nsmps*sizeof(MYFLT));
516 if (UNLIKELY(early)) nsmps -= early;
517
518 if (IS_ASIG_ARG(p->xfreq)) {
519 while (j--) {
520 double looplength = *endloop - *startloop;
521 MYFLT *freq = p->xfreq;
522
523 if (*mode == 1 || *mode ==3) {
524 int32_t flag =0;
525 if (*p->ienv > 1) { ExpEnvelope }
526 else if (*p->ienv > 0) { LinEnvelope }
527 for (n=offset;n<nsmps;n++) {
528 double si = *sampinc * freq[n];
529 Linear_interpolation Stereo_out Looped
530 }
531 }
532 else if (*phs < *end) {
533 if (*p->ienv > 1) { ExpEnvelope }
534 else if (*p->ienv > 0) { LinEnvelope }
535 for (n=offset;n<nsmps;n++) {
536 double si = *sampinc * freq[n];
537 Linear_interpolation Stereo_out Unlooped
538 }
539 }
540 phs++; base++; sampinc++; endloop++; startloop++;
541 left++; right++, mode++, end++; attack++; decay++; sustain++;
542 release++; tinc++; env++; attr++; decr++;
543 }
544 }
545 else {
546 MYFLT freq = *p->xfreq;
547 while (j--) {
548 double looplength = *endloop - *startloop;
549 double si = *sampinc * freq;
550 if (*mode == 1 || *mode ==3) {
551 int32_t flag =0;
552 if (*p->ienv > 1) { ExpEnvelope }
553 else if (*p->ienv > 0) { LinEnvelope }
554 for (n=offset;n<nsmps;n++) {
555 Linear_interpolation Stereo_out Looped
556 }
557 }
558 else if (*phs < *end) {
559 if (*p->ienv > 1) { ExpEnvelope }
560 else if (*p->ienv > 0) { LinEnvelope }
561 for (n=offset;n<nsmps;n++) {
562 Linear_interpolation Stereo_out Unlooped
563 }
564 }
565 phs++; base++; sampinc++; endloop++; startloop++;
566 left++; right++, mode++, end++; attack++; decay++; sustain++;
567 release++; tinc++; env++; attr++; decr++;
568 }
569 }
570 if (IS_ASIG_ARG(p->xamp)) {
571 MYFLT *amp = p->xamp;
572 for (n=offset;n<nsmps;n++) {
573 out1[n] *= amp[n];
574 out2[n] *= amp[n];
575 }
576 }
577 else {
578 MYFLT famp = *p->xamp;
579 for (n=offset;n<nsmps;n++) {
580 out1[n] *= famp;
581 out2[n] *= famp;
582 }
583 }
584 return OK;
585 }
586
SfPlay3(CSOUND * csound,SFPLAY * p)587 static int32_t SfPlay3(CSOUND *csound, SFPLAY *p)
588 {
589 IGN(csound);
590 MYFLT *out1 = p->out1, *out2 = p->out2, *env = p->env;
591 uint32_t offset = p->h.insdshead->ksmps_offset;
592 uint32_t early = p->h.insdshead->ksmps_no_end;
593 uint32_t n, nsmps = CS_KSMPS;
594 int32_t j = p->spltNum;
595 SHORT **base = p->base;
596 DWORD *end = p->end, *startloop = p->startloop,
597 *endloop = p->endloop, *tinc = p->ti;
598 SHORT *mode = p->mode;
599 double *sampinc = p->si, *phs = p->phs;
600 MYFLT *left= p->leftlevel, *right= p->rightlevel, *attack = p->attack,
601 *decr = p->decr, *decay = p->decay, *sustain= p->sustain,
602 *release = p->release, *attr = p->attr;
603
604 memset(out1, 0, nsmps*sizeof(MYFLT));
605 memset(out2, 0, nsmps*sizeof(MYFLT));
606 if (UNLIKELY(early)) nsmps -= early;
607
608 if (IS_ASIG_ARG(p->xfreq)) {
609 while (j--) {
610 double looplength = *endloop - *startloop;
611 MYFLT *freq = p->xfreq;
612 /* nsmps = CS_KSMPS; */
613 if (*mode == 1 || *mode ==3) {
614 int32_t flag =0;
615 if (*p->ienv > 1) { ExpEnvelope }
616 else if (*p->ienv > 0) { LinEnvelope }
617 for (n=offset;n<nsmps;n++) {
618 double si = *sampinc * freq[n];
619 Cubic_interpolation Stereo_out Looped
620 }
621 }
622 else if (*phs < *end) {
623 if (*p->ienv > 1) { ExpEnvelope }
624 else if (*p->ienv > 0) { LinEnvelope }
625 for (n=offset;n<nsmps;n++) {
626 double si = *sampinc * freq[n];
627 Cubic_interpolation Stereo_out Unlooped
628 }
629 }
630 phs++; base++; sampinc++; endloop++; startloop++;
631 left++; right++, mode++, end++; attack++; decay++; sustain++;
632 release++; tinc++; env++; attr++; decr++;
633 }
634 }
635 else {
636 MYFLT freq = *p->xfreq;
637 while (j--) {
638 double looplength = *endloop - *startloop, si = *sampinc * freq;
639 if (*mode == 1 || *mode ==3) {
640 int32_t flag =0;
641 if (*p->ienv > 1) { ExpEnvelope }
642 else if (*p->ienv > 0) { LinEnvelope }
643 for (n=offset;n<nsmps;n++) {
644 Cubic_interpolation Stereo_out Looped
645 }
646 }
647 else if (*phs < *end) {
648 if (*p->ienv > 1) { ExpEnvelope }
649 else if (*p->ienv > 0) { LinEnvelope }
650 for (n=offset;n<nsmps;n++) {
651 Cubic_interpolation Stereo_out Unlooped
652 }
653 }
654 phs++; base++; sampinc++; endloop++; startloop++;
655 left++; right++, mode++, end++; attack++; decay++; sustain++;
656 release++; tinc++; env++; attr++; decr++;
657 }
658 }
659
660 if (IS_ASIG_ARG(p->xamp)) {
661 MYFLT *amp = p->xamp;
662 for (n=offset;n<nsmps;n++) {
663 out1[n] *= amp[n];
664 out2[n] *= amp[n];
665 }
666 }
667 else {
668 MYFLT famp = *p->xamp;
669 for (n=offset;n<nsmps;n++) {
670 out1[n] *= famp;
671 out2[n] *= famp;
672 }
673 }
674 return OK;
675 }
676
SfPlayMono_set(CSOUND * csound,SFPLAYMONO * p)677 static int32_t SfPlayMono_set(CSOUND *csound, SFPLAYMONO *p)
678 {
679 DWORD index = (DWORD) *p->ipresethandle;
680 presetType *preset;
681 SHORT *sBase;
682 int32_t layersNum, j, spltNum = 0, flag=(int32_t) *p->iflag;
683 sfontg *globals;
684 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
685 if (UNLIKELY(index>=(DWORD)globals->currSFndx))
686 return csound->InitError(csound, Str("invalid soundfont"));
687
688 preset = globals->presetp[index];
689 sBase = globals->sampleBase[index];
690
691 if (UNLIKELY(!preset)) {
692 return csound->InitError(csound, Str("sfplaym: invalid or "
693 "out-of-range preset number"));
694 }
695 layersNum= preset->layers_num;
696 for (j =0; j < layersNum; j++) {
697 layerType *layer = &preset->layer[j];
698 int32_t vel= (int32_t) *p->ivel, notnum= (int32_t) *p->inotnum;
699 if (notnum >= layer->minNoteRange &&
700 notnum <= layer->maxNoteRange &&
701 vel >= layer->minVelRange &&
702 vel <= layer->maxVelRange) {
703 int32_t splitsNum = layer->splits_num, k;
704 for (k = 0; k < splitsNum; k++) {
705 splitType *split = &layer->split[k];
706 if (notnum >= split->minNoteRange &&
707 notnum <= split->maxNoteRange &&
708 vel >= split->minVelRange &&
709 vel <= split->maxVelRange) {
710 sfSample *sample = split->sample;
711 DWORD start=sample->dwStart;
712 double freq, orgfreq;
713 double tuneCorrection = split->coarseTune + layer->coarseTune +
714 (split->fineTune + layer->fineTune)*0.01;
715 int32_t orgkey = split->overridingRootKey;
716 if (orgkey == -1) orgkey = sample->byOriginalKey;
717 orgfreq = globals->pitches[orgkey] ;
718 if (flag) {
719 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection);
720 p->si[spltNum]= (freq/(orgfreq*orgfreq))*
721 sample->dwSampleRate*csound->onedsr;
722 }
723 else {
724 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection) *
725 pow( 2.0, ONETWELTH* (split->scaleTuning*0.01) * (notnum-orgkey));
726 p->si[spltNum]= (freq/orgfreq) * sample->dwSampleRate*csound->onedsr;
727 }
728 p->attenuation[spltNum] =
729 POWER(FL(2.0), (-FL(1.0)/FL(60.0)) * (layer->initialAttenuation +
730 split->initialAttenuation)) *
731 GLOBAL_ATTENUATION;
732 p->base[spltNum] = sBase+ start;
733 p->phs[spltNum] = (double) split->startOffset + *p->ioffset;
734 p->end[spltNum] = sample->dwEnd + split->endOffset - start;
735 p->startloop[spltNum] = sample->dwStartloop +
736 split->startLoopOffset - start;
737 p->endloop[spltNum] = sample->dwEndloop + split->endLoopOffset - start;
738 p->mode[spltNum]= split->sampleModes;
739 p->attack[spltNum] = split->attack*CS_EKR;
740 p->decay[spltNum] = split->decay*CS_EKR;
741 p->sustain[spltNum] = split->sustain;
742 p->release[spltNum] = split->release*CS_EKR;
743
744 if (*p->ienv > 1) {
745 p->attr[spltNum] = 1.0/(CS_EKR*split->attack);
746 p->decr[spltNum] = pow((split->sustain+0.0001),
747 1.0/(CS_EKR*
748 split->decay+0.0001));
749 if (split->attack != 0.0) p->env[spltNum] = 0.0;
750 else p->env[spltNum] = 1.0;
751 }
752 else if (*p->ienv > 0) {
753 p->attr[spltNum] = 1.0/(CS_EKR*split->attack);
754 p->decr[spltNum] = (split->sustain-1.0)/(CS_EKR*
755 split->decay);
756 if (split->attack != 0.0) p->env[spltNum] = 0.0;
757 else p->env[spltNum] = 1.0;
758 }
759 else {
760 p->env[spltNum] = 1.0;
761 }
762 p->ti[spltNum] = 0;
763 spltNum++;
764 }
765 }
766 }
767 }
768 p->spltNum = spltNum;
769 return OK;
770 }
771
SfPlayMono(CSOUND * csound,SFPLAYMONO * p)772 static int32_t SfPlayMono(CSOUND *csound, SFPLAYMONO *p)
773 {
774 IGN(csound);
775 MYFLT *out1 = p->out1 , *env = p->env;
776 uint32_t offset = p->h.insdshead->ksmps_offset;
777 uint32_t early = p->h.insdshead->ksmps_no_end;
778 uint32_t n, nsmps = CS_KSMPS;
779 int32_t j = p->spltNum;
780 SHORT **base = p->base;
781 DWORD *end= p->end, *startloop= p->startloop, *endloop= p->endloop,
782 *tinc = p->ti;
783 SHORT *mode = p->mode;
784 double *sampinc = p->si, *phs = p->phs;
785 MYFLT *attenuation = p->attenuation, *attack = p->attack, *decr = p->decr,
786 *decay = p->decay, *sustain= p->sustain, *release = p->release,
787 *attr = p->attr;
788
789 memset(out1, 0, nsmps*sizeof(MYFLT));
790 if (UNLIKELY(early)) nsmps -= early;
791
792 if (IS_ASIG_ARG(p->xfreq)) {
793 while (j--) {
794 double looplength = *endloop - *startloop;
795 MYFLT *freq = p->xfreq;
796
797 if (*mode == 1 || *mode ==3) {
798 int32_t flag =0;
799 for (n=offset;n<nsmps;n++) {
800 double si = *sampinc * freq[n];
801 if (*p->ienv > 1) { ExpEnvelope }
802 else if (*p->ienv > 0) { LinEnvelope }
803 { Linear_interpolation Mono_out Looped }
804 }
805 }
806 else if (*phs < *end) {
807 for (n=offset;n<nsmps;n++) {
808 double si = *sampinc * freq[n];
809 if (*p->ienv > 1) { ExpEnvelope }
810 else if (*p->ienv > 0) { LinEnvelope }
811 { Linear_interpolation Mono_out Unlooped }
812 }
813 }
814 phs++; base++; sampinc++; endloop++; startloop++;
815 attenuation++, mode++, end++; attack++; decay++; sustain++;
816 release++; tinc++; env++; attr++; decr++;
817 }
818 }
819 else {
820 MYFLT freq = *p->xfreq;
821 while (j--) {
822 double looplength = *endloop - *startloop;
823 double si = *sampinc * freq;
824 if (*mode == 1 || *mode ==3) {
825 int32_t flag =0;
826 for (n=offset;n<nsmps;n++) {
827 if (*p->ienv > 1) { ExpEnvelope }
828 else if (*p->ienv > 0) { LinEnvelope }
829 { Linear_interpolation Mono_out Looped }
830 }
831 }
832 else if (*phs < *end) {
833 for (n=offset;n<nsmps;n++) {
834 if (*p->ienv > 1) { ExpEnvelope }
835 else if (*p->ienv > 0) { LinEnvelope }
836 { Linear_interpolation Mono_out Unlooped }
837 }
838 }
839 phs++; base++; sampinc++; endloop++; startloop++;
840 attenuation++, mode++, end++; attack++; decay++; sustain++;
841 release++; tinc++; env++; attr++; decr++;
842 }
843 }
844 if (IS_ASIG_ARG(p->xamp)) {
845 MYFLT *amp = p->xamp;
846 for (n=offset;n<nsmps;n++) {
847 out1[n] *= amp[n];
848 }
849 }
850 else {
851 MYFLT famp = *p->xamp;
852 for (n=offset;n<nsmps;n++) {
853 out1[n] *= famp;
854 }
855 }
856 return OK;
857 }
858
SfPlayMono3(CSOUND * csound,SFPLAYMONO * p)859 static int32_t SfPlayMono3(CSOUND *csound, SFPLAYMONO *p)
860 {
861 IGN(csound);
862 MYFLT *out1 = p->out1, *env = p->env;
863 uint32_t offset = p->h.insdshead->ksmps_offset;
864 uint32_t early = p->h.insdshead->ksmps_no_end;
865 uint32_t n, nsmps = CS_KSMPS;
866 int32_t j = p->spltNum;
867 SHORT **base = p->base;
868 DWORD *end = p->end, *startloop = p->startloop,
869 *endloop = p->endloop, *tinc = p->ti;
870 SHORT *mode = p->mode;
871 double *sampinc = p->si, *phs = p->phs;
872 MYFLT *attenuation = p->attenuation,*attack = p->attack, *decr = p->decr,
873 *decay = p->decay, *sustain= p->sustain, *release = p->release,
874 *attr = p->attr;
875
876 memset(out1, 0, nsmps*sizeof(MYFLT));
877 if (UNLIKELY(early)) nsmps -= early;
878 if (IS_ASIG_ARG(p->xfreq)) {
879 while (j--) {
880 double looplength = *endloop - *startloop;
881 MYFLT *freq = p->xfreq;
882
883 if (*mode == 1 || *mode ==3) {
884 int32_t flag =0;
885 if (*p->ienv > 1) { ExpEnvelope }
886 else if (*p->ienv > 0) { LinEnvelope }
887 for (n=offset;n<nsmps;n++) {
888 double si = *sampinc * freq[n];
889 Cubic_interpolation Mono_out Looped
890 }
891 }
892 else if (*phs < *end) {
893 if (*p->ienv > 1) { ExpEnvelope }
894 else if (*p->ienv > 0) { LinEnvelope }
895 for (n=offset;n<nsmps;n++) {
896 double si = *sampinc * freq[n];
897 Cubic_interpolation Mono_out Unlooped
898 }
899 }
900 phs++; base++; sampinc++; endloop++; startloop++;
901 attenuation++, mode++, end++; attack++; decay++; sustain++;
902 release++; tinc++; env++; attr++; decr++;
903 }
904 }
905 else {
906 MYFLT freq = *p->xfreq;
907 while (j--) {
908 double looplength = *endloop - *startloop;
909 double si = *sampinc * freq;
910 if (*mode == 1 || *mode ==3) {
911 int32_t flag =0;
912 if (*p->ienv > 1) { ExpEnvelope }
913 else if (*p->ienv > 0) { LinEnvelope }
914 for (n=offset;n<nsmps;n++) {
915 Cubic_interpolation Mono_out Looped
916 }
917 }
918 else if (*phs < *end) {
919 if (*p->ienv > 1) { ExpEnvelope }
920 else if (*p->ienv > 0) { LinEnvelope }
921 for (n=offset;n<nsmps;n++) {
922 Cubic_interpolation Mono_out Unlooped
923 }
924 }
925 phs++; base++; sampinc++; endloop++; startloop++;
926 attenuation++, mode++, end++; attack++; decay++; sustain++;
927 release++; tinc++; env++; attr++; decr++;
928 }
929 }
930 if (IS_ASIG_ARG(p->xamp)) {
931 MYFLT *amp = p->xamp;
932 for (n=offset;n<nsmps;n++) {
933 out1[n] *= amp[n];
934 }
935 }
936 else {
937 MYFLT famp = *p->xamp;
938 for (n=offset;n<nsmps;n++) {
939 out1[n] *= famp;
940 }
941 }
942
943 return OK;
944 }
945
SfInstrPlay_set(CSOUND * csound,SFIPLAY * p)946 static int32_t SfInstrPlay_set(CSOUND *csound, SFIPLAY *p)
947 {
948 sfontg *globals;
949 SFBANK *sf;
950 int32_t index = (int32_t) *p->sfBank;
951 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
952 if (UNLIKELY(index<0 || index>=globals->currSFndx))
953 return csound->InitError(csound, Str("invalid soundfont"));
954 sf = &globals->sfArray[index];
955
956 if (UNLIKELY(*p->instrNum > sf->instrs_num)) {
957 return csound->InitError(csound, Str("sfinstr: instrument out of range"));
958 }
959 else {
960 instrType *layer = &sf->instr[(int32_t) *p->instrNum];
961 SHORT *sBase = sf->sampleData;
962 int32_t spltNum = 0, flag=(int32_t) *p->iflag;
963 int32_t vel= (int32_t) *p->ivel, notnum= (int32_t) *p->inotnum;
964 int32_t splitsNum = layer->splits_num, k;
965 for (k = 0; k < splitsNum; k++) {
966 splitType *split = &layer->split[k];
967 if (notnum >= split->minNoteRange &&
968 notnum <= split->maxNoteRange &&
969 vel >= split->minVelRange &&
970 vel <= split->maxVelRange) {
971 sfSample *sample = split->sample;
972 DWORD start=sample->dwStart;
973 MYFLT attenuation, pan;
974 double freq, orgfreq;
975 double tuneCorrection = split->coarseTune + split->fineTune*0.01;
976 int32_t orgkey = split->overridingRootKey;
977 if (orgkey == -1) orgkey = sample->byOriginalKey;
978 orgfreq = globals->pitches[orgkey] ;
979 if (flag) {
980 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection);
981 p->si[spltNum] = (freq/(orgfreq*orgfreq))*
982 sample->dwSampleRate*csound->onedsr;
983 }
984 else {
985 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection)
986 * pow( 2.0, ONETWELTH* (split->scaleTuning*0.01)*(notnum - orgkey));
987 p->si[spltNum] = (freq/orgfreq)*(sample->dwSampleRate*csound->onedsr);
988 }
989 attenuation = (MYFLT) (split->initialAttenuation);
990 attenuation = POWER(FL(2.0), (-FL(1.0)/FL(60.0)) * attenuation) *
991 GLOBAL_ATTENUATION;
992 pan = (MYFLT) split->pan / FL(1000.0) + FL(0.5);
993 if (pan > FL(1.0)) pan =FL(1.0);
994 else if (pan < FL(0.0)) pan = FL(0.0);
995 p->base[spltNum] = sBase + start;
996 p->phs[spltNum] = (double) split->startOffset + *p->ioffset;
997 p->end[spltNum] = sample->dwEnd + split->endOffset - start;
998 p->startloop[spltNum] = sample->dwStartloop +
999 split->startLoopOffset - start;
1000 p->endloop[spltNum] = sample->dwEndloop + split->endLoopOffset - start;
1001 p->leftlevel[spltNum] = (FL(1.0)-pan) * attenuation;
1002 p->rightlevel[spltNum] = pan * attenuation;
1003 p->mode[spltNum]= split->sampleModes;
1004
1005 p->attack[spltNum] = split->attack*CS_EKR;
1006 p->decay[spltNum] = split->decay*CS_EKR;
1007 p->sustain[spltNum] = split->sustain;
1008 p->release[spltNum] = split->release*CS_EKR;
1009
1010 if (*p->ienv > 1) {
1011 p->attr[spltNum] = 1.0/(CS_EKR*split->attack);
1012 p->decr[spltNum] = pow((split->sustain+0.0001),
1013 1.0/(CS_EKR*split->decay+0.0001));
1014 if (split->attack != 0.0) p->env[spltNum] = 0.0;
1015 else p->env[spltNum] = 1.0;
1016 }
1017 else if (*p->ienv > 0) {
1018 p->attr[spltNum] = 1.0/(CS_EKR*split->attack);
1019 p->decr[spltNum] = (split->sustain-1.0)/(CS_EKR*
1020 split->decay);
1021 if (split->attack != 0.0) p->env[spltNum] = 0.0;
1022 else p->env[spltNum] = 1.0;
1023 }
1024 else {
1025 p->env[spltNum] = 1.0;
1026 }
1027 p->ti[spltNum] = 0;
1028 spltNum++;
1029 }
1030 }
1031 p->spltNum = spltNum;
1032 }
1033 return OK;
1034 }
1035
SfInstrPlay(CSOUND * csound,SFIPLAY * p)1036 static int32_t SfInstrPlay(CSOUND *csound, SFIPLAY *p)
1037 {
1038 IGN(csound);
1039 MYFLT *out1= p->out1, *out2= p->out2, *env = p->env;
1040 uint32_t offset = p->h.insdshead->ksmps_offset;
1041 uint32_t early = p->h.insdshead->ksmps_no_end;
1042 uint32_t n, nsmps = CS_KSMPS;
1043 int32_t j = p->spltNum;
1044 SHORT **base = p->base;
1045 DWORD *end= p->end, *startloop= p->startloop,
1046 *endloop= p->endloop, *tinc = p->ti;
1047 SHORT *mode = p->mode;
1048 double *sampinc = p->si, *phs = p->phs;
1049 MYFLT *left= p->leftlevel, *right= p->rightlevel, *attack = p->attack,
1050 *decr = p->decr, *decay = p->decay, *sustain= p->sustain,
1051 *release = p->release, *attr = p->attr;
1052
1053 memset(out1, 0, nsmps*sizeof(MYFLT));
1054 memset(out2, 0, nsmps*sizeof(MYFLT));
1055 if (UNLIKELY(early)) nsmps -= early;
1056
1057 if (IS_ASIG_ARG(p->xfreq)) {
1058 while (j--) {
1059 double looplength = *endloop - *startloop;
1060 MYFLT *freq = p->xfreq;
1061
1062 if (*mode == 1 || *mode ==3) {
1063 int32_t flag =0;
1064 if (*p->ienv > 1) { ExpEnvelope }
1065 else if (*p->ienv > 0) { LinEnvelope }
1066 for (n=offset;n<nsmps;n++) {
1067 double si = *sampinc * freq[n];
1068 Linear_interpolation Stereo_out Looped
1069 }
1070 }
1071 else if (*phs < *end) {
1072 if (*p->ienv > 1) { ExpEnvelope }
1073 else if (*p->ienv > 0) { LinEnvelope }
1074 for (n=offset;n<nsmps;n++) {
1075 double si = *sampinc * freq[n];
1076 Linear_interpolation Stereo_out Unlooped
1077 }
1078 }
1079 phs++; base++; sampinc++; endloop++; startloop++;
1080 left++; right++, mode++, end++; attack++; decay++; sustain++;
1081 release++; tinc++; env++; attr++; decr++;
1082 }
1083 }
1084 else {
1085 MYFLT freq = *p->xfreq;
1086 while (j--) {
1087 double looplength = *endloop - *startloop;
1088 double si = *sampinc * freq;
1089 if (*mode == 1 || *mode ==3) {
1090 int32_t flag =0;
1091 if (*p->ienv > 1) { ExpEnvelope }
1092 else if (*p->ienv > 0) { LinEnvelope }
1093 for (n=offset;n<nsmps;n++) {
1094 Linear_interpolation Stereo_out Looped
1095 }
1096 }
1097 else if (*phs < *end) {
1098 if (*p->ienv > 1) { ExpEnvelope }
1099 else if (*p->ienv > 0) { LinEnvelope }
1100 for (n=offset;n<nsmps;n++) {
1101 Linear_interpolation Stereo_out Unlooped
1102 }
1103 }
1104 phs++; base++; sampinc++; endloop++; startloop++;
1105 left++; right++, mode++, end++; attack++; decay++; sustain++;
1106 release++; tinc++; env++; attr++; decr++;
1107 }
1108 }
1109
1110 if (IS_ASIG_ARG(p->xamp)) {
1111 MYFLT *amp = p->xamp;
1112 for (n=offset;n<nsmps;n++) {
1113 out1[n] *= amp[n];
1114 out2[n] *= amp[n];
1115 }
1116 }
1117 else {
1118 MYFLT famp = *p->xamp;
1119 for (n=offset;n<nsmps;n++) {
1120 out1[n] *= famp;
1121 out2[n] *= famp;
1122 }
1123 }
1124 return OK;
1125 }
1126
SfInstrPlay3(CSOUND * csound,SFIPLAY * p)1127 static int32_t SfInstrPlay3(CSOUND *csound, SFIPLAY *p)
1128 {
1129 IGN(csound);
1130 MYFLT *out1= p->out1, *out2= p->out2,*env =p->env;
1131 uint32_t offset = p->h.insdshead->ksmps_offset;
1132 uint32_t early = p->h.insdshead->ksmps_no_end;
1133 uint32_t n, nsmps = CS_KSMPS;
1134 int32_t j = p->spltNum;
1135 SHORT **base = p->base;
1136 DWORD *end= p->end, *startloop= p->startloop,
1137 *endloop= p->endloop, *tinc = p->ti;
1138 SHORT *mode = p->mode;
1139 double *sampinc = p->si, *phs = p->phs;
1140 MYFLT *left= p->leftlevel, *right= p->rightlevel,
1141 *attack = p->attack, *decr = p->decr,
1142 *decay = p->decay, *sustain= p->sustain, *release = p->release,
1143 *attr = p->attr;
1144
1145 memset(out1, 0, nsmps*sizeof(MYFLT));
1146 memset(out2, 0, nsmps*sizeof(MYFLT));
1147 if (UNLIKELY(early)) nsmps -= early;
1148
1149 if (IS_ASIG_ARG(p->xfreq)) {
1150 while (j--) {
1151 double looplength = *endloop - *startloop;
1152 MYFLT *freq = p->xfreq;
1153
1154 if (*mode == 1 || *mode ==3) {
1155 int32_t flag =0;
1156 if (*p->ienv > 1) { ExpEnvelope }
1157 else if (*p->ienv > 0) { LinEnvelope }
1158 for (n=offset;n<nsmps;n++) {
1159 double si = *sampinc * freq[n];
1160 Cubic_interpolation Stereo_out Looped
1161 }
1162 }
1163 else if (*phs < *end) {
1164 if (*p->ienv > 1) { ExpEnvelope }
1165 else if (*p->ienv > 0) { LinEnvelope }
1166 for (n=offset;n<nsmps;n++) {
1167 double si = *sampinc * freq[n];
1168 Cubic_interpolation Stereo_out Unlooped
1169 }
1170 }
1171 phs++; base++; sampinc++; endloop++; startloop++;
1172 left++; right++, mode++, end++; attack++; decay++; sustain++;
1173 release++; tinc++; env++; attr++; decr++;
1174 }
1175 }
1176 else {
1177 MYFLT freq = *p->xfreq;
1178 while (j--) {
1179 double looplength = *endloop - *startloop;
1180 double si = *sampinc * freq;
1181 if (*mode == 1 || *mode ==3) {
1182 int32_t flag =0;
1183 if (*p->ienv > 1) { ExpEnvelope }
1184 else if (*p->ienv > 0) { LinEnvelope }
1185 for (n=offset;n<nsmps;n++) {
1186 Cubic_interpolation Stereo_out Looped
1187 }
1188 }
1189 else if (*phs < *end) {
1190 if (*p->ienv > 1) { ExpEnvelope }
1191 else if (*p->ienv > 0) { LinEnvelope }
1192 for (n=offset;n<nsmps;n++) {
1193 Cubic_interpolation Stereo_out Unlooped
1194 }
1195 }
1196 phs++; base++; sampinc++; endloop++; startloop++;
1197 left++; right++, mode++, end++; attack++; decay++; sustain++;
1198 release++; tinc++; env++; attr++; decr++;
1199 }
1200 }
1201
1202 if (IS_ASIG_ARG(p->xamp)) {
1203 MYFLT *amp = p->xamp;
1204 for (n=offset;n<nsmps;n++) {
1205 out1[n] *= amp[n];
1206 out2[n] *= amp[n];
1207 }
1208 }
1209 else {
1210 MYFLT famp = *p->xamp;
1211 for (n=offset;n<nsmps;n++) {
1212 out1[n] *= famp;
1213 out2[n] *= famp;
1214 }
1215 }
1216 return OK;
1217 }
1218
SfInstrPlayMono_set(CSOUND * csound,SFIPLAYMONO * p)1219 static int32_t SfInstrPlayMono_set(CSOUND *csound, SFIPLAYMONO *p)
1220 {
1221 int32_t index = (int32_t) *p->sfBank;
1222 sfontg *globals;
1223 SFBANK *sf;
1224 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
1225 if (UNLIKELY(index<0 || index>=globals->currSFndx))
1226 return csound->InitError(csound, Str("invalid soundfont"));
1227
1228 sf = &globals->sfArray[index];
1229 if (UNLIKELY( *p->instrNum > sf->instrs_num)) {
1230 return csound->InitError(csound, Str("sfinstr: instrument out of range"));
1231 }
1232 else {
1233 instrType *layer = &sf->instr[(int32_t) *p->instrNum];
1234 SHORT *sBase = sf->sampleData;
1235 int32_t spltNum = 0, flag=(int32_t) *p->iflag;
1236 int32_t vel= (int32_t) *p->ivel, notnum= (int32_t) *p->inotnum;
1237 int32_t splitsNum = layer->splits_num, k;
1238 for (k = 0; k < splitsNum; k++) {
1239 splitType *split = &layer->split[k];
1240 if (notnum >= split->minNoteRange &&
1241 notnum <= split->maxNoteRange &&
1242 vel >= split->minVelRange &&
1243 vel <= split->maxVelRange) {
1244 sfSample *sample = split->sample;
1245 DWORD start=sample->dwStart;
1246 double freq, orgfreq;
1247 double tuneCorrection = split->coarseTune + split->fineTune/100.0;
1248 int32_t orgkey = split->overridingRootKey;
1249 if (orgkey == -1) orgkey = sample->byOriginalKey;
1250 orgfreq = globals->pitches[orgkey];
1251 if (flag) {
1252 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection);
1253 p->si[spltNum] = (freq/(orgfreq*orgfreq))*
1254 sample->dwSampleRate*csound->onedsr;
1255 }
1256 else {
1257 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection)
1258 * pow( 2.0, ONETWELTH* (split->scaleTuning*0.01) * (notnum-orgkey));
1259 p->si[spltNum] = (freq/orgfreq)*(sample->dwSampleRate*csound->onedsr);
1260 }
1261 p->attenuation[spltNum] = (MYFLT) pow(2.0, (-1.0/60.0)*
1262 split->initialAttenuation)
1263 * GLOBAL_ATTENUATION;
1264 p->base[spltNum] = sBase+ start;
1265 p->phs[spltNum] = (double) split->startOffset + *p->ioffset;
1266 p->end[spltNum] = sample->dwEnd + split->endOffset - start;
1267 p->startloop[spltNum] = sample->dwStartloop +
1268 split->startLoopOffset - start;
1269 p->endloop[spltNum] = sample->dwEndloop + split->endLoopOffset - start;
1270 p->mode[spltNum]= split->sampleModes;
1271 p->attack[spltNum] = split->attack*CS_EKR;
1272 p->decay[spltNum] = split->decay*CS_EKR;
1273 p->sustain[spltNum] = split->sustain;
1274 p->release[spltNum] = split->release*CS_EKR;
1275
1276 if (*p->ienv > 1) {
1277 p->attr[spltNum] = 1.0/(CS_EKR*split->attack);
1278 p->decr[spltNum] = pow((split->sustain+0.0001),
1279 1.0/(CS_EKR*
1280 split->decay+0.0001));
1281 if (split->attack != 0.0) p->env[spltNum] = 0.0;
1282 else p->env[spltNum] = 1.0;
1283 }
1284 else if (*p->ienv > 0) {
1285 p->attr[spltNum] = 1.0/(CS_EKR*split->attack);
1286 p->decr[spltNum] = (split->sustain-1.0)/(CS_EKR*
1287 split->decay);
1288 if (split->attack != 0.0) p->env[spltNum] = 0.0;
1289 else p->env[spltNum] = 1.0;
1290 }
1291 else {
1292 p->env[spltNum] = 1.0;
1293 }
1294 p->ti[spltNum] = 0;
1295 spltNum++;
1296 }
1297 }
1298 p->spltNum = spltNum;
1299 }
1300 return OK;
1301 }
1302
SfInstrPlayMono(CSOUND * csound,SFIPLAYMONO * p)1303 static int32_t SfInstrPlayMono(CSOUND *csound, SFIPLAYMONO *p)
1304 {
1305 IGN(csound);
1306 MYFLT *out1= p->out1, *env = p->env;
1307 uint32_t offset = p->h.insdshead->ksmps_offset;
1308 uint32_t early = p->h.insdshead->ksmps_no_end;
1309 uint32_t n, nsmps = CS_KSMPS;
1310 int32_t j = p->spltNum;
1311 SHORT **base = p->base;
1312 DWORD *end= p->end, *startloop= p->startloop, *endloop= p->endloop,
1313 *tinc = p->ti;
1314 SHORT *mode = p->mode;
1315
1316 double *sampinc = p->si, *phs = p->phs;
1317 MYFLT *attenuation = p->attenuation, *attack = p->attack, *decr = p->decr,
1318 *decay = p->decay, *sustain= p->sustain, *release = p->release,
1319 *attr = p->attr;
1320
1321 memset(out1, 0, nsmps*sizeof(MYFLT));
1322 if (UNLIKELY(early)) nsmps -= early;
1323
1324 if (IS_ASIG_ARG(p->xfreq)) {
1325 while (j--) {
1326 double looplength = *endloop - *startloop;
1327 MYFLT *freq = p->xfreq;
1328
1329 if (*mode == 1 || *mode ==3) {
1330 int32_t flag =0;
1331 if (*p->ienv > 1) { ExpEnvelope }
1332 else if (*p->ienv > 0) { LinEnvelope }
1333 for (n=offset;n<nsmps;n++) {
1334 double si = *sampinc * freq[n];
1335 Linear_interpolation Mono_out Looped
1336 }
1337 }
1338 else if (*phs < *end) {
1339 if (*p->ienv > 1) { ExpEnvelope }
1340 else if (*p->ienv > 0) { LinEnvelope }
1341 for (n=offset;n<nsmps;n++) {
1342 double si = *sampinc * freq[n];
1343 Linear_interpolation Mono_out Unlooped
1344 }
1345 }
1346 phs++; base++; sampinc++; endloop++; startloop++;
1347 attenuation++, mode++, end++; attack++; decay++; sustain++;
1348 release++; tinc++; env++; attr++; decr++;
1349 }
1350 }
1351 else {
1352 MYFLT freq = *p->xfreq;
1353 while (j--) {
1354 double looplength = *endloop - *startloop;
1355 double si = *sampinc * freq;
1356 if (*mode == 1 || *mode ==3) {
1357 int32_t flag =0;
1358 if (*p->ienv > 1) { ExpEnvelope }
1359 else if (*p->ienv > 0) { LinEnvelope }
1360 for (n=offset;n<nsmps;n++) {
1361 Linear_interpolation Mono_out Looped
1362 }
1363 }
1364 else if (*phs < *end) {
1365 if (*p->ienv > 1) { ExpEnvelope }
1366 else if (*p->ienv > 0) { LinEnvelope }
1367 for (n=offset;n<nsmps;n++) {
1368 Linear_interpolation Mono_out Unlooped
1369 }
1370 }
1371 phs++; base++; sampinc++; endloop++; startloop++;
1372 attenuation++, mode++, end++; attack++; decay++; sustain++;
1373 release++; tinc++; env++; attr++; decr++;
1374 }
1375 }
1376 if (IS_ASIG_ARG(p->xamp)) {
1377 MYFLT *amp = p->xamp;
1378 for (n=offset;n<nsmps;n++) {
1379 out1[n] *= amp[n];
1380 }
1381 }
1382 else {
1383 MYFLT famp = *p->xamp;
1384 for (n=offset;n<nsmps;n++) {
1385 out1[n] *= famp;
1386 }
1387 }
1388 return OK;
1389 }
1390
SfInstrPlayMono3(CSOUND * csound,SFIPLAYMONO * p)1391 static int32_t SfInstrPlayMono3(CSOUND *csound, SFIPLAYMONO *p)
1392 {
1393 IGN(csound);
1394 MYFLT *out1= p->out1, *env = p->env ;
1395 uint32_t offset = p->h.insdshead->ksmps_offset;
1396 uint32_t early = p->h.insdshead->ksmps_no_end;
1397 uint32_t n, nsmps = CS_KSMPS;
1398 int32_t j = p->spltNum;
1399 SHORT **base = p->base;
1400 DWORD *end= p->end, *startloop= p->startloop,
1401 *endloop= p->endloop, *tinc = p->ti;
1402 SHORT *mode = p->mode;
1403 double *sampinc = p->si, *phs = p->phs;
1404 MYFLT *attenuation = p->attenuation,*attack = p->attack, *decr = p->decr,
1405 *decay = p->decay, *sustain= p->sustain, *release = p->release,
1406 *attr = p->attr;
1407
1408 memset(out1, 0, nsmps*sizeof(MYFLT));
1409 if (UNLIKELY(early)) nsmps -= early;
1410
1411 if (IS_ASIG_ARG(p->xfreq)) {
1412 while (j--) {
1413 double looplength = *endloop - *startloop;
1414 MYFLT *freq = p->xfreq;
1415
1416 if (*mode == 1 || *mode ==3) {
1417 int32_t flag =0;
1418 if (*p->ienv > 1) { ExpEnvelope }
1419 else if (*p->ienv > 0) { LinEnvelope }
1420 for (n=offset;n<nsmps;n++) {
1421 double si = *sampinc * freq[n];
1422 Cubic_interpolation Mono_out Looped
1423 }
1424 }
1425 else if (*phs < *end) {
1426 if (*p->ienv > 1) { ExpEnvelope }
1427 else if (*p->ienv > 0) { LinEnvelope }
1428 for (n=offset;n<nsmps;n++) {
1429 double si = *sampinc * freq[n];
1430 Cubic_interpolation Mono_out Unlooped
1431 }
1432 }
1433 phs++; base++; sampinc++; endloop++; startloop++;
1434 attenuation++, mode++, end++; attack++; decay++; sustain++;
1435 release++; tinc++; env++; attr++; decr++;
1436 }
1437 }
1438 else {
1439 MYFLT freq = *p->xfreq;
1440 while (j--) {
1441 double looplength = *endloop - *startloop;
1442 double si = *sampinc * freq;
1443 if (*mode == 1 || *mode ==3) {
1444 int32_t flag =0;
1445 if (*p->ienv > 1) { ExpEnvelope }
1446 else if (*p->ienv > 0) { LinEnvelope }
1447 for (n=offset;n<nsmps;n++) {
1448 Cubic_interpolation Mono_out Looped
1449 }
1450 }
1451 else if (*phs < *end) {
1452 if (*p->ienv > 1) { ExpEnvelope }
1453 else if (*p->ienv > 0) { LinEnvelope }
1454 for (n=offset;n<nsmps;n++) {
1455 Cubic_interpolation Mono_out Unlooped
1456 }
1457 }
1458 phs++; base++; sampinc++; endloop++; startloop++;
1459 attenuation++, mode++, end++; attack++; decay++; sustain++;
1460 release++; tinc++; env++; attr++; decr++;
1461 }
1462 }
1463 if (IS_ASIG_ARG(p->xamp)) {
1464 MYFLT *amp = p->xamp;
1465 for (n=offset;n<nsmps;n++) {
1466 out1[n] *= amp[n];
1467 }
1468 }
1469 else {
1470 MYFLT famp = *p->xamp;
1471 for (n=offset;n<nsmps;n++) {
1472 out1[n] *= famp;
1473 }
1474 }
1475 return OK;
1476 }
1477
1478 /*********************/
1479
1480 /* Convert Big-endian <-> Little-endian (for Big-endian machines only)
1481 * fmt: ((b|w|d)[0-9]*)+
1482 * b:byte (no conversion), w:word, d:double word, digits(optional):repeat n times
1483 */
1484 #ifdef WORDS_BIGENDIAN
ChangeByteOrder(char * fmt,char * p,int32 size)1485 static void ChangeByteOrder(char *fmt, char *p, int32 size)
1486 {
1487 char c, c1, c2, c3, c4;
1488 char *fmt_org = fmt;
1489 int32 i, times;
1490
1491 while (size > 0) {
1492 fmt = fmt_org;
1493 while (*fmt) {
1494 c = *fmt++;
1495 if (isdigit(*fmt)) {
1496 times = strtol(fmt, &fmt, 10);
1497 } else {
1498 times = 1;
1499 }
1500 for (i = 0; i < times; i++) {
1501 switch(c) {
1502 case 'b': case 'B':
1503 p++; size--; break;
1504 case 'w': case 'W':
1505 c1 = p[0]; c2 = p[1];
1506 *p++ = c2; *p++ = c1;
1507 size -= 2; break;
1508 case 'd': case 'D':
1509 c1 = p[0]; c2 = p[1]; c3 = p[2]; c4 = p[3];
1510 *p++ = c4; *p++ = c3; *p++ = c2; *p++ = c1;
1511 size -= 4;
1512 break;
1513 }
1514 }
1515 }
1516 }
1517 }
1518 #else
1519 #define ChangeByteOrder(fmt, p, size) /* nothing */
1520 #endif
1521
fill_SfStruct(CSOUND * csound)1522 static int32_t fill_SfStruct(CSOUND *csound)
1523 {
1524 int32_t j, k, i, l, m, size, iStart, iEnd, kk, ll, mStart, mEnd;
1525 int32_t pbag_num,first_pbag,layer_num;
1526 int32_t ibag_num,first_ibag,split_num;
1527 CHUNK *phdrChunk;
1528 presetType *preset;
1529 sfPresetHeader *phdr;
1530 sfPresetBag *pbag;
1531 sfGenList *pgen;
1532 sfInst *inst;
1533 sfInstBag *ibag;
1534 /* sfInstModList *imod; */
1535 sfInstGenList *igen;
1536 sfSample *shdr;
1537 SFBANK *soundFont;
1538 sfontg *globals;
1539 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
1540 soundFont = globals->soundFont;
1541
1542
1543 /* imod = soundFont->chunk.imod; */
1544 igen = soundFont->chunk.igen;
1545 shdr = soundFont->chunk.shdr;
1546
1547 phdrChunk= soundFont->chunk.phdrChunk;
1548 phdr = soundFont->chunk.phdr;
1549 pbag = soundFont->chunk.pbag;
1550 pgen = soundFont->chunk.pgen;
1551 inst = soundFont->chunk.inst;
1552 ibag = soundFont->chunk.ibag;
1553
1554 size = phdrChunk->ckSize / sizeof(sfPresetHeader);
1555 soundFont->presets_num = size;
1556 preset = (presetType *) csound->Malloc(csound, size * sizeof(presetType));
1557 for (j=0; j < size; j++) {
1558 preset[j].name = phdr[j].achPresetName;
1559 if (strcmp(preset[j].name,"EOP")==0) {
1560 soundFont->presets_num = j;
1561 goto end_fill_presets;
1562 }
1563 preset[j].num = j;
1564 preset[j].prog = phdr[j].wPreset;
1565 preset[j].bank = phdr[j].wBank;
1566 first_pbag = phdr[j].wPresetBagNdx;
1567 pbag_num = phdr[j+1].wPresetBagNdx - first_pbag;
1568 layer_num = 0;
1569 for (k = 0 ; k < pbag_num ; k++) {
1570 iStart = pbag[k+first_pbag].wGenNdx;
1571 iEnd = pbag[k+first_pbag+1].wGenNdx;
1572 for (i = iStart; i < iEnd; i++) {
1573 if (pgen[i].sfGenOper == instrument ) {
1574 layer_num++;
1575 }
1576 }
1577 }
1578 preset[j].layers_num = layer_num;
1579 preset[j].layer =
1580 (layerType *) csound->Malloc(csound, layer_num * sizeof(layerType));
1581 for (k=0; k <layer_num; k++) {
1582 layerDefaults(&preset[j].layer[k]);
1583 }
1584 for (k = 0, kk=0; k < pbag_num ; k++) {
1585 iStart = pbag[k+first_pbag].wGenNdx;
1586 iEnd = pbag[k+first_pbag+1].wGenNdx;
1587 for (i = iStart; i < iEnd; i++) {
1588 layerType *layer;
1589 layer = &preset[j].layer[kk];
1590 switch (pgen[i].sfGenOper) {
1591 case instrument:
1592 {
1593 #define UNUSE 0x7fffffff
1594 int32_t GsampleModes=UNUSE, GcoarseTune=UNUSE, GfineTune=UNUSE;
1595 int32_t Gpan=UNUSE, GinitialAttenuation=UNUSE,GscaleTuning=UNUSE;
1596 int32_t GoverridingRootKey = UNUSE;
1597
1598 layer->num = pgen[i].genAmount.wAmount;
1599 layer->name = inst[layer->num].achInstName;
1600 first_ibag = inst[layer->num].wInstBagNdx;
1601 ibag_num = inst[layer->num +1].wInstBagNdx - first_ibag;
1602 split_num = 0;
1603 for (l=0; l < ibag_num; l++) {
1604 mStart = ibag[l+first_ibag].wInstGenNdx;
1605 mEnd = ibag[l+first_ibag+1].wInstGenNdx;
1606 for (m=mStart; m < mEnd; m++) {
1607 if (igen[m].sfGenOper == sampleID) {
1608 split_num++;
1609 }
1610 }
1611 }
1612 layer->splits_num = split_num;
1613 layer->split =
1614 (splitType *) csound->Malloc(csound, split_num * sizeof(splitType));
1615 for (l=0; l<split_num; l++) {
1616 splitDefaults(&layer->split[l]);
1617 }
1618 for (l=0, ll=0; l < ibag_num; l++) {
1619 int32_t sglobal_zone = 1;
1620 mStart = ibag[l+first_ibag].wInstGenNdx;
1621 mEnd = ibag[l+first_ibag+1].wInstGenNdx;
1622
1623 for (m=mStart; m < mEnd; m++) {
1624 if (igen[m].sfGenOper == sampleID) sglobal_zone=0;
1625 }
1626 if (sglobal_zone) {
1627 for (m=mStart; m < mEnd; m++) {
1628 switch (igen[m].sfGenOper) {
1629 case sampleID:
1630 break;
1631 case overridingRootKey:
1632 GoverridingRootKey = igen[m].genAmount.wAmount;
1633 break;
1634 case coarseTune:
1635 GcoarseTune = igen[m].genAmount.shAmount;
1636 break;
1637 case fineTune:
1638 GfineTune = igen[m].genAmount.shAmount;
1639 break;
1640 case scaleTuning:
1641 GscaleTuning = igen[m].genAmount.shAmount;
1642 break;
1643 case pan:
1644 Gpan = igen[m].genAmount.shAmount;
1645 break;
1646 case sampleModes:
1647 GsampleModes = igen[m].genAmount.wAmount;
1648 break;
1649 case initialAttenuation:
1650 GinitialAttenuation = igen[m].genAmount.shAmount;
1651 break;
1652 case keyRange:
1653 break;
1654 case velRange:
1655 break;
1656 }
1657 }
1658 }
1659 else {
1660 splitType *split;
1661 split = &layer->split[ll];
1662 split->attack = split->decay = split->sustain =
1663 split->release = FL(0.0);
1664 if (GoverridingRootKey != UNUSE)
1665 split->overridingRootKey = (BYTE) GoverridingRootKey;
1666 if (GcoarseTune != UNUSE)
1667 split->coarseTune = (BYTE) GcoarseTune;
1668 if (GfineTune != UNUSE)
1669 split->fineTune = (BYTE) GfineTune;
1670 if (GscaleTuning != UNUSE)
1671 split->scaleTuning = (BYTE) GscaleTuning;
1672 if (Gpan != UNUSE)
1673 split->pan = (BYTE) Gpan;
1674 if (GsampleModes != UNUSE)
1675 split->sampleModes = (BYTE) GsampleModes;
1676 if (GinitialAttenuation != UNUSE)
1677 split->initialAttenuation = (BYTE) GinitialAttenuation;
1678
1679 for (m=mStart; m < mEnd; m++) {
1680 switch (igen[m].sfGenOper) {
1681 case sampleID:
1682 {
1683 int32_t num = igen[m].genAmount.wAmount;
1684 split->num= num;
1685 split->sample = &shdr[num];
1686 if (UNLIKELY(split->sample->sfSampleType & 0x8000)) {
1687 csound->Free(csound, preset);
1688 csound->ErrorMsg(csound, Str("SoundFont file \"%s\" "
1689 "contains ROM samples !\n"
1690 "At present time only RAM "
1691 "samples are allowed "
1692 "by sfload.\n"
1693 "Session aborted !"),
1694 Gfname);
1695 return NOTOK;
1696 }
1697 sglobal_zone = 0;
1698 ll++;
1699 }
1700 break;
1701 case overridingRootKey:
1702 split->overridingRootKey = (BYTE) igen[m].genAmount.wAmount;
1703 break;
1704 case coarseTune:
1705 split->coarseTune = (char) igen[m].genAmount.shAmount;
1706 break;
1707 case fineTune:
1708 split->fineTune = (char) igen[m].genAmount.shAmount;
1709 break;
1710 case scaleTuning:
1711 split->scaleTuning = igen[m].genAmount.shAmount;
1712 break;
1713 case pan:
1714 split->pan = igen[m].genAmount.shAmount;
1715 break;
1716 case sampleModes:
1717 split->sampleModes = (BYTE) igen[m].genAmount.wAmount;
1718 break;
1719 case initialAttenuation:
1720 split->initialAttenuation = igen[m].genAmount.shAmount;
1721 break;
1722 case keyRange:
1723 split->minNoteRange = igen[m].genAmount.ranges.byLo;
1724 split->maxNoteRange = igen[m].genAmount.ranges.byHi;
1725 break;
1726 case velRange:
1727 split->minVelRange = igen[m].genAmount.ranges.byLo;
1728 split->maxVelRange = igen[m].genAmount.ranges.byHi;
1729 break;
1730 case startAddrsOffset:
1731 split->startOffset += igen[m].genAmount.shAmount;
1732 break;
1733 case endAddrsOffset:
1734 split->endOffset += igen[m].genAmount.shAmount;
1735 break;
1736 case startloopAddrsOffset:
1737 split->startLoopOffset += igen[m].genAmount.shAmount;
1738 break;
1739 case endloopAddrsOffset:
1740 split->endLoopOffset += igen[m].genAmount.shAmount;
1741 break;
1742 case startAddrsCoarseOffset:
1743 split->startOffset += igen[m].genAmount.shAmount * 32768;
1744 break;
1745 case endAddrsCoarseOffset:
1746 split->endOffset += igen[m].genAmount.shAmount * 32768;
1747 break;
1748 case startloopAddrCoarseOffset:
1749 split->startLoopOffset += igen[m].genAmount.shAmount * 32768;
1750 break;
1751 case endloopAddrsCoarseOffset:
1752 split->endLoopOffset += igen[m].genAmount.shAmount * 32768;
1753 break;
1754 case delayVolEnv:
1755 csound->Message(csound, "del: %f\n",
1756 (double) igen[m].genAmount.shAmount);
1757 break;
1758 case attackVolEnv: /*attack */
1759 split->attack = POWER(FL(2.0),
1760 igen[m].genAmount.shAmount/FL(1200.0));
1761 /* csound->Message(csound, "att: %f\n", split->attack ); */
1762 break;
1763 /* case holdVolEnv: */ /*hold 35 */
1764 case decayVolEnv: /*decay */
1765 split->decay = POWER(FL(2.0),
1766 igen[m].genAmount.shAmount/FL(1200.0));
1767 /* csound->Message(csound, "dec: %f\n", split->decay); */
1768 break;
1769 case sustainVolEnv: /*sustain */
1770 split->sustain = POWER(FL(10.0),
1771 -igen[m].genAmount.shAmount/FL(20.0));
1772 /* csound->Message(csound, "sus: %f\n", split->sustain); */
1773 break;
1774 case releaseVolEnv: /*release */
1775 split->release = POWER(FL(2.0),
1776 igen[m].genAmount.shAmount/FL(1200.0));
1777 /* csound->Message(csound, "rel: %f\n", split->release); */
1778 break;
1779 case keynum:
1780 /*csound->Message(csound, "");*/
1781 break;
1782 case velocity:
1783 /*csound->Message(csound, "");*/
1784 break;
1785 case exclusiveClass:
1786 /*csound->Message(csound, "");*/
1787 break;
1788
1789 }
1790 }
1791 }
1792 }
1793 kk++;
1794 }
1795 break;
1796 case coarseTune:
1797 layer->coarseTune = (char) pgen[i].genAmount.shAmount;
1798 break;
1799 case fineTune:
1800 layer->fineTune = (char) pgen[i].genAmount.shAmount;
1801 break;
1802 case scaleTuning:
1803 layer->scaleTuning = pgen[i].genAmount.shAmount;
1804 break;
1805 case initialAttenuation:
1806 layer->initialAttenuation = pgen[i].genAmount.shAmount;
1807 break;
1808 case pan:
1809 layer->pan = pgen[i].genAmount.shAmount;
1810 break;
1811 case keyRange:
1812 layer->minNoteRange = pgen[i].genAmount.ranges.byLo;
1813 layer->maxNoteRange = pgen[i].genAmount.ranges.byHi;
1814 break;
1815 case velRange:
1816 layer->minVelRange = pgen[i].genAmount.ranges.byLo;
1817 layer->maxVelRange = pgen[i].genAmount.ranges.byHi;
1818 break;
1819 }
1820 }
1821 }
1822 }
1823 end_fill_presets:
1824 soundFont->preset = preset;
1825 /* fill layer list */
1826 {
1827 instrType *instru;
1828 size = soundFont->chunk.instChunk->ckSize / sizeof(sfInst);
1829 soundFont->instrs_num = size;
1830 instru = (instrType *) csound->Malloc(csound, size * sizeof(layerType));
1831 for (j=0; j < size; j++) {
1832 #define UNUSE 0x7fffffff
1833 int32_t GsampleModes=UNUSE, GcoarseTune=UNUSE, GfineTune=UNUSE;
1834 int32_t Gpan=UNUSE, GinitialAttenuation=UNUSE,GscaleTuning=UNUSE;
1835 int32_t GoverridingRootKey = UNUSE;
1836
1837 instru[j].name = inst[j].achInstName;
1838 if (strcmp(instru[j].name,"EOI")==0) {
1839 soundFont->instrs_num = j;
1840 goto end_fill_layers;
1841 }
1842 instru[j].num = j;
1843 first_ibag = inst[j].wInstBagNdx;
1844 ibag_num = inst[j+1].wInstBagNdx - first_ibag;
1845 split_num=0;
1846 for (l=0; l < ibag_num; l++) {
1847 mStart = ibag[l+first_ibag].wInstGenNdx;
1848 mEnd = ibag[l+first_ibag+1].wInstGenNdx;
1849 for (m=mStart; m < mEnd; m++) {
1850 if (igen[m].sfGenOper == sampleID) {
1851 split_num++;
1852 }
1853 }
1854 }
1855 instru[j].splits_num = split_num;
1856 instru[j].split =
1857 (splitType *) csound->Malloc(csound, split_num * sizeof(splitType));
1858 for (l=0; l<split_num; l++) {
1859 splitDefaults(&instru[j].split[l]);
1860 }
1861 for (l=0, ll=0; l < ibag_num; l++) {
1862 int32_t sglobal_zone = 1;
1863 mStart = ibag[l+first_ibag].wInstGenNdx;
1864 mEnd = ibag[l+first_ibag+1].wInstGenNdx;
1865
1866 for (m=mStart; m < mEnd; m++) {
1867 if (igen[m].sfGenOper == sampleID) sglobal_zone=0;
1868 }
1869 if (sglobal_zone) {
1870 for (m=mStart; m < mEnd; m++) {
1871 switch (igen[m].sfGenOper) {
1872 case sampleID:
1873 break;
1874 case overridingRootKey:
1875 GoverridingRootKey = igen[m].genAmount.wAmount;
1876 break;
1877 case coarseTune:
1878 GcoarseTune = igen[m].genAmount.shAmount;
1879 break;
1880 case fineTune:
1881 GfineTune = igen[m].genAmount.shAmount;
1882 break;
1883 case scaleTuning:
1884 GscaleTuning = igen[m].genAmount.shAmount;
1885 break;
1886 case pan:
1887 Gpan = igen[m].genAmount.shAmount;
1888 break;
1889 case sampleModes:
1890 GsampleModes = igen[m].genAmount.wAmount;
1891 break;
1892 case initialAttenuation:
1893 GinitialAttenuation = igen[m].genAmount.shAmount;
1894 break;
1895 case keyRange:
1896 break;
1897 case velRange:
1898 break;
1899 }
1900 }
1901 }
1902 else {
1903 splitType *split;
1904 split = &instru[j].split[ll];
1905 if (GoverridingRootKey != UNUSE)
1906 split->overridingRootKey = (BYTE) GoverridingRootKey;
1907 if (GcoarseTune != UNUSE)
1908 split->coarseTune = (BYTE) GcoarseTune;
1909 if (GfineTune != UNUSE)
1910 split->fineTune = (BYTE) GfineTune;
1911 if (GscaleTuning != UNUSE)
1912 split->scaleTuning = (BYTE) GscaleTuning;
1913 if (Gpan != UNUSE)
1914 split->pan = (BYTE) Gpan;
1915 if (GsampleModes != UNUSE)
1916 split->sampleModes = (BYTE) GsampleModes;
1917 if (GinitialAttenuation != UNUSE)
1918 split->initialAttenuation = (BYTE) GinitialAttenuation;
1919
1920 for (m=mStart; m < mEnd; m++) {
1921 switch (igen[m].sfGenOper) {
1922 case sampleID:
1923 {
1924 int32_t num = igen[m].genAmount.wAmount;
1925 split->num= num;
1926 split->sample = &shdr[num];
1927 if (UNLIKELY(split->sample->sfSampleType & 0x8000)) {
1928 csound->Free(csound, instru);
1929 csound->ErrorMsg(csound, Str("SoundFont file \"%s\" contains "
1930 "ROM samples !\n"
1931 "At present time only RAM samples "
1932 "are allowed by sfload.\n"
1933 "Session aborted !"), Gfname);
1934 return NOTOK;
1935 }
1936 sglobal_zone = 0;
1937 ll++;
1938 }
1939 break;
1940 case overridingRootKey:
1941 split->overridingRootKey = (BYTE) igen[m].genAmount.wAmount;
1942 break;
1943 case coarseTune:
1944 split->coarseTune = (char) igen[m].genAmount.shAmount;
1945 break;
1946 case fineTune:
1947 split->fineTune = (char) igen[m].genAmount.shAmount;
1948 break;
1949 case scaleTuning:
1950 split->scaleTuning = igen[m].genAmount.shAmount;
1951 break;
1952 case pan:
1953 split->pan = igen[m].genAmount.shAmount;
1954 break;
1955 case sampleModes:
1956 split->sampleModes = (BYTE) igen[m].genAmount.wAmount;
1957 break;
1958 case initialAttenuation:
1959 split->initialAttenuation = igen[m].genAmount.shAmount;
1960 break;
1961 case keyRange:
1962 split->minNoteRange = igen[m].genAmount.ranges.byLo;
1963 split->maxNoteRange = igen[m].genAmount.ranges.byHi;
1964 break;
1965 case velRange:
1966 split->minVelRange = igen[m].genAmount.ranges.byLo;
1967 split->maxVelRange = igen[m].genAmount.ranges.byHi;
1968 break;
1969 case startAddrsOffset:
1970 split->startOffset += igen[m].genAmount.shAmount;
1971 break;
1972 case endAddrsOffset:
1973 split->endOffset += igen[m].genAmount.shAmount;
1974 break;
1975 case startloopAddrsOffset:
1976 split->startLoopOffset += igen[m].genAmount.shAmount;
1977 break;
1978 case endloopAddrsOffset:
1979 split->endLoopOffset += igen[m].genAmount.shAmount;
1980 break;
1981 case startAddrsCoarseOffset:
1982 split->startOffset += igen[m].genAmount.shAmount * 32768;
1983 break;
1984 case endAddrsCoarseOffset:
1985 split->endOffset += igen[m].genAmount.shAmount * 32768;
1986 break;
1987 case startloopAddrCoarseOffset:
1988 split->startLoopOffset += igen[m].genAmount.shAmount * 32768;
1989 break;
1990 case endloopAddrsCoarseOffset:
1991 split->endLoopOffset += igen[m].genAmount.shAmount * 32768;
1992 break;
1993 case keynum:
1994 /*csound->Message(csound, "");*/
1995 break;
1996 case velocity:
1997 /*csound->Message(csound, "");*/
1998 break;
1999 case exclusiveClass:
2000 /*csound->Message(csound, "");*/
2001 break;
2002 }
2003 }
2004 }
2005 }
2006 }
2007 end_fill_layers:
2008 soundFont->instr = instru;
2009 }
2010 return OK;
2011 }
2012
layerDefaults(layerType * layer)2013 static void layerDefaults(layerType *layer)
2014 {
2015 layer->splits_num = 0;
2016 layer->minNoteRange = 0;
2017 layer->maxNoteRange = 127;
2018 layer->minVelRange = 0;
2019 layer->maxVelRange = 127;
2020 layer->coarseTune = 0;
2021 layer->fineTune = 0;
2022 layer->scaleTuning = 0;
2023 layer->initialAttenuation = 0;
2024 layer->pan = 0;
2025 }
2026
splitDefaults(splitType * split)2027 static void splitDefaults(splitType *split)
2028 {
2029 split->sampleModes = 0;
2030 split->minNoteRange = 0;
2031 split->maxNoteRange = 127;
2032 split->minVelRange = 0;
2033 split->maxVelRange = 127;
2034 split->startOffset = 0;
2035 split->endOffset = 0;
2036 split->startLoopOffset = 0;
2037 split->endLoopOffset = 0;
2038 split->overridingRootKey = -1;
2039 split->coarseTune = 0;
2040 split->fineTune = 0;
2041 split->scaleTuning = 100;
2042 split->initialAttenuation = 0;
2043 split->pan = 0;
2044 }
2045
chunk_read(CSOUND * csound,FILE * fil,CHUNK * chunk)2046 static int32_t chunk_read(CSOUND *csound, FILE *fil, CHUNK *chunk)
2047 {
2048 if (UNLIKELY(4 != fread(chunk->ckID,1,4, fil)))
2049 return 0;
2050 if (UNLIKELY(1 != fread(&chunk->ckSize,4,1,fil))) {
2051 chunk->ckSize = 0;
2052 return 0;
2053 }
2054 //if (UNLIKELY(chunk->ckSize>0x8fffff00)) return 0;
2055 ChangeByteOrder("d", (char *)&chunk->ckSize, 4);
2056 chunk->ckDATA = (BYTE *) csound->Malloc(csound, chunk->ckSize);
2057 if (chunk->ckDATA==NULL)
2058 return 0;
2059 if (chunk->ckSize>0x8fffff00) return 0;
2060 return fread(chunk->ckDATA,1,chunk->ckSize,fil);
2061 }
2062
dword(char * p)2063 static DWORD dword(char *p)
2064 {
2065 union cheat {
2066 DWORD i;
2067 char c[4];
2068 } x;
2069 x.c[0] = *p++;
2070 x.c[1] = *p++;
2071 x.c[2] = *p++;
2072 x.c[3] = *p++;
2073 return x.i;
2074 }
2075
fill_SfPointers(CSOUND * csound)2076 static void fill_SfPointers(CSOUND *csound)
2077 {
2078 char *chkp;
2079 DWORD chkid, j, size;
2080
2081 CHUNK *main_chunk;
2082 CHUNK *smplChunk=NULL, *phdrChunk=NULL, *pbagChunk=NULL, *pmodChunk=NULL;
2083 CHUNK *pgenChunk=NULL, *instChunk=NULL, *ibagChunk=NULL, *imodChunk=NULL;
2084 CHUNK *igenChunk=NULL, *shdrChunk=NULL;
2085
2086 SFBANK *soundFont;
2087 sfontg *globals;
2088 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
2089
2090 if (UNLIKELY(globals == NULL)) {
2091 csound->ErrorMsg(csound, Str("Sfont: cannot use globals/"));
2092 return;
2093 }
2094
2095 soundFont = globals->soundFont;
2096 if (LIKELY(soundFont != NULL))
2097 main_chunk=&(soundFont->chunk.main_chunk);
2098 else {
2099 csound->ErrorMsg(csound, Str("Sfont: cannot use globals/"));
2100 return;
2101 }
2102
2103 if (UNLIKELY(main_chunk->ckDATA == NULL)) {
2104 csound->ErrorMsg(csound, Str("Sfont format not compatible"));
2105 return;
2106 }
2107 chkp = (char *) main_chunk->ckDATA+4;
2108
2109 for (j=4; j< main_chunk->ckSize;) {
2110
2111 chkid = /* (DWORD *) chkp*/ dword(chkp);
2112 /* #ifdef BETA */
2113 /* csound->Message(csound, "Looking at %.4s\n", (char*) &chkid); */
2114 /* #endif */
2115 if (chkid == s2d("LIST")) {
2116 /* #ifdef BETA */
2117 /* csound->Message(csound, "LIST "); */
2118 /* #endif */
2119 j += 4; chkp += 4;
2120 ChangeByteOrder("d", chkp, 4);
2121 size = /* (DWORD *) chkp */ dword(chkp);
2122 j += 4; chkp += 4;
2123 chkid = /* (DWORD *) chkp */ dword(chkp);
2124 /* #ifdef BETA */
2125 /* csound->Message(csound, "**chkid %p %p\n", */
2126 /* (void*) chkid, (void*) (*((DWORD *) chkp))); */
2127 /* csound->Message(csound, ":Looking at %.4s (%u)\n", */
2128 /* (char*) &chkid, (uint32_t) size); */
2129 /* #endif */
2130 if (chkid == s2d("INFO")) {
2131 chkp += size;
2132 j += size;
2133 }
2134 else if (chkid == s2d("sdta")) {
2135 j +=4; chkp += 4;
2136 smplChunk = (CHUNK *) chkp;
2137 soundFont->sampleData = (void *) &(smplChunk->ckDATA);
2138 ChangeByteOrder("d", chkp + 4, 4);
2139 ChangeByteOrder("w", chkp + 8, size - 12);
2140 /* #ifdef BETA */
2141 /* { */
2142 /* DWORD i; */
2143 /* for (i=size-12; i< size+4; i++) */
2144 /* csound->Message(csound, "%c(%.2x)", chkp[i], chkp[i]); */
2145 /* csound->Message(csound, "\n"); */
2146 /* } */
2147 /* #endif */
2148 chkp += size-4;
2149 j += size-4;
2150 }
2151 else if (chkid == s2d("pdta")) {
2152 j += 4; chkp += 4;
2153 do {
2154 chkid = /* (DWORD *) chkp */ dword(chkp);
2155 /* csound->Message(csound, "::Looking at %.4s (%d)\n",&chkid,size); */
2156 if (chkid == s2d("phdr")) {
2157 phdrChunk = (CHUNK *) chkp;
2158 soundFont->chunk.phdr= (sfPresetHeader *) &phdrChunk->ckDATA;
2159 ChangeByteOrder("d", chkp + 4, 4);
2160 ChangeByteOrder("b20w3d3", chkp + 8, phdrChunk->ckSize);
2161 chkp += phdrChunk->ckSize+8;
2162 j += phdrChunk->ckSize+8;
2163 }
2164 else if (chkid == s2d("pbag")) {
2165 pbagChunk = (CHUNK *) chkp;
2166 soundFont->chunk.pbag= (void *) &pbagChunk->ckDATA;
2167 ChangeByteOrder("d", chkp + 4, 4);
2168 ChangeByteOrder("w2", chkp + 8, pbagChunk->ckSize);
2169 chkp += pbagChunk->ckSize+8;
2170 j += pbagChunk->ckSize+8;
2171 }
2172 else if (chkid == s2d("pmod")) {
2173 pmodChunk = (CHUNK *) chkp;
2174 soundFont->chunk.pmod= (void *) &pmodChunk->ckDATA;
2175 ChangeByteOrder("d", chkp + 4, 4);
2176 ChangeByteOrder("w5", chkp + 8, pmodChunk->ckSize);
2177 chkp += pmodChunk->ckSize+8;
2178 j += pmodChunk->ckSize+8;
2179 }
2180 else if (chkid == s2d("pgen")) {
2181 pgenChunk = (CHUNK *) chkp;
2182 soundFont->chunk.pgen= (void *) &pgenChunk->ckDATA;
2183 ChangeByteOrder("d", chkp + 4, 4);
2184 ChangeByteOrder("w2", chkp + 8, pgenChunk->ckSize);
2185 chkp += pgenChunk->ckSize+8;
2186 j += pgenChunk->ckSize+8;
2187 }
2188 else if (chkid == s2d("inst")) {
2189 instChunk = (CHUNK *) chkp;
2190 soundFont->chunk.inst= (sfInst *) &instChunk->ckDATA;
2191 ChangeByteOrder("d", chkp + 4, 4);
2192 ChangeByteOrder("b20w", chkp + 8, instChunk->ckSize);
2193 chkp += instChunk->ckSize+8;
2194 j += instChunk->ckSize+8;
2195 }
2196 else if (chkid == s2d("ibag")) {
2197 ibagChunk = (CHUNK *) chkp;
2198 soundFont->chunk.ibag= (void *) &ibagChunk->ckDATA;
2199 ChangeByteOrder("d", chkp + 4, 4);
2200 ChangeByteOrder("w2", chkp + 8, ibagChunk->ckSize);
2201 chkp += ibagChunk->ckSize+8;
2202 j += ibagChunk->ckSize+8;
2203 }
2204 else if (chkid == s2d("imod")) {
2205 imodChunk = (CHUNK *) chkp;
2206 soundFont->chunk.imod= (void *) &imodChunk->ckDATA;
2207 ChangeByteOrder("d", chkp + 4, 4);
2208 ChangeByteOrder("w5", chkp + 8, imodChunk->ckSize);
2209 chkp += imodChunk->ckSize+8;
2210 j += imodChunk->ckSize+8;
2211 }
2212 else if (chkid == s2d("igen")) {
2213 igenChunk = (CHUNK *) chkp;
2214 soundFont->chunk.igen= (sfInstGenList *) &igenChunk->ckDATA;
2215 ChangeByteOrder("d", chkp + 4, 4);
2216 ChangeByteOrder("w2", chkp + 8, igenChunk->ckSize);
2217 chkp += igenChunk->ckSize+8;
2218 j += igenChunk->ckSize+8;
2219 }
2220 else if (chkid == s2d("shdr")) {
2221 shdrChunk = (CHUNK *) chkp;
2222 soundFont->chunk.shdr= (sfSample *) &shdrChunk->ckDATA;
2223 ChangeByteOrder("d", chkp + 4, 4);
2224 ChangeByteOrder("b20d5b2w2", chkp + 8, shdrChunk->ckSize);
2225 chkp += shdrChunk->ckSize+8;
2226 j += shdrChunk->ckSize+8;
2227 }
2228 else {
2229 /* #ifdef BETA */
2230 /* csound->Message(csound, "Unknown sfont %.4s(%.8x)\n", */
2231 /* (char*) &chkid, (uint32_t) chkid); */
2232 /* #endif */
2233 shdrChunk = (CHUNK *) chkp;
2234 chkp += shdrChunk->ckSize+8;
2235 j += shdrChunk->ckSize+8;
2236 }
2237 } while (j < main_chunk->ckSize);
2238 }
2239 else {
2240 /* #ifdef BETA */
2241 /* csound->Message(csound, "Unknown sfont %.4s(%.8x)\n", */
2242 /* (char*) &chkid, (uint32_t) chkid); */
2243 /* #endif */
2244 shdrChunk = (CHUNK *) chkp;
2245 chkp += shdrChunk->ckSize+8;
2246 j += shdrChunk->ckSize+8;
2247 }
2248 }
2249 else {
2250 /* #ifdef BETA */
2251 /* csound->Message(csound, "Unknown sfont %.4s(%.8x)\n", */
2252 /* (char*) &chkid, (uint32_t) chkid); */
2253 /* #endif */
2254 shdrChunk = (CHUNK *) chkp;
2255 chkp += shdrChunk->ckSize+8;
2256 j += shdrChunk->ckSize+8;
2257 }
2258 }
2259 soundFont->chunk.smplChunk = smplChunk;
2260 soundFont->chunk.phdrChunk = phdrChunk;
2261 soundFont->chunk.pbagChunk = pbagChunk;
2262 soundFont->chunk.pmodChunk = pmodChunk;
2263 soundFont->chunk.pgenChunk = pgenChunk;
2264 soundFont->chunk.instChunk = instChunk;
2265 soundFont->chunk.ibagChunk = ibagChunk;
2266 soundFont->chunk.imodChunk = imodChunk;
2267 soundFont->chunk.igenChunk = igenChunk;
2268 soundFont->chunk.shdrChunk = shdrChunk;
2269 }
2270
2271 typedef struct _sflooper {
2272 OPDS h;
2273 MYFLT *outL, *outR; /* output */
2274 MYFLT *ivel, *inotnum, *amp, *pitch, *ipresethandle, *loop_start, *loop_end,
2275 *crossfade, *start, *imode, *ifn2, *iskip;
2276 int32_t spltNum;
2277 SHORT *sBase[MAXSPLT];
2278 FUNC *efunc;
2279 MYFLT count;
2280 int32_t lstart[MAXSPLT], lend[MAXSPLT], cfade, mode;
2281 double ndx[MAXSPLT][2]; /* table lookup ndx */
2282 double freq[MAXSPLT];
2283 int32_t firsttime[MAXSPLT], init, end[MAXSPLT], sstart[MAXSPLT];
2284 MYFLT leftlevel[MAXSPLT], rightlevel[MAXSPLT];
2285 } sflooper;
2286
sflooper_init(CSOUND * csound,sflooper * p)2287 static int32_t sflooper_init(CSOUND *csound, sflooper *p)
2288 {
2289 DWORD index = (DWORD) *p->ipresethandle;
2290 presetType *preset;
2291 SHORT *sBase;
2292 int32_t layersNum, j, spltNum = 0;
2293 sfontg *globals;
2294 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
2295
2296 preset = globals->presetp[index];
2297 sBase = globals->sampleBase[index];
2298 if (!preset) {
2299 return csound->InitError(csound, Str("sfplay: invalid or "
2300 "out-of-range preset number"));
2301 }
2302 layersNum = preset->layers_num;
2303 for (j =0; j < layersNum; j++) {
2304 layerType *layer = &preset->layer[j];
2305 int32_t vel= (int32_t) *p->ivel, notnum= (int32_t) *p->inotnum;
2306 if (notnum >= layer->minNoteRange &&
2307 notnum <= layer->maxNoteRange &&
2308 vel >= layer->minVelRange &&
2309 vel <= layer->maxVelRange) {
2310 int32_t splitsNum = layer->splits_num, k;
2311 for (k = 0; k < splitsNum; k++) {
2312 splitType *split = &layer->split[k];
2313 if (notnum >= split->minNoteRange &&
2314 notnum <= split->maxNoteRange &&
2315 vel >= split->minVelRange &&
2316 vel <= split->maxVelRange) {
2317 sfSample *sample = split->sample;
2318 DWORD start=sample->dwStart;
2319 MYFLT attenuation;
2320 double pan;
2321 double freq, orgfreq;
2322 double tuneCorrection = split->coarseTune + layer->coarseTune +
2323 (split->fineTune + layer->fineTune)*0.01;
2324 int32_t orgkey = split->overridingRootKey;
2325 if (orgkey == -1) orgkey = sample->byOriginalKey;
2326 orgfreq = globals->pitches[orgkey];
2327 freq = orgfreq * pow(2.0, ONETWELTH * tuneCorrection) *
2328 pow(2.0, ONETWELTH * (split->scaleTuning*0.01) * (notnum-orgkey));
2329 p->freq[spltNum]= (freq/orgfreq) * sample->dwSampleRate*csound->onedsr;
2330 attenuation = (MYFLT) (layer->initialAttenuation +
2331 split->initialAttenuation);
2332 attenuation = POWER(FL(2.0), (-FL(1.0)/FL(60.0)) * attenuation )
2333 * GLOBAL_ATTENUATION;
2334 pan = (double)(split->pan + layer->pan) / 1000.0 + 0.5;
2335 if (pan > 1.0) pan = 1.0;
2336 else if (pan < 0.0) pan = 0.0;
2337 p->sBase[spltNum] = sBase;
2338 p->sstart[spltNum] = start;
2339 p->end[spltNum] = sample->dwEnd + split->endOffset;
2340 p->leftlevel[spltNum] = (MYFLT) sqrt(1.0-pan) * attenuation;
2341 p->rightlevel[spltNum] = (MYFLT) sqrt(pan) * attenuation;
2342 spltNum++;
2343 }
2344 }
2345 }
2346 }
2347 p->spltNum = spltNum;
2348 if (*p->ifn2 != 0) p->efunc = csound->FTnp2Finde(csound, p->ifn2);
2349 else p->efunc = NULL;
2350
2351 if (*p->iskip == 0){
2352 p->mode = (int32_t) *p->imode;
2353
2354 for (j=0; j < spltNum; j++) {
2355 if (p->mode == 0 || p->mode == 2){
2356 if ((p->ndx[j][0] = *p->start*CS_ESR+p->sstart[j]) < 0)
2357 p->ndx[j][0] = 0;
2358 if (p->ndx[j][0] >= p->end[j])
2359 p->ndx[j][0] = (double) p->end[j] - 1.0;
2360 p->count = 0;
2361 }
2362 p->firsttime[j] = 1;
2363 }
2364 p->init = 1;
2365
2366 }
2367 return OK;
2368 }
2369
sflooper_process(CSOUND * csound,sflooper * p)2370 static int32_t sflooper_process(CSOUND *csound, sflooper *p)
2371 {
2372 int32_t k;
2373 uint32_t offset = p->h.insdshead->ksmps_offset;
2374 uint32_t early = p->h.insdshead->ksmps_no_end;
2375 uint32_t i, nsmps = CS_KSMPS;
2376 MYFLT *outL = p->outL, *outR = p->outR, out, sr = CS_ESR;
2377 MYFLT amp = *(p->amp), pit = *(p->pitch);
2378 SHORT **base = p->sBase, *tab;
2379 double *ndx;
2380 MYFLT frac0, frac1, *etab, left, right;
2381 int32_t *nend = p->end, *loop_end = p->lend, *loop_start = p->lstart,
2382 crossfade = p->cfade, send, sstart, spltNum = p->spltNum;
2383 MYFLT count = p->count,fadein, fadeout, pitch;
2384 int32_t *firsttime = p->firsttime, elen, mode=p->mode, init = p->init;
2385 uint32 tndx0, tndx1;
2386
2387 if (p->efunc != NULL) {
2388 etab = p->efunc->ftable;
2389 elen = p->efunc->flen;
2390 }
2391 else {
2392 etab = NULL;
2393 elen = 0;
2394 }
2395
2396 /* loop parameters & check */
2397 if (pit < FL(0.0)) pit = FL(0.0);
2398 memset(outL, 0, nsmps*sizeof(MYFLT));
2399 memset(outR, 0, nsmps*sizeof(MYFLT));
2400 if (UNLIKELY(early)) nsmps -= early;
2401
2402 for (k=0; k < spltNum; k++) {
2403
2404 tab = base[k];
2405 sstart = p->sstart[k];
2406 send = nend[k] + sstart;
2407 ndx = p->ndx[k];
2408 left = p->leftlevel[k];
2409 right = p->rightlevel[k];
2410 pitch = pit*p->freq[k];
2411
2412 if (firsttime[k]) {
2413 int32_t loopsize;
2414 loop_start[k] = (int32_t) (*p->loop_start*sr) + sstart;
2415 loop_end[k] = (int32_t) (*p->loop_end*sr) + sstart;
2416 loop_start[k] = loop_start[k] < sstart ? sstart : loop_start[k];
2417 /* TODO : CHECKS */
2418 if(loop_start[k] > send) {
2419 csound->Warning(csound, "loop start %f beyond sample end %f, clamping.\n",
2420 (loop_start[k] - sstart)/sr,
2421 (send - sstart)/sr);
2422 loop_start[k] = send;
2423 }
2424 if(loop_end[k] > send) {
2425 csound->Warning(csound, "loop end %f beyond sample end %f, clamping.\n",
2426 (loop_end[k] - sstart)/sr,
2427 (send - sstart)/sr);
2428 loop_end[k] = send;
2429 }
2430 loopsize = loop_end[k] - loop_start[k];
2431 crossfade = (int32_t) (*p->crossfade*sr);
2432 if (mode == 1) {
2433 ndx[0] = (double) loop_end[k];
2434 ndx[1] = (double) loop_end[k];
2435 count = (MYFLT) crossfade;
2436 p->cfade = crossfade = crossfade > loopsize ? loopsize : crossfade;
2437 }
2438 else if (mode == 2) {
2439 ndx[1] = (double) loop_start[k] - 1.0;
2440 p->cfade = crossfade = crossfade > loopsize/2 ? loopsize/2 - 1 : crossfade;
2441 }
2442 else {
2443 ndx[1] = (double) loop_start[k];
2444 p->cfade = crossfade = crossfade > loopsize ? loopsize : crossfade;
2445 }
2446 firsttime[k] = 0;
2447 }
2448 for (i=offset; i < nsmps; i++) {
2449 if (mode == 1){ /* backwards */
2450 tndx0 = (int32_t) ndx[0];
2451 frac0 = ndx[0] - tndx0;
2452 if (ndx[0] > crossfade + loop_start[k])
2453 out = amp*(tab[tndx0] + frac0*(tab[tndx0+1] - tab[tndx0]));
2454 else {
2455 tndx1 = (int32_t) ndx[1];
2456 frac1 = ndx[1] - tndx1;
2457 if (etab==NULL){
2458 fadeout = count/crossfade;
2459 fadein = FL(1.0) - fadeout;
2460 }
2461 else {
2462 fadeout = elen*count/crossfade;
2463 fadein = etab[elen - (int32_t)fadeout];
2464 fadeout = etab[(int32_t)fadeout];
2465 }
2466 out = amp*(fadeout*(tab[tndx0] + frac0*(tab[tndx0+1] - tab[tndx0]))
2467 + fadein*(tab[tndx1] + frac1*(tab[tndx1+1] - tab[tndx1])));
2468
2469 ndx[1] -= pitch;
2470 count -= pitch;
2471 }
2472 ndx[0] -= pitch;
2473
2474 if (ndx[0] <= loop_start[k]) {
2475 int32_t loopsize;
2476 loop_start[k] = (int32_t) (*p->loop_start*sr) + sstart;
2477 loop_end[k] = (int32_t) (*p->loop_end*sr) + sstart;
2478 loop_start[k] = loop_start[k] < sstart ? sstart: loop_start[k];
2479 /* CHECKS */
2480 if(loop_start[k] > send) {
2481 csound->Warning(csound, "loop start %f beyond sample end %f, clamping.\n",
2482 (loop_start[k] - sstart)/sr,
2483 (send - sstart)/sr);
2484 loop_start[k] = send;
2485 }
2486 if(loop_end[k] > send) {
2487 csound->Warning(csound, "loop end %f beyond sample end %f, clamping.\n",
2488 (loop_end[k] - sstart)/sr,
2489 (send - sstart)/sr);
2490 loop_end[k] = send;
2491 }
2492 loopsize = loop_end[k] - loop_start[k];
2493 crossfade = (int32_t) (*p->crossfade*sr);
2494 p->cfade = crossfade = crossfade > loopsize ? loopsize : crossfade;
2495 ndx[0] = ndx[1];
2496 ndx[1] = (double)loop_end[k];
2497 count=(MYFLT)crossfade;
2498 }
2499 outR[i] += out*right;
2500 outL[i] += out*left;
2501 }
2502 else if (mode==2) { /* back and forth */
2503 out = 0;
2504 /* this is the forward reader */
2505 if (init && ndx[0] < loop_start[k] + crossfade) {
2506 tndx0 = (int32_t) ndx[0];
2507 frac0 = ndx[0] - tndx0;
2508 out = amp*(tab[tndx0] + frac0*(tab[tndx0+1] - tab[tndx0]));
2509 ndx[0] += pitch;
2510 }
2511 else if (ndx[0] < loop_start[k] + crossfade) {
2512 if (etab==NULL) fadein = count/crossfade;
2513 else fadein = etab[(int32_t)(elen*count/crossfade)];
2514 tndx0 = (int32_t) ndx[0];
2515 frac0 = ndx[0] - tndx0;
2516 out += amp*fadein*(tab[tndx0] + frac0*(tab[tndx0+1] - tab[tndx0]));
2517 ndx[0] += pitch;
2518 count += pitch;
2519 }
2520 else if (ndx[0] < loop_end[k] - crossfade) {
2521 tndx0 = (int32_t) ndx[0];
2522 frac0 = ndx[0] - tndx0;
2523 out = amp*(tab[tndx0] + frac0*(tab[tndx0+1] - tab[tndx0]));
2524 ndx[0] += pitch;
2525 init = 0;
2526 if (ndx[0] >= loop_end[k] - crossfade) {
2527 ndx[1] = (double) loop_end[k];
2528 count = 0;
2529 }
2530 }
2531 else if (ndx[0] < loop_end[k]) {
2532 if (etab==NULL) fadeout = FL(1.0) - count/crossfade;
2533 else fadeout = etab[(int32_t)(elen*(FL(1.0) - count/crossfade))];
2534 tndx0 = (int32_t) ndx[0];
2535 frac0 = ndx[0] - tndx0;
2536 out += amp*fadeout*(tab[tndx0] + frac0*(tab[tndx0+1] - tab[tndx0]));
2537 ndx[0] += pitch;
2538 count += pitch;
2539 }
2540 /* this is the backward reader */
2541 if (ndx[1] > loop_end[k] - crossfade) {
2542 if (etab==NULL) fadein = count/crossfade;
2543 else fadein = etab[(int32_t)(elen*count/crossfade)];
2544 tndx1 = (int32_t) ndx[1];
2545 frac1 = ndx[1] - tndx1;
2546 out += amp*fadein*(tab[tndx1] + frac1*(tab[tndx1+1] - tab[tndx1]));
2547 ndx[1] -= pitch;
2548 }
2549 else if (ndx[1] > loop_start[k] + crossfade) {
2550 tndx1 = (int32_t) ndx[1];
2551 frac1 = ndx[1] - tndx1;
2552 out = amp*(tab[tndx1] + frac1*(tab[tndx1+1] - tab[tndx1]));
2553 ndx[1] -= pitch;
2554 if (ndx[1] <= loop_start[k] + crossfade) {
2555 ndx[0] = (double) loop_start[k];
2556 count = 0;
2557 }
2558 }
2559 else if (ndx[1] > loop_start[k]) {
2560 if (etab==NULL) fadeout = FL(1.0) - count/crossfade;
2561 else fadeout = etab[(int32_t)(elen*(FL(1.0) - count/crossfade))];
2562 tndx1 = (int32_t) ndx[1];
2563 frac1 = ndx[1] - tndx1;
2564 out += amp*fadeout*(tab[tndx1] + frac1*(tab[tndx1+1] - tab[tndx1]));
2565 ndx[1] -= pitch;
2566 if (ndx[1] <= loop_start[k]) {
2567 int32_t loopsize;
2568 loop_start[k] = (int32_t) (*p->loop_start*sr) + p->sstart[k];
2569 loop_end[k] = (int32_t) (*p->loop_end*sr) + p->sstart[k];
2570 loop_start[k] = loop_start[k] < sstart ? sstart: loop_start[k];
2571 /* CHECKS */
2572 if(loop_start[k] > send) {
2573 csound->Warning(csound, "loop start %f beyond sample end %f, clamping.\n",
2574 (loop_start[k] - sstart)/sr,
2575 (send - sstart)/sr);
2576 loop_start[k] = send;
2577 }
2578 if(loop_end[k] > send) {
2579 csound->Warning(csound, "loop end %f beyond sample end %f, clamping.\n",
2580 (loop_end[k] - sstart)/sr,
2581 (send - sstart)/sr);
2582 loop_end[k] = send;
2583 }
2584
2585 loopsize = loop_end[k] - loop_start[k];
2586 crossfade = (int32_t) (*p->crossfade*sr);
2587 p->cfade = crossfade =
2588 crossfade > loopsize/2 ? loopsize/2-1 : crossfade;
2589 }
2590 }
2591 outR[i] += out*right;
2592 outL[i] += out*left;
2593 }
2594 else { /* normal */
2595 out = 0;
2596 tndx0 = (uint32) ndx[0];
2597 frac0 = ndx[0] - tndx0;
2598 if (ndx[0] < loop_end[k]-crossfade)
2599 out = amp*(tab[tndx0] + frac0*(tab[tndx0+1] - tab[tndx0]));
2600 else {
2601 tndx1 = (int32_t) ndx[1];
2602 frac1 = ndx[1] - tndx1;
2603 if (etab==NULL) {
2604 fadein = count/crossfade;
2605 fadeout = FL(1.0) - fadein;
2606 }
2607 else {
2608 fadein = elen*count/crossfade;
2609 fadeout = etab[elen - (int32_t)fadein];
2610 fadein = etab[(int32_t)fadein];
2611 }
2612 out = amp*(fadeout*(tab[tndx0] + frac0*(tab[tndx0+1] - tab[tndx0]))
2613 + fadein*(tab[tndx1] + frac1*(tab[tndx1+1] - tab[tndx1])));
2614 ndx[1]+=pitch;
2615 count+=pitch;
2616 }
2617 ndx[0]+=pitch;
2618 if (ndx[0] >= loop_end[k]) {
2619 int32_t loopsize;
2620 loop_start[k] = (int32_t) (*p->loop_start*sr) + p->sstart[k];
2621 loop_end[k] = (int32_t) (*p->loop_end*sr) + p->sstart[k];
2622 loop_start[k] = loop_start[k] < sstart ? sstart: loop_start[k];
2623 /* TODO : CHECKS */
2624 if(loop_start[k] > send) {
2625 csound->Warning(csound, "loop start %f beyond sample end %f, clamping.\n",
2626 (loop_start[k] - sstart)/sr,
2627 (send - sstart)/sr);
2628 loop_start[k] = send;
2629 }
2630 if(loop_end[k] > send) {
2631 csound->Warning(csound, "loop end %f beyond sample end %f, clamping.\n",
2632 (loop_end[k] - sstart)/sr,
2633 (send - sstart)/sr);
2634 loop_end[k] = send;
2635 }
2636 loopsize = loop_end[k] - loop_start[k];
2637 crossfade = (int32_t) (*p->crossfade*sr);
2638 p->cfade = crossfade = crossfade > loopsize ? loopsize-1 : crossfade;
2639 ndx[0] = ndx[1];
2640 ndx[1] = (double)loop_start[k];
2641 count=0;
2642 }
2643 outR[i] += out*right;
2644 outL[i] += out*left;
2645 }
2646 }
2647
2648 }
2649 p->count = count;
2650 p->cfade = crossfade;
2651
2652 p->init = init;
2653 return OK;
2654 }
2655
2656 #define S sizeof
2657
2658 static OENTRY localops[] = {
2659 { "sfload",S(SFLOAD), 0, 1, "i", "S", (SUBR)SfLoad_S, NULL, NULL },
2660 { "sfload.i",S(SFLOAD), 0, 1, "i", "i", (SUBR)SfLoad, NULL, NULL },
2661 { "sfpreset",S(SFPRESET), 0, 1, "i", "iiii", (SUBR)SfPreset },
2662 { "sfplay", S(SFPLAY), 0, 3, "aa", "iixxiooo",
2663 (SUBR)SfPlay_set, (SUBR)SfPlay },
2664 { "sfplaym", S(SFPLAYMONO), 0, 3, "a", "iixxiooo",
2665 (SUBR)SfPlayMono_set, (SUBR)SfPlayMono },
2666 { "sfplist",S(SFPLIST), 0, 1, "", "i", (SUBR)Sfplist },
2667 { "sfilist",S(SFPLIST), 0, 1, "", "i", (SUBR)Sfilist },
2668 { "sfpassign",S(SFPASSIGN), 0, 1, "", "iip", (SUBR)SfAssignAllPresets },
2669 { "sfinstrm", S(SFIPLAYMONO),0, 3, "a", "iixxiiooo",
2670 (SUBR)SfInstrPlayMono_set, (SUBR)SfInstrPlayMono },
2671 { "sfinstr", S(SFIPLAY), 0, 3, "aa", "iixxiiooo",
2672 (SUBR)SfInstrPlay_set,(SUBR)SfInstrPlay },
2673 { "sfplay3", S(SFPLAY), 0, 3, "aa", "iixxiooo",
2674 (SUBR)SfPlay_set, (SUBR)SfPlay3 },
2675 { "sfplay3m", S(SFPLAYMONO), 0, 3, "a", "iixxiooo",
2676 (SUBR)SfPlayMono_set,(SUBR)SfPlayMono3 },
2677 { "sfinstr3", S(SFIPLAY), 0, 3, "aa", "iixxiiooo",
2678 (SUBR)SfInstrPlay_set, (SUBR)SfInstrPlay3 },
2679 { "sfinstr3m", S(SFIPLAYMONO), 0, 3, "a", "iixxiiooo",
2680 (SUBR)SfInstrPlayMono_set, (SUBR)SfInstrPlayMono3 },
2681 { "sflooper", S(sflooper), 0, 3, "aa", "iikkikkkoooo",
2682 (SUBR)sflooper_init, (SUBR)sflooper_process },
2683 { NULL, 0, 0, 0, NULL, NULL, (SUBR) NULL, (SUBR) NULL, (SUBR) NULL }
2684 };
2685
sfont_ModuleCreate(CSOUND * csound)2686 int32_t sfont_ModuleCreate(CSOUND *csound)
2687 {
2688 int32_t j;
2689 sfontg *globals;
2690 csound->CreateGlobalVariable(csound, "::sfontg",
2691 sizeof(sfontg));
2692 globals = (sfontg *) (csound->QueryGlobalVariable(csound, "::sfontg"));
2693 if (globals == NULL)
2694 return csound->InitError(csound,
2695 Str("error... could not create sfont globals\n"));
2696
2697 globals->sfArray = (SFBANK *) csound->Calloc(csound, MAX_SFONT*sizeof(SFBANK));
2698 globals->presetp =
2699 (presetType **) csound->Calloc(csound, MAX_SFPRESET *sizeof(presetType *));
2700 globals->sampleBase =
2701 (SHORT **) csound->Calloc(csound, MAX_SFPRESET*sizeof(SHORT *));
2702 globals->currSFndx = 0;
2703 globals->maxSFndx = MAX_SFONT;
2704 for (j=0; j<128; j++) {
2705 globals->pitches[j] = (MYFLT) (csound->A4 * pow(2.0, (double)(j- 69)/12.0));
2706 }
2707
2708 return OK;
2709 }
2710
sfont_ModuleInit(CSOUND * csound)2711 int32_t sfont_ModuleInit(CSOUND *csound)
2712 {
2713 OENTRY *ep = (OENTRY*) &(localops[0]);
2714 int32_t err = 0;
2715
2716 while (ep->opname != NULL) {
2717 err |= csound->AppendOpcode(csound,
2718 ep->opname, ep->dsblksiz, ep->flags,
2719 ep->thread, ep->outypes, ep->intypes,
2720 (int32_t (*)(CSOUND *, void*)) ep->iopadr,
2721 (int32_t (*)(CSOUND *, void*)) ep->kopadr,
2722 (int32_t
2723 (*)(CSOUND *, void*)) ep->aopadr);
2724 ep++;
2725 }
2726 return err;
2727 }
2728