sfont.c
来自「A GTK sound font editor. Sound font file」· C语言 代码 · 共 1,502 行 · 第 1/3 页
C
1,502 行
sf->up2date = FALSE; return (zone);}/* add an already existing zone to a preset */gintsfont_add_preset_zone (SFData * sf, SFPreset * pset, SFZone * zone){ /* refuse to link in a global zone if one already exists */ if (!zone->instsamp && pset->zone && !((SFZone *) (pset->zone->data))->instsamp) return (FAIL); if (zone->instsamp) pset->zone = g_slist_append (pset->zone, zone); else /* global zone should be first zone */ pset->zone = g_slist_prepend (pset->zone, zone); sf->up2date = FALSE; return (OK);}/* create a new zone for an instrument */SFZone *sfont_new_inst_zone (SFData * sf, SFInst * inst, GSList * sam){ SFZone *zone; /* request to create global zone? Does one already exist? */ if (!sam && inst->zone && !((SFZone *) (inst->zone->data))->instsamp) return (NULL); zone = sfont_zone_alloc (); zone->instsamp = sam; if (sam) inst->zone = g_slist_append (inst->zone, zone); else /* global zone should be first zone */ inst->zone = g_slist_prepend (inst->zone, zone); sf->up2date = FALSE; return (zone);}/* add an already existing zone to an instrument */gintsfont_add_inst_zone (SFData * sf, SFInst * inst, SFZone * zone){ /* refuse to link in a global zone if one already exists */ if (!zone->instsamp && inst->zone && !((SFZone *) (inst->zone->data))->instsamp) return (FAIL); if (zone->instsamp) inst->zone = g_slist_append (inst->zone, zone); else /* global zone should be first zone */ inst->zone = g_slist_prepend (inst->zone, zone); sf->up2date = FALSE; return (OK);}/* remove zone from zone list */voidsfont_remove_zone (SFData * sf, GSList ** zlist, SFZone * zone){ *zlist = g_slist_remove (*zlist, (gpointer) zone); sfont_zone_destroy (zone); sf->up2date = FALSE;}/* Find first unused preset bank preset# in the melodic or percussion branch */voidsfont_find_free_preset (SFData *sf, gint *bank, gint *prenum, gboolean melodic){ SFPreset *pset; GSList *p; gint b, n; /* Stores current bank and preset number */ if (melodic) b = 0; else b = 128; n = 0; p = sf->preset; while (p) { pset = (SFPreset *)(p->data); if (pset->bank > b || (pset->bank == b && pset->prenum > n)) break; if (melodic || pset->bank == 128) { if (++n > 127) { n = 0; b++; } } p = g_slist_next (p); } *bank = b; *prenum = n;}/* find preset by name or bank/preset #, match name if !NULL and match bank/prenum if bank <= 128, match name || bank/prenum if both specified, excl specifies a preset to exclude from the search or NULL */GSList *sfont_find_preset (SFData * sf, gchar * name, guint bank, guint prenum, SFPreset * excl){ GSList *p; SFPreset *pset; p = sf->preset; while (p) { pset = (SFPreset *) (p->data); if (pset != excl /* if excl is NULL it will never == pset */ && ((pset->bank <= 128 && pset->bank == bank && pset->prenum == prenum) || (name && strcmp (pset->name, name) == 0))) return (p); p = g_slist_next (p); } return (NULL);}/* find instrument by name, excl is an instrument to exclude from find or NULL */GSList *sfont_find_inst (SFData * sf, gchar * name, SFInst * excl){ GSList *p; SFInst *inst; p = sf->inst; while (p) { inst = (SFInst *) (p->data); if (inst != excl && strcmp (inst->name, name) == 0) return (p); p = g_slist_next (p); } return (NULL);}/* find sample by name */GSList *sfont_find_sample (SFData * sf, gchar * name, SFSample * excl){ GSList *p; SFSample *sam; p = sf->sample; while (p) { sam = (SFSample *) (p->data); if (sam != excl && strcmp (sam->name, name) == 0) return (p); p = g_slist_next (p); } return (NULL);}/* set a sound font file name */voidsfont_set_fname (SFData * sf, gchar * fname){ gchar *temp; temp = g_strdup (fname); /* just in case fname == sf->fname */ if (sf->fname) g_free (sf->fname); sf->fname = temp;}/* Get an info string by id */gchar *sfont_get_info (SFData * sf, guint8 id){ GSList *p; p = sf->info; while (p) { if (*(guint8 *) (p->data) == id) return ((gchar *) ((guint8 *) (p->data) + 1)); p = g_slist_next (p); } return ("");}/* Set an info string by id */voidsfont_set_info (SFData * sf, guint8 id, gchar * str){ GSList *p; gchar *newstr; guint length; p = sf->info; while (p) { if (*(guint8 *) (p->data) == id) break; p = g_slist_next (p); } /* make sure length of info string is even */ length = strlen (str); length++; /* 1 more for terminator */ newstr = g_malloc (length + length % 2 + 1); newstr[0] = id; strcpy (&newstr[1], str); if (length % 2) newstr[length + 1] = '\0'; /* even terminator = '0' */ if (p) { g_free (p->data); p->data = newstr; } else sf->info = g_slist_append (sf->info, newstr); sf->up2date = FALSE;}/* Set namestr */voidsfont_set_namestr (SFData * sf, gchar * namestr, gchar * name){ sfont_set_namestr_nosf (namestr, name); sf->up2date = FALSE;}/* set a namestr, without updating sound font up2date variable */voidsfont_set_namestr_nosf (gchar * namestr, gchar * name){ if (strlen (name) > 20) { strncpy (namestr, name, 20); namestr[20] = '\0'; } else strcpy (namestr, name);}/* ---------------------------- *//* ---- SFPreset functions ---- *//* ---------------------------- *//* duplicate a preset and its zones, see sfont_zone_dup for details on mode */SFPreset *sfont_preset_dup (SFPreset * pset, SFDupEnum mode){ SFPreset *dup; SFZone *dupz; GSList *p; dup = sfont_preset_alloc (); /* allocate a new preset */ strcpy (dup->name, pset->name); dup->prenum = pset->prenum; dup->bank = pset->bank; dup->libr = pset->libr; dup->genre = pset->genre; dup->morph = pset->morph; /* if not SFDUP_NORMAL mode then duplicate itemid */ if (mode != SFDUP_NORMAL) dup->itemid = pset->itemid; p = pset->zone; while (p) { /* loop over pset zones and copy them */ /* duplicate the zone (with same mode) */ dupz = sfont_zone_dup ((SFZone *)(p->data), mode); dup->zone = g_slist_append (dup->zone, dupz); p = g_slist_next (p); } return (dup);}/* destroy a preset and its zones */voidsfont_preset_destroy (SFPreset * pset){ GSList *p; p = pset->zone; while (p) { /* loop over preset's zones */ sfont_zone_destroy (p->data); p = g_slist_next (p); } g_slist_free (pset->zone); /* free preset's zone list */ sfont_preset_free (pset);}/* allocate a preset structure and initialize it to dead state */SFPreset *sfont_preset_alloc (void){ return (g_chunk_new0 (SFPreset, chunk_preset));}/* free a preset structure */voidsfont_preset_free (SFPreset *preset){ g_mem_chunk_free (chunk_preset, preset); /* free preset chunk */}/* -------------------------- *//* ---- SFInst functions ---- *//* -------------------------- *//* duplicate instrument and its zones, see sfont_zone_dup for info on mode */SFInst *sfont_inst_dup (SFInst * inst, SFDupEnum mode){ SFInst *dup; SFZone *dupz; GSList *p; dup = sfont_inst_alloc (); /* allocate a new instrument */ strcpy (dup->name, inst->name); /* if not SFDUP_NORMAL mode then duplicate itemid */ if (mode != SFDUP_NORMAL) dup->itemid = inst->itemid; p = inst->zone; while (p) { /* loop over inst zones and copy them */ /* duplicate the zone (with same mode) */ dupz = sfont_zone_dup ((SFZone *)(p->data), mode); dup->zone = g_slist_append (dup->zone, dupz); p = g_slist_next (p); } return (dup);}/* destroy an instrument and its zones */voidsfont_inst_destroy (SFInst * inst){ GSList *p; p = inst->zone; while (p) { /* loop over instrument's zones */ sfont_zone_destroy (p->data); p = g_slist_next (p); } g_slist_free (inst->zone); /* free instrument's zone list */ sfont_inst_free (inst);}/* allocate and initialize an SFInst structure */SFInst *sfont_inst_alloc (void){ return (g_chunk_new0 (SFInst, chunk_inst));}/* free an SFInst structure */voidsfont_inst_free (SFInst *inst){ g_mem_chunk_free (chunk_inst, inst); /* free inst chunk */}/* ---------------------------- *//* ---- SFSample functions ---- *//* ---------------------------- *//* duplicate a SFSample structure, if mode != SFDUP_NORMAL then copy itemid otherwise clear it, same SFSamDataInfo structure is referenced and refcount/dorefcount is incremented depending on "refcount" == TRUE/FALSE */SFSample *sfont_sample_dup (SFSample * sam, SFDupEnum mode, gboolean refcount){ SFSample *dup; dup = sfont_sample_alloc (); memcpy (dup, sam, sizeof (SFSample)); /* if normal duplicate mode then clear itemid */ if (mode == SFDUP_NORMAL) dup->itemid = 0; if (refcount) dup->datainfo->refcount++; else dup->datainfo->dorefcount++; return (dup);}/* destroy a sample and decrement refcount/dorefcount of the SamDataInfo structure, depending on the value of "refcount" (TRUE/FALSE) */voidsfont_sample_destroy (SFSample *sam, gboolean refcount){ if (refcount) sam->datainfo->refcount--; else sam->datainfo->dorefcount--; sfont_sample_free (sam);}/* allocate and initialize a sample structure to dead state */SFSample *sfont_sample_alloc (void){ return (g_chunk_new0 (SFSample, chunk_sample));}/* free a sample structure */voidsfont_sample_free (SFSample *sam){ g_mem_chunk_free (chunk_sample, sam); /* free sample chunk */}/* allocate a SFSamDataInfo structure */SFSamDataInfo *sfont_samdatainfo_alloc (void){ SFSamDataInfo *datainfo; datainfo = g_chunk_new0 (SFSamDataInfo, chunk_samdatainfo); return (datainfo);}/* free a SFSamDataInfo structure */voidsfont_samdatainfo_free (SFSamDataInfo *datainfo){ g_mem_chunk_free (chunk_samdatainfo, datainfo);}/* -------------------------- *//* ---- SFZone functions ---- *//* -------------------------- *//* free all elements of a zone (Preset or Instrument) */voidsfont_zone_destroy (SFZone * zone){ GSList *p; if (!zone) return; p = zone->gen; while (p) { /* Free gen chunks for this zone */ if (p->data) g_mem_chunk_free (chunk_gen, p->data); p = g_slist_next (p); } g_slist_free (zone->gen); /* free genlist */ p = zone->mod; while (p) { /* Free mod chunks for this zone */ if (p->data) g_mem_chunk_free (chunk_mod, p->data); p = g_slist_next (p); } g_slist_free (zone->mod); /* free modlist */ sfont_zone_free (zone);}/* duplicate a zone (preset or instrument), mode can be one of 3 states SFDUP_NORMAL: Normal duplicate, itemids are cleared instsamp GSList * dup'd SFDUP_ARCHIVE: Archival mode, zone itemid dup'd, GSList * -> itemid SFDUP_RESTORE: Restore from archival, zone item ID dup'd, itemid -> GSList **/SFZone *sfont_zone_dup (SFZone * zone, SFDupEnum mode){ GSList *p; SFZone *dup; SFGen *gen, *dupgen; SFMod *mod, *dupmod; GtkCTreeNode *node; dup = sfont_zone_alloc (); if (mode != SFDUP_NORMAL) dup->itemid = zone->itemid; dup->gen = NULL; dup->mod = NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?