sfsave.c
来自「A GTK sound font editor. Sound font file」· C语言 代码 · 共 847 行 · 第 1/2 页
C
847 行
*size += (x += 8); CHUNKSIZE (x, fd); WRITECHUNK (PGEN_ID, zero_size, fd); if (!save_pgen (sf, &x, fd)) return (FAIL); *size += (x += 8); CHUNKSIZE (x, fd); WRITECHUNK (IHDR_ID, zero_size, fd); if (!save_ihdr (sf, &x, fd)) return (FAIL); *size += (x += 8); CHUNKSIZE (x, fd); WRITECHUNK (IBAG_ID, zero_size, fd); if (!save_ibag (sf, &x, fd)) return (FAIL); *size += (x += 8); CHUNKSIZE (x, fd); WRITECHUNK (IMOD_ID, zero_size, fd); if (!save_imod (sf, &x, fd)) return (FAIL); *size += (x += 8); CHUNKSIZE (x, fd); WRITECHUNK (IGEN_ID, zero_size, fd); if (!save_igen (sf, &x, fd)) return (FAIL); *size += (x += 8); CHUNKSIZE (x, fd); WRITECHUNK (SHDR_ID, zero_size, fd); if (!save_shdr (sf, &x, fd)) return (FAIL); *size += (x += 8); CHUNKSIZE (x, fd); return (OK);}/* zero non-used characters in a Preset, Instrument or Sample name string */static voidzero_namestr (gchar *name){ gint i = strlen (name); while (i < 21) name [i++] = '\0';}/* preset header writer */static gintsave_phdr (SFData * sf, guint32 * size, FILE * fd){ GSList *p; SFPreset *pr; guint16 ndx = 0; gchar eop[] = "EOP"; gint retval; *size = SFPHDRSIZE; /* for the terminal record */ p = sf->preset; while (p) { /* Traverse presets */ pr = (SFPreset *) (p->data); zero_namestr (pr->name); WRITESTR (&pr->name, fd); WRITEW (pr->prenum, fd); WRITEW (pr->bank, fd); WRITEW (ndx, fd); WRITED (pr->libr, fd); WRITED (pr->genre, fd); WRITED (pr->morph, fd); ndx += g_slist_length (pr->zone); *size += SFPHDRSIZE; p = g_slist_next (p); } if (!safe_fwrite (eop, 4, fd)) return (FAIL); WRITEZERO (20, fd); WRITEW (ndx, fd); WRITEZERO (12, fd); return (retval);}/* preset bag writer */static gintsave_pbag (SFData * sf, guint32 * size, FILE * fd){ GSList *p, *p2; SFZone *z; guint16 genndx = 0, modndx = 0; *size = SFBAGSIZE; /* for terminal record */ p = sf->preset; while (p) { /* loop through presets */ p2 = ((SFPreset *) (p->data))->zone; while (p2) { /* loop through zones */ WRITEW (genndx, fd); WRITEW (modndx, fd); z = (SFZone *) (p2->data); genndx += g_slist_length (z->gen); if (z->instsamp) genndx++; modndx += g_slist_length (z->mod); *size += SFBAGSIZE; p2 = g_slist_next (p2); } p = g_slist_next (p); } WRITEW (genndx, fd); /* terminal record */ WRITEW (modndx, fd); return (OK);}/* preset modulator writer */static gintsave_pmod (SFData * sf, guint32 * size, FILE * fd){ GSList *p, *p2, *p3; SFMod *m; *size = SFMODSIZE; /* for terminal record */ p = sf->preset; while (p) { p2 = ((SFPreset *) (p->data))->zone; while (p2) { /* traverse this preset's zones */ p3 = ((SFZone *) (p2->data))->mod; while (p3) { /* load zone's modulators */ m = (SFMod *) (p3->data); WRITEW (m->src, fd); WRITEW (m->dest, fd); WRITEW (m->amount, fd); WRITEW (m->amtsrc, fd); WRITEW (m->trans, fd); *size += SFMODSIZE; p3 = g_slist_next (p3); } p2 = g_slist_next (p2); } p = g_slist_next (p); } WRITEZERO (SFMODSIZE, fd); return (OK);}/* preset generator writer */static gintsave_pgen (SFData * sf, guint32 * size, FILE * fd){ GSList *p, *p2, *p3; SFZone *z; SFGen *g; guint32 dummy; *size = SFGENSIZE; /* for terminal record */ p = sf->preset; while (p) { /* traverse presets */ p2 = ((SFPreset *) (p->data))->zone; while (p2) { /* traverse this preset's zones */ p3 = ((SFZone *) (p2->data))->gen; while (p3) { /* traverse zone's generators */ g = (SFGen *) (p3->data); WRITEW (g->id, fd); if (g->id == Gen_KeyRange || g->id == Gen_VelRange) { WRITEB (g->amount.range.lo, fd); WRITEB (g->amount.range.hi, fd); } else WRITEW (g->amount.sword, fd); *size += SFGENSIZE; p3 = g_slist_next (p3); /* next generator */ } z = (SFZone *) (p2->data); if (z->instsamp) { (guint16) dummy = Gen_Instrument; WRITEW ((guint16) dummy, fd); (guint16) dummy = g_slist_position (sf->inst, z->instsamp); WRITEW ((guint16) dummy, fd); *size += SFGENSIZE; } p2 = g_slist_next (p2); } p = g_slist_next (p); } dummy = 0; WRITED (dummy, fd); /* terminal record */ return (OK);}/* instrument header writer */static gintsave_ihdr (SFData * sf, guint32 * size, FILE * fd){ GSList *p; SFInst *in; gchar eoi[] = "EOI"; guint16 ndx = 0; gint retval; *size = SFIHDRSIZE; /* for terminal record */ p = sf->inst; while (p) { /* Traverse instruments */ in = (SFInst *) (p->data); zero_namestr (in->name); WRITESTR (&in->name, fd); WRITEW (ndx, fd); ndx += g_slist_length (in->zone); *size += SFIHDRSIZE; p = g_slist_next (p); } if (!safe_fwrite (eoi, 4, fd)) return (FAIL); WRITEZERO (16, fd); WRITEW (ndx, fd); return (retval);}/* instrument bag writer */static gintsave_ibag (SFData * sf, guint32 * size, FILE * fd){ GSList *p, *p2; SFZone *z; guint16 genndx = 0, modndx = 0; *size = SFBAGSIZE; /* for terminal record */ p = sf->inst; while (p) { /* loop through instruments */ p2 = ((SFInst *) (p->data))->zone; while (p2) { /* loop through zones */ WRITEW (genndx, fd); WRITEW (modndx, fd); z = (SFZone *) (p2->data); genndx += g_slist_length (z->gen); if (z->instsamp) genndx++; modndx += g_slist_length (z->mod); *size += SFBAGSIZE; p2 = g_slist_next (p2); } p = g_slist_next (p); } WRITEW (genndx, fd); /* terminal record */ WRITEW (modndx, fd); return (OK);}/* instrument modulator writer */static gintsave_imod (SFData * sf, guint32 * size, FILE * fd){ GSList *p, *p2, *p3; SFMod *m; *size = SFMODSIZE; /* for terminal record */ p = sf->inst; while (p) { p2 = ((SFInst *) (p->data))->zone; while (p2) { /* traverse this instrument's zones */ p3 = ((SFZone *) (p2->data))->mod; while (p3) { /* load zone's modulators */ m = (SFMod *) (p3->data); WRITEW (m->src, fd); WRITEW (m->dest, fd); WRITEW (m->amount, fd); WRITEW (m->amtsrc, fd); WRITEW (m->trans, fd); *size += SFMODSIZE; p3 = g_slist_next (p3); } p2 = g_slist_next (p2); } p = g_slist_next (p); } WRITEZERO (SFMODSIZE, fd); return (OK);}/* instrument generator writer */static gintsave_igen (SFData * sf, guint32 * size, FILE * fd){ GSList *p, *p2, *p3; SFZone *z; SFGen *g; guint32 dummy; *size = SFGENSIZE; /* for terminal record */ p = sf->inst; while (p) { /* traverse instruments */ p2 = ((SFInst *) (p->data))->zone; while (p2) { /* traverse this instrument's zones */ p3 = ((SFZone *) (p2->data))->gen; while (p3) { /* traverse zone's generators */ g = (SFGen *) (p3->data); WRITEW (g->id, fd); if (g->id == Gen_KeyRange || g->id == Gen_VelRange) { WRITEB (g->amount.range.lo, fd); WRITEB (g->amount.range.hi, fd); } else WRITEW (g->amount.sword, fd); *size += SFGENSIZE; p3 = g_slist_next (p3); /* next generator */ } z = (SFZone *) (p2->data); if (z->instsamp) { (guint16) dummy = Gen_SampleId; WRITEW ((guint16) dummy, fd); (guint16) dummy = g_slist_position (sf->sample, z->instsamp); WRITEW ((guint16) dummy, fd); *size += SFGENSIZE; } p2 = g_slist_next (p2); } p = g_slist_next (p); } dummy = 0; WRITED (dummy, fd); /* terminal record */ return (OK);}/* sample header writer */static gintsave_shdr (SFData * sf, guint32 * size, FILE * fd){ GSList *p; SFSample *s; gchar eos[] = "EOS"; gint retval; guint16 dumzero = 0; guint32 dummy; /* WRITE macros must have variable */ *size = SFSHDRSIZE; /* terminal record */ p = sf->sample; while (p) { s = (SFSample *) (p->data); zero_namestr (s->name); WRITESTR (&s->name, fd); WRITED (s->datainfo->start, fd);/* sample end, loopstart and loopend are offsets, SHDR uses absolute values, so add start. Sample end adds an additonal 1 because SHDR end should point to first point after sample, whereas we have it point to last sample*/ dummy = s->end + s->datainfo->start + 1; WRITED (dummy, fd); dummy = s->loopstart + s->datainfo->start; WRITED (dummy, fd); dummy = s->loopend + s->datainfo->start; WRITED (dummy, fd); WRITED (s->samplerate, fd); WRITEB (s->origpitch, fd); WRITEB (s->pitchadj, fd); WRITEW (dumzero, fd); /* put 0 in sample link */ WRITEW (s->sampletype, fd); *size += SFSHDRSIZE; p = g_slist_next (p); } if (!safe_fwrite (eos, 4, fd)) return (FAIL); WRITEZERO (SFSHDRSIZE - 4, fd); return (retval);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?