⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vbank.c

📁 A GTK sound font editor. Sound font files are used to synthesize instruments from audio samples for
💻 C
📖 第 1 页 / 共 2 页
字号:
/*================================================================== * vbank.c - Virtual sound font bank file (*.bnk) routines * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * Borrowed code from awesfx utilities * in files loadbank.c, bool.c, dynload.c in awelib/ * awesfx utilities are Copyright (C) 1996-1999 Takashi Iwai * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green <jgreen@users.sourceforge.net> * Smurf homepage: http://smurf.sourceforge.net *==================================================================*/#include "config.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <glib.h>#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <unistd.h>#include "vbank.h"#include "i18n.h"#include "sfont.h"#include "smurfcfg.h"#include "util.h"#include "uif_sfont.h"		/* probably won't depend on this in future */static void vbank_sort (VBnkData *vbnk);static gint vbank_map_sort_func (gconstpointer a, gconstpointer b);static gint vbank_compare_bank_prenum (gint bank1, gint pset1,				       gint bank2, gint pset2);static void vbank_GHFunc_find_sfont (gpointer key, gpointer value,				     gpointer data);static gint vbank_hash_sffiles (gchar *dirname, gboolean recurse);static gint vbank_parse (FILE *fp, VBnkData *vbnk);static gint vbank_parse_item(gchar *arg, VBnkItem *item, gchar **strp);static void vbank_parse_preset(VBnkPtr *vptr, char *arg);static int vbank_parse_arg(char *arg);static char *strschr(char *str, char *dels);/* hash tables to index sound font file names in virtual bank search path *//* vbank_sffile_hash is an index of sound font file names but with the '.' in   the extension changed to a '\0' which makes 2 strings. So the hash key is   effectively the sound font file name without the extension, but the extension   can still be found by retrieving the original key */static GHashTable *vbank_sffile_hash = NULL;static GHashTable *vbank_sfdir_hash = NULL; /* stores directory names */VBnkData *vbank_new (gint untitlecount){  VBnkData *vbnk;  vbnk = g_malloc0 (sizeof (VBnkData));  vbnk->fname = g_strdup_printf (_("untitled%d.bnk"), untitlecount);  vbnk->up2date = TRUE;  vbnk->beensaved = FALSE;  return (vbnk);}VBnkData *vbank_load (gchar *fname){  FILE *fp;  VBnkData *vbnk;  if (!(fp = fopen (fname, "r")))    {      logit (LogFubar, _("Failed to open virtual bank '%s'"), fname);      return (NULL);    }  vbnk = g_malloc0 (sizeof (VBnkData));  if (!vbank_parse (fp, vbnk))    return (NULL);  vbank_sort (vbnk);  vbnk->fname = g_strdup (fname);  vbnk->up2date = TRUE;  vbnk->beensaved = FALSE;  return (vbnk);}gintvbank_save (VBnkData * vbnk, FILE *fp){  VBnkItem *item;  GSList *p;  gchar *s, *s2, *name;  gint i;  if (fprintf (fp, _("## Virtual Sound Font Bank file written by:\n")) <= 0)    goto agh;  if (fprintf (fp, "## Smurf Sound Font Editor v" VERSION "\n\n") <= 0)    goto agh;  if (vbnk->defname && fprintf (fp, _("default %s\n\n"), vbnk->defname) <= 0)    goto agh;  p = vbnk->items;  while (p)    {      item = (VBnkItem *)(p->data);      /* write source preset/bank[/keynote] */      if (fprintf (fp, "%d/%d", item->src.psetnum, item->src.bank) <= 0)	goto agh;      if (item->src.keynote >= 0 && fprintf (fp, "/%d", item->src.keynote) <= 0)	goto agh;      /* write destination :preset/bank[/keynote] */      if (fprintf (fp, ":%d/%d", item->map.psetnum, item->map.bank) <= 0)	goto agh;      if (item->map.keynote >= 0 && fprintf (fp, "/%d", item->map.keynote) <= 0)	goto agh;      /* get name of source sound font (no path or extension) */      s = item->sfname;      if (s)			/* if sound font file name, then format it */	{	  i = strlen (s);	  /* allocate space for largest possible '\' escaped sound font name */	  name = g_malloc (i * 2 + 1);	  s2 = name;	  /* '\' escape all spaces and back slashes */	  while (i--)	    {	      if (*s == ' ')		{		  *(s2++) = '\\';		  *(s2++) = ' ';		}	      else if (*s == '\\')		{		  *(s2++) = '\\';		  *(s2++) = '\\';		}	      else *(s2++) = *s;	      s++;	    }	  *s2 = '\0';	  i = fprintf (fp, ":%s", name);	  g_free (name);	  if (i <= 0) goto agh;	}      if (fputc ('\n', fp) == EOF)	goto agh;      p = g_slist_next (p);    }  return (OK); agh:  return (logit (LogFubar | LogErrno, _("Failed to write to vbank")));}voidvbank_close (VBnkData *vbnk){  GSList *p;  if (vbnk->fname) g_free (vbnk->fname);  if (vbnk->defname) g_free (vbnk->defname);  p = vbnk->items;  while (p)    {      vbank_item_free ((VBnkItem *)(p->data));      p = g_slist_next (p);    }}VBnkItem *vbank_item_alloc (void){  return ((VBnkItem *)g_malloc0 (sizeof (VBnkItem)));}voidvbank_item_free (VBnkItem *item){  if (item->sfname) g_free (item->sfname);  g_free (item);}VBnkItem *vbank_add_map (gint mapbank, gint mappset, gint mapnote, gint srcbank,	       gint srcpset, gint srcnote, gchar *srcsfname, VBnkData *vbnk){  VBnkItem *item;  g_return_val_if_fail (srcsfname != NULL, NULL);  item = vbank_item_alloc ();  item->map.bank = mapbank;  item->map.psetnum = mappset;  item->map.keynote = mapnote;  item->src.bank = srcbank;  item->src.psetnum = srcpset;  item->src.keynote = srcnote;  item->sfname = srcsfname;  vbnk->items = g_slist_insert_sorted (vbnk->items, item, vbank_map_sort_func);  return (item);}voidvbank_delete_map (VBnkItem *item, VBnkData *vbnk){  vbnk->items = g_slist_remove (vbnk->items, item);  vbank_item_free (item);}/* finds the first available preset map greater or equal to bank:preset and   stores result in bank:preset */voidvbank_find_free_map (gint *bank, gint *psetnum, VBnkData *vbnk){  VBnkItem *item;  GSList *p;  gint bnk, pr;  p = vbnk->items;  bnk = *bank;  pr = *psetnum;  while (p)    {      item = (VBnkItem *)(p->data);      p = g_slist_next (p);      /* if item->bank:preset < start bank:preset, then skip */      if (item->map.bank < *bank	  || (item->map.bank == *bank && item->map.psetnum < *psetnum))	continue;      if (bnk < item->map.bank	  || (bnk == item->map.bank && pr < item->map.psetnum))	break;      if (++pr > 127)	{	  pr = 0;	  bnk++;	}    }  *bank = bnk;  *psetnum = pr;}static voidvbank_sort (VBnkData *vbnk){  vbnk->items = g_slist_sort (vbnk->items, vbank_map_sort_func);}/* a GCompareFunc for the sorting of VBnkItems */static gintvbank_map_sort_func (gconstpointer a, gconstpointer b){  VBnkItem *aitem, *bitem;  aitem = (VBnkItem *)a;  bitem = (VBnkItem *)b;  return (((aitem->map.bank - bitem->map.bank) << 8)    + (aitem->map.psetnum - bitem->map.psetnum));}/* check the extension */gintvbank_is_virtual_bank (gchar *path){  char *p;  if ((p = strrchr(path, '.')) == NULL)    return FALSE;  if (strcmp(p + 1, "bnk") == 0)    return TRUE;  return FALSE;}voidvbank_set_fname (VBnkData *vbnk, gchar *fname){  if (vbnk->fname) g_free (vbnk->fname);  vbnk->fname = g_strdup (fname);}voidvbank_set_defsf (VBnkData *vbnk, gchar *fname){  g_return_if_fail (fname != NULL);  if (vbnk->defname) g_free (vbnk->defname);  vbnk->defname = fname;}/* get virtual bank items (returns: GList of VBnkPresetMap's)   ** GList and list items should be freed ** */GList *vbank_get_preset_maps (VBnkData *vbnk){  GList *psetlist = NULL;  VBnkItem *item;  VBnkPresetMap *psetmap;  UISFont *uisf, *defuisf;  SFPreset *pset;  gchar *path;  GSList *lvi, *lpr;  gint rv;  /* find default sound font if its opened already */  path = NULL;  if (vbnk->defname && (path = vbank_locate_sfont_by_name (vbnk->defname))      && (defuisf = uisf_find_sfont_by_fname (path, NULL)))    lpr = uisf->sf->preset;  else lpr = NULL;  if (path) g_free (path);  lvi = vbnk->items;  /* loop over virtual bank items and default sound font presets, virtual bank     items override default presets */  while (lvi || lpr)    {      if (lvi)			/* any virtual bank items left? */	{	  item = (VBnkItem *)(lvi->data);	  rv = 1;	}      /* allocate preset map (an SFPreset and its bank:preset # to map to) */      psetmap = g_malloc (sizeof (VBnkPresetMap));      if (lpr)			/* any default presets left? */	{	  psetmap->preset = (SFPreset *)(lpr->data);	  rv = -1;	}      /* check ordering of current vbank item and default preset */      if (lvi && lpr)	rv = vbank_compare_bank_prenum (psetmap->preset->bank,					psetmap->preset->prenum,					item->map.bank, item->map.psetnum);      if (rv <= 0)		/* advance default preset, if needed */	lpr = g_slist_next (lpr);      if (rv >= 0)		/* vbank item comes next or overrides def? */	{	  lvi = g_slist_next (lvi);	  /* ?: sound font loaded for this item and src preset is valid? */	  if (!(pset = vbank_get_item_preset (item)))	    {	      g_free (psetmap);	      continue;		/* ?: No, skip it */	    }	  psetmap->preset = pset;	  psetmap->sf = uisf->sf;	  psetmap->bank = item->map.bank;	  psetmap->psetnum = item->map.psetnum;	}      else	{	  psetmap->sf = defuisf->sf;	  psetmap->bank = psetmap->preset->bank;	  psetmap->psetnum = psetmap->preset->prenum;	}      psetlist = g_list_append (psetlist, psetmap);    }  return (psetlist);}/* find a virtual bank item's preset in opened sfonts (NULL if not found) */SFPreset *vbank_get_item_preset (VBnkItem *item){  gchar *path;  UISFont *uisf;  GSList *p;  if (item->sfname      && (path = vbank_locate_sfont_by_name (item->sfname))      && (uisf = uisf_find_sfont_by_fname (path, NULL))      && (p = sfont_find_preset (uisf->sf, NULL, item->src.bank,				 item->src.psetnum, NULL)))    return ((SFPreset *)(p->data));  return (NULL);}/* compares two bank:preset pairs */static gintvbank_compare_bank_prenum (gint bank1, gint pset1, gint bank2, gint pset2){  if (bank1 < bank2) return (-1);  if (bank1 > bank2) return (1);

⌨️ 快捷键说明

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