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