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