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