sfload.c
字号:
z->gen = NULL; /* In case of failure, */ z->mod = NULL; /* sfont_close can clean up */ READW (genndx, fd); /* READW = possible read failure */ READW (modndx, fd); z->instsamp = NULL; if (pz) { /* if not first zone */ if (genndx < pgenndx) return (logit (LogFubar, _("Instrument generator indices not monotonic"))); if (modndx < pmodndx) return (logit (LogFubar, _("Instrument modulator indices not monotonic"))); i = genndx - pgenndx; while (i--) pz->gen = g_slist_prepend (pz->gen, NULL); i = modndx - pmodndx; while (i--) pz->mod = g_slist_prepend (pz->mod, NULL); } pz = z; /* update previous zone ptr */ pgenndx = genndx; pmodndx = modndx; p2 = g_slist_next (p2); } p = g_slist_next (p); } size -= SFBAGSIZE; if (size != 0) return (logit (LogFubar, _("Instrument chunk size mismatch"))); READW (genndx, fd); READW (modndx, fd); if (!pz) { /* in case that all are no zoners */ if (genndx > 0) logit (LogWarn, _("No instrument generators and terminal index not 0")); if (modndx > 0) logit (LogWarn, _("No instrument modulators and terminal index not 0")); return (OK); } if (genndx < pgenndx) return (logit (LogFubar, _("Instrument generator indices not monotonic"))); if (modndx < pmodndx) return (logit (LogFubar, _("Instrument modulator indices not monotonic"))); i = genndx - pgenndx; while (i--) pz->gen = g_slist_prepend (pz->gen, NULL); i = modndx - pmodndx; while (i--) pz->mod = g_slist_prepend (pz->mod, NULL); return (OK);}/* instrument modulator loader */static gintload_imod (gint32 size, SFData * sf, FILE * fd){ GSList *p, *p2, *p3; SFMod *m; p = sf->inst; while (p) { /* traverse through all inst */ p2 = ((SFInst *) (p->data))->zone; while (p2) { /* traverse this inst's zones */ p3 = ((SFZone *) (p2->data))->mod; while (p3) { /* load zone's modulators */ if ((size -= SFMODSIZE) < 0) return (logit (LogFubar, _("Instrument modulator chunk size mismatch"))); m = sfont_mod_alloc (); p3->data = m; READW (m->src, fd); READW (m->dest, fd); READW (m->amount, fd); READW (m->amtsrc, fd); READW (m->trans, fd); p3 = g_slist_next (p3); } p2 = g_slist_next (p2); } p = g_slist_next (p); } /* If there isn't even a terminal record Hmmm, the specs say there should be one, but.. */ if (size == 0) return (OK); size -= SFMODSIZE; if (size != 0) return (logit (LogFubar, _("Instrument modulator chunk size mismatch"))); FSKIP (SFMODSIZE, fd); /* terminal mod */ return (OK);}/* load instrument generators (see load_pgen for loading rules) */static gintload_igen (gint32 size, SFData * sf, FILE * fd){ GSList *p, *p2, *p3, *dup, **hz; SFZone *z; SFGen *g; SFGenAmount genval; guint16 genid; gint level, skip, drop, gzone, discarded; p = sf->inst; while (p) { /* traverse through all instruments */ gzone = FALSE; discarded = FALSE; p2 = ((SFInst *) (p->data))->zone; if (p2) hz = &p2; while (p2) { /* traverse this instrument's zones */ level = 0; z = (SFZone *) (p2->data); p3 = z->gen; while (p3) { /* load zone's generators */ dup = NULL; skip = FALSE; drop = FALSE; if ((size -= SFGENSIZE) < 0) return (logit (LogFubar, _("IGEN chunk size mismatch"))); READW (genid, fd); if (genid == Gen_KeyRange) { /* nothing precedes */ if (level == 0) { level = 1; READB (genval.range.lo, fd); READB (genval.range.hi, fd); } else skip = TRUE; } else if (genid == Gen_VelRange) { /* only KeyRange precedes */ if (level <= 1) { level = 2; READB (genval.range.lo, fd); READB (genval.range.hi, fd); } else skip = TRUE; } else if (genid == Gen_SampleId) { /* sample is last gen */ level = 3; READW (genval.uword, fd); GPOINTER_TO_INT (((SFZone *) (p2->data))->instsamp) = genval.uword + 1; break; /* break out of generator loop */ } else { level = 2; if (gen_valid (genid)) { /* gen valid? */ READW (genval.sword, fd); dup = gen_inlist (genid, z->gen); } else skip = TRUE; } if (!skip) { if (!dup) { /* if gen ! dup alloc new */ g = sfont_gen_alloc (); p3->data = g; g->id = genid; } else { g = (SFGen *) (dup->data); drop = TRUE; } g->amount = genval; } else { /* skip this generator */ discarded = TRUE; drop = TRUE; FSKIPW (fd); } if (!drop) p3 = g_slist_next (p3); /* next gen */ else SLADVREM (z->gen, p3); } /* generator loop */ if (level == 3) SLADVREM (z->gen, p3); /* zone has sample? */ else { /* its a global zone */ if (!gzone) { gzone = TRUE; /* if global zone is not 1st zone, relocate */ if (*hz != p2) { gpointer save = p2->data; logit (LogWarn, _("Instrument \"%s\": Global zone is not first zone"), ((SFPreset *) (p->data))->name); SLADVREM (*hz, p2); *hz = g_slist_prepend (*hz, save); continue; } } else { /* previous global zone exists, discard */ logit (LogWarn, _("Instrument \"%s\": Discarding invalid global zone"), ((SFInst *) (p->data))->name); sfont_remove_zone (sf, hz, (SFZone *) (p2->data)); } } while (p3) { /* Kill any zones following a sample */ discarded = TRUE; if ((size -= SFGENSIZE) < 0) return (logit (LogFubar, _("Instrument generator chunk size mismatch"))); FSKIP (SFGENSIZE, fd); SLADVREM (z->gen, p3); } p2 = g_slist_next (p2); /* next zone */ } if (discarded) logit (LogWarn, _("Instrument \"%s\": Some invalid generators were discarded"), ((SFInst *) (p->data))->name); p = g_slist_next (p); } /* for those non-terminal record cases, grr! */ if (size == 0) return (OK); size -= SFGENSIZE; if (size != 0) return (logit (LogFubar, _("IGEN chunk size mismatch"))); FSKIP (SFGENSIZE, fd); /* terminal gen */ return (OK);}/* sample header loader */static gintload_shdr (gint32 size, SFData * sf, FILE * fd){ guint32 i; SFSample *p; if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */ return (logit (LogFubar, _("Sample header has invalid size"))); size = size / SFSHDRSIZE - 1; if (size == 0) { /* at least one sample + term record? */ logit (LogWarn, _("File contains no samples")); FSKIP (SFSHDRSIZE, fd); return (OK); } /* load all sample headers */ for (i = 0; i < size; i++) { p = sfont_sample_alloc (); sf->sample = g_slist_append (sf->sample, p); p->datainfo = sam_datainfo_new (); /* create new sam data info struct */ p->datainfo->samfile = FALSE; /* sample is in sound font */ p->datainfo->sf = sf; p->datainfo->refcount++; /* update reference count */ READSTR (&p->name, fd); READD (p->datainfo->start, fd); READD (p->end, fd); /* - end, loopstart and loopend */ READD (p->loopstart, fd); /* - will be checked and turned into */ READD (p->loopend, fd); /* - offsets in fixup_sample() */ READD (p->samplerate, fd); READB (p->origpitch, fd); READB (p->pitchadj, fd); FSKIPW (fd); /* skip sample link */ READW (p->sampletype, fd); } FSKIP (SFSHDRSIZE, fd); /* skip terminal shdr */ return (OK);}/* "fixup" (inst # -> inst ptr) instrument references in preset list */static gintfixup_pgen (SFData * sf){ GSList *p, *p2, *p3; SFZone *z; gint i; p = sf->preset; while (p) { p2 = ((SFPreset *) (p->data))->zone; while (p2) { /* traverse this preset's zones */ z = (SFZone *) (p2->data); if ((i = GPOINTER_TO_INT (z->instsamp))) { /* load instrument # */ p3 = g_slist_nth (sf->inst, i - 1); if (!p3) return (logit (LogFubar, _("Preset %03d %03d: Invalid instrument reference"), ((SFPreset *) (p->data))->bank, ((SFPreset *) (p->data))->prenum)); z->instsamp = p3; } else z->instsamp = NULL; p2 = g_slist_next (p2); } p = g_slist_next (p); } return (OK);}/* "fixup" (sample # -> sample ptr) sample references in instrument list */static gintfixup_igen (SFData * sf){ GSList *p, *p2, *p3; SFZone *z; gint i; p = sf->inst; while (p) { p2 = ((SFInst *) (p->data))->zone; while (p2) { /* traverse instrument's zones */ z = (SFZone *) (p2->data); if ((i = GPOINTER_TO_INT (z->instsamp))) { /* load sample # */ p3 = g_slist_nth (sf->sample, i - 1); if (!p3) return (logit (LogFubar, _("Instrument \"%s\": Invalid sample reference"), ((SFInst *) (p->data))->name)); z->instsamp = p3; } p2 = g_slist_next (p2); } p = g_slist_next (p); } return (OK);}/* convert sample end, loopstart and loopend to offsets and check if valid */static gintfixup_sample (SFData * sf){ GSList *p; SFSample *sam; p = sf->sample; while (p) { sam = (SFSample *) (p->data); /* if sample is not a ROM sample and end is over the sample data chunk or sam start is greater than 4 less than the end (at least 4 samples) */ if ((!(sam->sampletype & SF_SAMPLETYPE_ROM) && sam->end > sdtachunk_size) || sam->datainfo->start > (sam->end - 4)) { logit (LogWarn, _("Sample '%s' start/end file positions are invalid," " disabling and will not be saved"), sam->name); /* disable sample by setting all sample markers to 0 */ sam->datainfo->start = sam->end = sam->loopstart = sam->loopend = 0; return (OK); } else if (sam->loopend > sam->end || sam->loopstart >= sam->loopend || sam->loopstart <= sam->datainfo->start) { /* loop is fowled?? (cluck cluck :) */ /* can pad loop by 8 samples and ensure at least 4 for loop (2*8+4) */ if ((sam->end - sam->datainfo->start) >= 20) { sam->loopstart = sam->datainfo->start + 8; sam->loopend = sam->end - 8; } else { /* loop is fowled, sample is tiny (can't pad 8 samples) */ sam->loopstart = sam->datainfo->start + 1; sam->loopend = sam->end - 1; } } /* convert sample end, loopstart, loopend to offsets from sam->start */ sam->end -= sam->datainfo->start + 1; /* marks last sample, contrary to SF spec. (wish I hadn't done this, will change again later) */ sam->loopstart -= sam->datainfo->start; sam->loopend -= sam->datainfo->start; sam->datainfo->size = sam->end + 1; /* update sam data info size */ p = g_slist_next (p); } return (OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -