sfont.c
来自「A GTK sound font editor. Sound font file」· C语言 代码 · 共 1,502 行 · 第 1/3 页
C
1,502 行
if ((dup->instsamp = zone->instsamp)) { if (mode == SFDUP_ARCHIVE) /* if archive, GSList * -> itemid */ dup->instsamp = GINT_TO_POINTER (*((SFItemID *)(dup->instsamp->data))); else if (mode == SFDUP_RESTORE) { /* if restore, itemid -> GSList * */ node = SFTREE_LOOKUP_ITEMID (GPOINTER_TO_INT (dup->instsamp)); if (node) dup->instsamp = (GSList *)(SFTREE_NODE_REF (node)->dptr); else dup->instsamp = NULL; } } p = zone->gen; while (p) { gen = (SFGen *) (p->data); dupgen = sfont_gen_alloc (); dupgen->id = gen->id; dupgen->amount.sword = gen->amount.sword; dup->gen = g_slist_append (dup->gen, dupgen); p = g_slist_next (p); } p = zone->mod; while (p) { mod = (SFMod *) (p->data); dupmod = sfont_mod_alloc (); dupmod->src = mod->src; dupmod->dest = mod->dest; dupmod->amount = mod->amount; dupmod->amtsrc = mod->amtsrc; dupmod->trans = mod->trans; dup->mod = g_slist_append (dup->mod, dupmod); p = g_slist_next (p); } return (dup);}SFZone *sfont_zone_alloc (void){ return (g_chunk_new0 (SFZone, chunk_zone));}voidsfont_zone_free (SFZone *zone){ g_mem_chunk_free (chunk_zone, zone);}/* ------------------------- *//* ---- SFMod functions ---- *//* ------------------------- */SFMod *sfont_mod_alloc (void){ return (g_chunk_new0 (SFMod, chunk_mod));}voidsfont_mod_free (SFMod * mod){ g_mem_chunk_free (chunk_mod, mod);}/* ------------------------- *//* ---- SFGen functions ---- *//* ------------------------- */SFGen *sfont_gen_alloc (void){ return (g_chunk_new0 (SFGen, chunk_gen));}voidsfont_gen_free (SFGen * gen){ g_mem_chunk_free (chunk_gen, gen);}/* Convert SF generator amount to user units */floatgen_sf2userval (guint16 gen, SFGenAmount amt, gboolean absval){ guint8 unit; unit = genparms[gen].unit; /* get the unit enum for this gen */ if (!unit) return (0.0); /* if no unit specified, return */ /* convert absolute or offset gen value? */ if (absval) return ((*genconv[unit].sf2user) (amt)); /* convert abs gen */ else return ((*genconv[unit].sf2ofs) (amt)); /* convert ofs gen */}/* gen_sf2userstr ------------------------------------------------------- * * Desc: Convert generator value from sound font units to user units * * Inputs: generator id, GenAmount, char *buf to store printable string * * Outputs: Floating user unit value, see char *buf in inputs * * ---------------------------------------------------------------------- */floatgen_sf2userstr (guint16 gen, SFGenAmount amt, gchar * buf, gboolean absval){ float val; guint8 unit; unit = genparms[gen].unit; /* get the unit type for this gen */ if (!unit) return (0.0); /* if no unit specified, return */ /* convert absolute or offset gen value? */ if (absval) val = (*genconv[unit].sf2user) (amt); /* convert abs gen */ else val = (*genconv[unit].sf2ofs) (amt); /* convert ofs gen */ sprintf (buf, "%.*f", (int) genconv[unit].digits, val); return (val);}gint16gen_userstr2sf (guint16 gen, gchar * val, gboolean absval, gboolean * err){ gchar *errptr = NULL; /* if error occurs during ascii conv */ float uval; /* user float value, after ascii to float conversion */ guint8 unit; gint sfval; gint ofsrange; /* used only for offset gens, range of value */ uval = strtod (val, &errptr); /* convert user string to float */ if (errptr == val) { /* conversion error occured? */ *err = TRUE; return (0); } *err = FALSE; /* no more chance of error */ unit = genparms[gen].unit; if (!unit) return (0); /* if not convertable, bad programmer, bad! */ /* calculate value in sound font units, and range check */ if (absval) { sfval = (*genconv[unit].user2sf) (uval); if (sfval < genparms[gen].min) sfval = genparms[gen].min; else if (sfval > genparms[gen].max) sfval = genparms[gen].max; } else { sfval = (*genconv[unit].ofs2sf) (uval); ofsrange = genparms[gen].max - genparms[gen].min; if (sfval < -ofsrange) sfval = -ofsrange; else if (sfval > ofsrange) sfval = ofsrange; } return ((gint16) sfval);}/* Set inst gen value (deletes if value is default, creates if no exist) */voidsfont_gen_set (SFData * sf, SFZone * zone, guint16 gen, SFGenAmount amt, gboolean preset){ GSList *p; SFGen *genp; gboolean defval = FALSE; /* Check if requested value is the default for this gen */ if (preset) { if ((gen == Gen_KeyRange || gen == Gen_VelRange) && amt.uword == DEFRANGE) defval = TRUE; else if (amt.uword == 0) defval = TRUE; } else { if (genparms[gen].def == amt.sword) defval = TRUE; } p = zone->gen; while (p) { /* loop through zone's generators */ genp = (SFGen *) (p->data); if (genp->id == gen) { /* Is this gen the requested one? */ if (defval) { /* gen found, if default val then remove */ g_mem_chunk_free (chunk_gen, genp); zone->gen = g_slist_remove (zone->gen, genp); } else genp->amount.sword = amt.sword; sf->up2date = FALSE; /* sfont has changed */ return; } p = g_slist_next (p); } if (defval) return; /* if gen not found and default val, return */ /* Generator not found, and amt isn't the default */ genp = g_chunk_new (SFGen, chunk_gen); genp->id = gen; genp->amount.sword = amt.sword; if (gen == Gen_KeyRange) { /* Keyranges must be first */ zone->gen = g_slist_prepend (zone->gen, genp); } else if (gen == Gen_VelRange) { /* Velranges preceded only by keyranges */ gint i = 0; if (zone->gen && ((SFGen *) (zone->gen->data))->id == Gen_KeyRange) i++; zone->gen = g_slist_insert (zone->gen, genp, i); } else { /* All other gens can just be appended */ zone->gen = g_slist_append (zone->gen, genp); } sf->up2date = FALSE; /* sfont has changed */}/* removes a generator from a zone, thereby falling back to its default val */voidsfont_gen_unset (SFData * sf, SFZone * zone, guint16 gen){ GSList *p; SFGen *genp; p = zone->gen; while (p) { genp = (SFGen *) (p->data); if (genp->id == gen) { g_mem_chunk_free (chunk_gen, genp); zone->gen = g_slist_remove (zone->gen, genp); sf->up2date = FALSE; return; } p = g_slist_next (p); }}/* retrieve a generator value */SFGenAmount *sfont_gen_get (SFZone * zone, guint16 gen){ GSList *p; SFGen *genp; p = zone->gen; while (p) { /* loop through zone's generators */ genp = (SFGen *) (p->data); if (genp->id == gen) /* Is this gen the requested one? */ return (&genp->amount); p = g_slist_next (p); } return (NULL);}/* init a generator array to default values */voidgen_initdef (SFGenAmount * garr){ gint i; for (i = 0; i <= SFGen_MaxValid; i++) { // for each generator item garr[i].uword = genparms[i].def; // init to default val }}/* init an offset generator array (presets) to ZERO values */voidgen_initofs (SFGenAmount * garr){ gint i; for (i = 0; i <= SFGen_MaxValid; i++) { garr[i].uword = 0; } garr[Gen_KeyRange].uword = DEFRANGE; garr[Gen_VelRange].uword = DEFRANGE; return;}/* Insert generator values from zone into generator array */voidgen_process_zone (SFZone * zone, SFGenAmount * garr){ GSList *p; SFGen *gen; p = zone->gen; // First generator while (p) { // while generators gen = (SFGen *) (p->data); garr[gen->id].uword = gen->amount.uword; // assign to array p = g_slist_next (p); }}/* Offset an array of absolute generators with offset generators */voidgen_offset_zone (SFGenAmount * abs, SFGenAmount * ofs){ gint i; gint32 temp; for (i = 0; i < Gen_KeyRange; i++) { temp = (gint32) (abs[i].sword) + (gint32) (ofs[i].sword); if (temp < (gint32) genparms[i].min) temp = genparms[i].min; else if (temp > (gint32) genparms[i].max) temp = genparms[i].max; abs[i].sword = (gint16) temp; } abs[Gen_KeyRange] = range_intersect (abs[Gen_KeyRange], ofs[Gen_KeyRange]); abs[Gen_VelRange] = range_intersect (abs[Gen_VelRange], ofs[Gen_VelRange]); for (i = Gen_VelRange + 1; i < SFGen_MaxValid; i++) { temp = (gint32) (abs[i].sword) + (gint32) (ofs[i].sword); if (temp < (gint32) genparms[i].min) temp = genparms[i].min; else if (temp > (gint32) genparms[i].max) temp = genparms[i].max; abs[i].sword = (gint16) temp; } return;}/* Find intersection of two generator ranges */SFGenAmountrange_intersect (SFGenAmount a, SFGenAmount b){ gint i = 0; guint8 p[2] = { 0, 0 }; SFGenAmount val; if ((a.range.lo >= b.range.lo) && (a.range.lo <= b.range.hi)) p[i++] = a.range.lo; if ((a.range.hi >= b.range.lo) && (a.range.hi <= b.range.hi)) p[i++] = a.range.hi; if ((b.range.lo > a.range.lo) && (b.range.lo < a.range.hi)) p[i++] = b.range.lo; if ((b.range.hi > a.range.lo) && (b.range.hi < a.range.hi)) p[i++] = b.range.hi; if (p[0] < p[1]) { val.range.lo = p[0]; val.range.hi = p[1]; } else { val.range.lo = p[1]; val.range.hi = p[0]; } return (val);}/* Find generator in gen list */GSList *gen_inlist (gint gen, GSList * genlist){ /* is generator in gen list? */ GSList *p; p = genlist; while (p) { if (p->data == NULL) return (NULL); if (gen == ((SFGen *) p->data)->id) break; p = g_slist_next (p); } return (p);}/* check validity of instrument generator */gintgen_valid (gint gen){ /* is generator id valid? */ gint i = 0; if (gen > SFGen_MaxValid) return (FALSE); while (badgen[i] && badgen[i] != gen) i++; return (badgen[i] == 0);}/* check validity of preset generator */gintgen_validp (gint gen){ /* is preset generator valid? */ gint i = 0; if (!gen_valid (gen)) return (FALSE); while (badpgen[i] && badpgen[i] != (guint16) gen) i++; return (badpgen[i] == 0);}/* conversion functions */gintfloat2int (float f){ return ((gint) f);}floatint2float (SFGenAmount val){ return ((float) val.sword);}ginthz2cents (float hz){ return ((gint) (log (hz / 8.176) / log (2) * 1200));}floatcents2hz (SFGenAmount cents){ return (8.176 * pow (2.0, ((double) cents.sword) / 1200.0));}gintdb2cb (float db){ return ((gint) (db * 10.0));}floatcb2db (SFGenAmount cb){ return ((float) cb.sword / 10.0);}gintsec2tcent (float sec){ return ((gint) (log (sec) / log (2) * 1200));}floattcent2sec (SFGenAmount tcent){ return (pow (2.0, ((double) tcent.sword) / 1200.0));}gintperc2tperc (float perc){ return ((gint) (perc * 10));}floattperc2perc (SFGenAmount tperc){ return (((float) tperc.sword) / 10);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?