欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

sfload.c

A GTK sound font editor. Sound font files are used to synthesize instruments from audio samples for
C
第 1 页 / 共 3 页
字号:
static gintload_phdr (gint32 size, SFData * sf, FILE * fd){  gint i, i2;  SFPreset *p, *pr = NULL;	/* ptr to current & previous preset */  guint16 zndx, pzndx;  if (size % SFPHDRSIZE || size == 0)    return (logit (LogFubar, _("Preset header chunk size is invalid")));  i = size / SFPHDRSIZE - 1;  if (i == 0)    {				/* at least one preset + term record */      logit (LogWarn, _("File contains no presets"));      FSKIP (SFPHDRSIZE, fd);      return (OK);    }  for (; i > 0; i--)    {				/* load all preset headers */      p = sfont_preset_alloc ();      sf->preset = g_slist_append (sf->preset, p);      READSTR (&p->name, fd);      READW (p->prenum, fd);      READW (p->bank, fd);      READW (zndx, fd);      READD (p->libr, fd);      READD (p->genre, fd);      READD (p->morph, fd);      if (pr)	{			/* not first preset? */	  if (zndx < pzndx)	    return (logit (LogFubar, _("Preset header indices not monotonic")));	  i2 = zndx - pzndx;	  while (i2--)	    {	      pr->zone = g_slist_prepend (pr->zone, NULL);	    }	}      else if (zndx > 0)	/* 1st preset, warn if ofs >0 */	logit (LogWarn, _("%d preset zones not referenced, discarding"), zndx);      pr = p;			/* update preset ptr */      pzndx = zndx;    }  FSKIP (24, fd);  READW (zndx, fd);		/* Read terminal generator index */  FSKIP (12, fd);  if (zndx < pzndx)    return (logit (LogFubar, _("Preset header indices not monotonic")));  i2 = zndx - pzndx;  while (i2--)    {      pr->zone = g_slist_prepend (pr->zone, NULL);    }  return (OK);}/* preset bag loader */static gintload_pbag (gint32 size, SFData * sf, FILE * fd){  GSList *p, *p2;  SFZone *z, *pz = NULL;  guint16 genndx, modndx;  guint16 pgenndx, pmodndx;  guint16 i;  if (size % SFBAGSIZE || size == 0)	/* size is multiple of SFBAGSIZE? */    return (logit (LogFubar, _("Preset bag chunk size is invalid")));  p = sf->preset;  while (p)    {				/* traverse through presets */      p2 = ((SFPreset *) (p->data))->zone;      while (p2)	{			/* traverse preset's zones */	  if ((size -= SFBAGSIZE) < 0)	    return (logit (LogFubar, _("Preset bag chunk size mismatch")));	  z = sfont_zone_alloc ();	  p2->data = z;	  z->gen = NULL;	/* Init gen and mod before possible failure, */	  z->mod = NULL;	/* to ensure proper cleanup (sfont_close) */	  READW (genndx, fd);	/* possible read failure ^ */	  READW (modndx, fd);	  z->instsamp = NULL;	  if (pz)	    {			/* if not first zone */	      if (genndx < pgenndx)		return (logit (LogFubar,		    _("Preset bag generator indices not monotonic")));	      if (modndx < pmodndx)		return (logit (LogFubar,		    _("Preset bag 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;	/* update previous zone gen index */	  pmodndx = modndx;	/* update previous zone mod index */	  p2 = g_slist_next (p2);	}      p = g_slist_next (p);    }  size -= SFBAGSIZE;  if (size != 0)    return (logit (LogFubar, _("Preset bag chunk size mismatch")));  READW (genndx, fd);  READW (modndx, fd);  if (!pz)    {      if (genndx > 0)	logit (LogWarn, _("No preset generators and terminal index not 0"));      if (modndx > 0)	logit (LogWarn, _("No preset modulators and terminal index not 0"));      return (OK);    }  if (genndx < pgenndx)    return (logit (LogFubar, _("Preset bag generator indices not monotonic")));  if (modndx < pmodndx)    return (logit (LogFubar, _("Preset bag 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);}/* preset modulator loader */static gintload_pmod (gint32 size, SFData * sf, FILE * fd){  GSList *p, *p2, *p3;  SFMod *m;  p = sf->preset;  while (p)    {				/* traverse through all presets */      p2 = ((SFPreset *) (p->data))->zone;      while (p2)	{			/* traverse this preset's zones */	  p3 = ((SFZone *) (p2->data))->mod;	  while (p3)	    {			/* load zone's modulators */	      if ((size -= SFMODSIZE) < 0)		return (logit (LogFubar,		    _("Preset 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, _("Preset modulator chunk size mismatch")));  FSKIP (SFMODSIZE, fd);	/* terminal mod */  return (OK);}/* ------------------------------------------------------------------- * preset generator loader * generator (per preset) loading rules: * Zones with no generators or modulators shall be annihilated * Global zone must be 1st zone, discard additional ones (instrumentless zones) * * generator (per zone) loading rules (in order of decreasing precedence): * KeyRange is 1st in list (if exists), else discard * if a VelRange exists only preceded by a KeyRange, else discard * if a generator follows an instrument discard it * if a duplicate generator exists replace previous one * ------------------------------------------------------------------- */static gintload_pgen (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->preset;  while (p)    {				/* traverse through all presets */      gzone = FALSE;      discarded = FALSE;      p2 = ((SFPreset *) (p->data))->zone;      if (p2)	hz = &p2;      while (p2)	{			/* traverse preset'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,		    _("Preset generator 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_Instrument)		{		/* inst 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_validp (genid))		    {		/* generator 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);	/* ptr to orig gen */		      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);	/* drop place holder */	    }			/* generator loop */	  if (level == 3)	    SLADVREM (z->gen, p3);	/* zone has inst? */	  else	    {			/* congratulations its a global zone */	      if (!gzone)		{		/* Prior global zones? */		  gzone = TRUE;		  /* if global zone is not 1st zone, relocate */		  if (*hz != p2)		    {		      gpointer save = p2->data;		      logit (LogWarn,			_("Preset \"%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,		    _("Preset \"%s\": Discarding invalid global zone"),		    ((SFPreset *) (p->data))->name);		  sfont_remove_zone (sf, hz, (SFZone *) (p2->data));		}	    }	  while (p3)	    {			/* Kill any zones following an instrument */	      discarded = TRUE;	      if ((size -= SFGENSIZE) < 0)		return (logit (LogFubar,		    _("Preset generator chunk size mismatch")));	      FSKIP (SFGENSIZE, fd);	      SLADVREM (z->gen, p3);	    }	  p2 = g_slist_next (p2);	/* next zone */	}      if (discarded)	logit (LogWarn,	  _("Preset \"%s\": Some invalid generators were discarded"),	  ((SFPreset *) (p->data))->name);      p = g_slist_next (p);    }  /* in case there isn't a terminal record */  if (size == 0)    return (OK);  size -= SFGENSIZE;  if (size != 0)    return (logit (LogFubar, _("Preset generator chunk size mismatch")));  FSKIP (SFGENSIZE, fd);	/* terminal gen */  return (OK);}/* instrument header loader */static gintload_ihdr (gint32 size, SFData * sf, FILE * fd){  gint i, i2;  SFInst *p, *pr = NULL;	/* ptr to current & previous instrument */  guint16 zndx, pzndx;  if (size % SFIHDRSIZE || size == 0)	/* chunk size is valid? */    return (logit (LogFubar, _("Instrument header has invalid size")));  size = size / SFIHDRSIZE - 1;  if (size == 0)    {				/* at least one preset + term record */      logit (LogWarn, _("File contains no instruments"));      FSKIP (SFIHDRSIZE, fd);      return (OK);    }  for (i = 0; i < size; i++)    {				/* load all instrument headers */      p = sfont_inst_alloc ();      sf->inst = g_slist_append (sf->inst, p);      READSTR (&p->name, fd);      READW (zndx, fd);      if (pr)	{			/* not first instrument? */	  if (zndx < pzndx)	    return (logit (LogFubar,		_("Instrument header indices not monotonic")));	  i2 = zndx - pzndx;	  while (i2--)	    pr->zone = g_slist_prepend (pr->zone, NULL);	}      else if (zndx > 0)	/* 1st inst, warn if ofs >0 */	logit (LogWarn, _("%d instrument zones not referenced, discarding"),	  zndx);      pzndx = zndx;      pr = p;			/* update instrument ptr */    }  FSKIP (20, fd);  READW (zndx, fd);  if (zndx < pzndx)    return (logit (LogFubar, _("Instrument header indices not monotonic")));  i2 = zndx - pzndx;  while (i2--)    pr->zone = g_slist_prepend (pr->zone, NULL);  return (OK);}/* instrument bag loader */static gintload_ibag (gint32 size, SFData * sf, FILE * fd){  GSList *p, *p2;  SFZone *z, *pz = NULL;  guint16 genndx, modndx, pgenndx, pmodndx;  gint i;  if (size % SFBAGSIZE || size == 0)	/* size is multiple of SFBAGSIZE? */    return (logit (LogFubar, _("Instrument bag chunk size is invalid")));  p = sf->inst;  while (p)    {				/* traverse through inst */      p2 = ((SFInst *) (p->data))->zone;      while (p2)	{			/* load this inst's zones */	  if ((size -= SFBAGSIZE) < 0)	    return (logit (LogFubar, _("Instrument bag chunk size mismatch")));	  z = sfont_zone_alloc ();	  p2->data = z;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -