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 + -
显示快捷键?