wavetable.c

来自「A GTK sound font editor. Sound font file」· C语言 代码 · 共 1,081 行 · 第 1/2 页

C
1,081
字号
  if (!gt) gtree = g_tree_new (wtbl_ptr_compare_func);  else gtree = gt;  p = inst->zone;  while (p)			/* loop over instrument zones */    {      z = (SFZone *)(p->data);      if (z->instsamp)	{	  sam = (SFSample *)(((GSList *)(z->instsamp))->data);	  /* if not already counted */	  if (!g_tree_lookup (gtree, sam->datainfo))	    {	      /* add to binary tree */	      g_tree_insert (gtree, sam->datainfo, GINT_TO_POINTER (TRUE));	      rv = wtbl_samdata_mem_required (sam, sf, TRUE, locked);	      if (rv == -1) break; /* error occured? */	      size += rv;	    }	}      p = g_slist_next (p);    }  if (!gt) g_tree_destroy (gtree);  if (p == NULL) return (size);	/* all instrument zones processed? */  else return (-1);		/* ?: NO, error occured */}/* initialize active wavetable driver */gintwtbl_init (void){  if (wtbl_active) return (OK);	/* return if already open */  if (!wtbl_drivers[wtbl_driver].init)	/* this driver has init function? */    return (OK);  /* run the wavetable init routine */  if (!(*wtbl_drivers[wtbl_driver].init) ())    return (FAIL);  wtbl_active = TRUE;  return (OK);}/* close active wavetable driver */voidwtbl_close (void){  if (!wtbl_active) return;  if (wtbl_drivers[wtbl_driver].close)    (*wtbl_drivers[wtbl_driver].close) ();  wtbl_active = FALSE;  wtbl_onetime_clear_samples = TRUE;}voidwtbl_set_effect (gint chan, guint16 genid, SFGenAmount amt){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].effect)    return;  (*wtbl_drivers[wtbl_driver].effect) (chan, genid, amt);}/* load sound font into wavetable */gintwtbl_load_sfont (SFData *sf){  GSList *p;  SFPreset *pset;  gint mem_avail, mem_req;  if (!wtbl_active) return (OK);  /* clear all samples */  if (!wtbl_clear_samples ()) return (FAIL);  mem_avail = wtbl_mem_avail ();  mem_req = wtbl_sfont_mem_required (sf);  if (mem_avail == -1 || mem_req == -1) return (FAIL);  if (mem_req > mem_avail)    return (logit (LogFubar, _("Not enough wavetable memory")));  if (!wtbl_open_patch (TRUE))	/* open patch (with sample locking) */    return (FAIL);  /* load all the presets */  p = sf->preset;  while (p)    {      pset = (SFPreset *)(p->data);      if (!wtbl_load_preset_real (pset->bank, pset->prenum, pset, sf))	break;      p = g_slist_next (p);    }  wtbl_close_patch ();		/* close patch */  if (p != NULL)		/* ?: all presets loaded? */    return (FAIL);		/* ?: No, FAIL */  wtbl_update_cache_vars ();  wtbl_loaded_sfbank = sf->itemid; /* indicate that sound font is loaded */  return (OK);}/* load virtual bank into wavetable */gintwtbl_load_vbank (VBnkData *vbnk){  GList *psetmaps, *p;  VBnkPresetMap *pmap;  gint mem_avail, mem_req;  if (!wtbl_active) return (OK);  /* clear all samples */  if (!wtbl_clear_samples ()) return (FAIL);  mem_avail = wtbl_mem_avail ();  mem_req = wtbl_vbank_mem_required (vbnk);  if (mem_avail == -1 || mem_req == -1) return (FAIL);  if (mem_req > mem_avail)    return (logit (LogFubar, _("Not enough wavetable memory")));  if (!wtbl_open_patch (TRUE))	/* open patch (with sample locking) */    return (FAIL);  /* get preset maps for this virtual bank (SFPreset w/ bank:prenum to map 2) */  psetmaps = vbank_get_preset_maps (vbnk);  p = psetmaps;  while (p)			/* loop over preset maps */    {      pmap = (VBnkPresetMap *)(p->data);      /* load preset */      if (!wtbl_load_preset_real (pmap->bank, pmap->psetnum, pmap->preset,				  pmap->sf))	break;      p = g_list_next (p);    }  g_list_foreach (psetmaps, (GFunc)g_free, NULL);  g_list_free (psetmaps);  wtbl_close_patch ();		/* close patch */  if (p != NULL)		/* ?: all presets loaded? */    return (FAIL);		/* ?: No, FAIL */  wtbl_update_cache_vars ();  wtbl_loaded_sfbank = vbnk->itemid; /* indicate new loaded vbank */  return (OK);}/* reloads cache variables, called after sfont/vbank load */static gintwtbl_update_cache_vars (void){  gint mem_avail;  /* fetch amount of memory that is still available (cache memory) */  mem_avail = wtbl_mem_avail ();  if (mem_avail == -1)    return (FAIL);  wtbl_cache_mem_avail = mem_avail;  return (OK);}static gintwtbl_clear_cache_if_needed (gint memreq){  gint mem_avail;  if ((mem_avail = wtbl_mem_avail ()) == -1)    return (FAIL);  /* initialize wtbl_cache_mem_avail if it hasn't already been */  if (wtbl_cache_mem_avail == -1)    wtbl_cache_mem_avail = mem_avail;  /* if there isn't enough memory available */  if (memreq > mem_avail)    {      /* if required memory exceeds available cache memory, FAIL */      if (memreq > wtbl_cache_mem_avail)	return (logit (LogFubar, _("Not enough wavetable memory")));      wtbl_clear_unlocked_samples ();	/* clear the cache */    }  return (OK);}gintwtbl_load_temp_preset (SFPreset *pset, SFData *sf){  gint mem_req;  gint rv;  if (!wtbl_active) return (OK);  /* calculate wavetable memory required to load preset */  if ((mem_req = wtbl_preset_mem_required (pset, sf, FALSE, NULL)) == -1)    return (FAIL);  /* check if theres enough wavetable memory and clear cache if necessary */  if (!wtbl_clear_cache_if_needed (mem_req))    return (FAIL);  if (!wtbl_open_patch (FALSE))	/* open patch (without sample locking) */    return (FAIL);  rv =    wtbl_load_preset_real (smurfcfg_get_int (SMURFCFG_TEMP_AUDIBLE_BANK),			   smurfcfg_get_int (SMURFCFG_TEMP_AUDIBLE_PRESET),			   pset, sf);  wtbl_close_patch ();  if (rv)			/* update temp audible vars */    {      wtbl_temp_audible = pset->itemid;      wtbl_temp_audible_changed = FALSE;    }  return (rv);}/* the real preset loading routine (without mem checks and open/close patch) */static gintwtbl_load_preset_real (gint bank, gint prenum, SFPreset *pset, SFData *sf){  enum { PG, PL, IG, IL };	/* preset global, preset */  GSList *p, *p2;  SFInst *inst;			/* Insrument ptr */  SFSample *sam;		/* Sample ptr */  SFGenAmount *garrs[4];	/* Generator arrays */  gboolean replace = TRUE;  /* call wtbl_load_patch_info once with replace */  gint retval = FAIL;  /* return if no zones */  if (!(p = pset->zone))    return (OK);		/* No zones? */  garrs[0] = g_malloc (SFGen_ArraySize * 4);  garrs[1] = garrs[0] + SFGen_Count;	/* ptr to second gen array */  garrs[2] = garrs[1] + SFGen_Count;	/* ptr to third gen array */  garrs[3] = garrs[2] + SFGen_Count;	/* ptr to fourth gen array */  gen_initofs (garrs[PG]);	/* init global preset array to ZERO vals */  if (!((SFZone *) (p->data))->instsamp)  /* global zone? */    {  /* process global zone */      gen_process_zone ((SFZone *) (p->data), garrs[PG]);      if (!(p = g_slist_next (p)))	{			/* Only global zone?, exit peacefully */	  g_free (*garrs);	  return (OK);	}    }  while (p)    {				/* loop through preset zones */      memcpy (garrs[PL], garrs[PG], SFGen_ArraySize);  /* copy global gens */      gen_process_zone ((SFZone *) (p->data), garrs[PL]);      inst = (SFInst *) (((SFZone *) (p->data))->instsamp->data);      p2 = inst->zone;		/* ptr to first inst zone */      gen_initdef (garrs[IG]);	/* init inst global gen array */      if (p2 && !((SFZone *) (p2->data))->instsamp)	{			/* Global zone? */	  gen_process_zone ((SFZone *) (p2->data), garrs[IG]);	  p2 = g_slist_next (p2);	}      while (p2)	{			/* loop through instrument zones */	  memcpy (garrs[IL], garrs[IG], SFGen_ArraySize);	  gen_process_zone ((SFZone *) (p2->data), garrs[IL]);	  gen_offset_zone (garrs[IL], garrs[PL]);	/* apply offset gens */	  sam = (SFSample *) (((SFZone *) (p2->data))->instsamp->data);	  if (!wtbl_load_sample (sam, sf))	    goto ret;	  if (!wtbl_load_patch_info (bank, prenum, garrs[IL], sam, sf, replace))	    goto ret;	  replace = FALSE;	  p2 = g_slist_next (p2);	/* next instrument zone */	}      p = g_slist_next (p);    }  retval = OK; ret:  g_free (*garrs);  return (retval);}gintwtbl_load_temp_inst (SFInst *inst, SFData *sf){  gint mem_req;  GSList *p;  SFSample *sam;		/* Sample ptr */  SFGenAmount *gzarr;		/* stores global zone gens (if any) */  SFGenAmount *zarr;		/* current zone generators */  gboolean replace = TRUE;  /* call wtbl_load_patch_info once with replace */  gint retval = FAIL;  if (!wtbl_active) return (OK);  p = inst->zone;		/* p = ptr to head instrument zone */  gzarr = g_malloc (SFGen_ArraySize);  /* malloc global gen arr */  gen_initdef (gzarr);		/* initialize array to defaults */  if (p && !((SFZone *) (p->data))->instsamp)    {				/* global zone? */      gen_process_zone ((SFZone *) (p->data), gzarr);      p = g_slist_next (p);    }  if (!p)    {				/* no zones, exit peacefully */      g_free (gzarr);      return (OK);    }  if ((mem_req = wtbl_inst_mem_required (inst, sf, FALSE, NULL)) == -1      || !wtbl_clear_cache_if_needed (mem_req))    {      g_free (gzarr);      return (FAIL);    }  if (!wtbl_open_patch (FALSE))	/* open patch without sample locking */    {      g_free (gzarr);      return (FAIL);    }  zarr = g_malloc (SFGen_ArraySize);  while (p)    {				/* loop through zones */      memcpy (zarr, gzarr, SFGen_ArraySize); /* copy global gen vals */      gen_process_zone ((SFZone *) (p->data), zarr);  /* process current zone */      sam = (SFSample *) (((SFZone *) (p->data))->instsamp->data);      if (!wtbl_load_sample (sam, sf))	goto ret;      if (!wtbl_load_patch_info (smurfcfg_get_int (SMURFCFG_TEMP_AUDIBLE_BANK),				 smurfcfg_get_int(SMURFCFG_TEMP_AUDIBLE_PRESET),				 zarr, sam, sf, replace))	goto ret;      replace = FALSE;      p = g_slist_next (p);	/* next instrument zone */    }  retval = OK;  wtbl_temp_audible = inst->itemid;  wtbl_temp_audible_changed = FALSE; ret:  wtbl_close_patch ();  g_free (gzarr);  g_free (zarr);  return (retval);}gintwtbl_load_temp_sam_as_inst (SFSample *sam, SFData *sf){  gint mem_req;  SFGenAmount *garr;		/* current zone generators */  gint retval = FAIL;  if (!wtbl_active) return (OK);  /* check memory required and clear temporary sample cache if necessary */  if ((mem_req = wtbl_samdata_mem_required (sam, sf, TRUE, FALSE)) == -1      || !wtbl_clear_cache_if_needed (mem_req))    return (FAIL);  if (!wtbl_open_patch (FALSE))	/* open patch without sample locking */    return (FAIL);  garr = g_malloc (SFGen_ArraySize);  /* malloc global gen arr */  gen_initdef (garr);		/* initialize array to defaults */  /* Turn looping on if wtbl_loop_sam_as_inst is active */  if (wtbl_loop_sam_as_inst)    garr[Gen_SampleModes].uword = 0x0001;  if (!wtbl_load_sample (sam, sf))    goto ret;  if (!wtbl_load_patch_info (smurfcfg_get_int (SMURFCFG_TEMP_AUDIBLE_BANK),			     smurfcfg_get_int (SMURFCFG_TEMP_AUDIBLE_PRESET),			     garr, sam, sf, TRUE))    goto ret;  retval = OK;  wtbl_temp_audible = sam->itemid;  wtbl_temp_audible_changed = FALSE; ret:  wtbl_close_patch ();  g_free (garr);  return (retval);}gintwtbl_open_patch (gboolean samplelocking){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].open_patch)    return (OK);  /* clear samples with first patch open (or if no sample caching) */  if (wtbl_onetime_clear_samples || !wtbl_cache_samples)    {      wtbl_onetime_clear_samples = FALSE;      wtbl_clear_samples ();    }  return ((*wtbl_drivers[wtbl_driver].open_patch) (samplelocking));}gintwtbl_close_patch (void){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].close_patch)    return (OK);  return ((*wtbl_drivers[wtbl_driver].close_patch) ());}gintwtbl_load_sample (SFSample *sam, SFData *sf){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].load_sample)    return (OK);  return ((*wtbl_drivers[wtbl_driver].load_sample) (sam, sf));}gintwtbl_load_patch_info (gint bank, gint prenum, SFGenAmount *gens,		      SFSample *sam, SFData *sf, gboolean replace){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].load_patch_info)    return (OK);  return ((*wtbl_drivers[wtbl_driver].load_patch_info) (bank, prenum, gens,							sam, sf, replace));}gintwtbl_clear_samples (void){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].clear_samples)    return (OK);  wtbl_loaded_sfbank = SFITEMID_NONE; /* no more loaded SF/vbank (if any) */  wtbl_silence_temp_audible ();	/* silence temporary audible (if any) */  wtbl_temp_audible_changed = FALSE;  return ((*wtbl_drivers[wtbl_driver].clear_samples) ());}gintwtbl_clear_unlocked_samples (void){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].clear_unlocked_samples)    return (OK);  return ((*wtbl_drivers[wtbl_driver].clear_unlocked_samples) ());}voidwtbl_clear_sample_patch_id (SFSample *sam, gboolean locked){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].clear_sample_patch_id)    return;  (*wtbl_drivers[wtbl_driver].clear_sample_patch_id) (sam, locked);}gintwtbl_mem_avail (void){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].mem_avail)    return (-1);  return ((*wtbl_drivers[wtbl_driver].mem_avail) ());}gintwtbl_samdata_mem_required (SFSample *sam, SFData *sf, gboolean usecache,			   gboolean locked){  if (!wtbl_active || !wtbl_drivers[wtbl_driver].samdata_mem_required)    return (-1);  return ((*wtbl_drivers[wtbl_driver].samdata_mem_required) (sam, sf,							     usecache, locked));}

⌨️ 快捷键说明

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