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

📄 uif_selections.c

📁 A GTK sound font editor. Sound font files are used to synthesize instruments from audio samples for
💻 C
📖 第 1 页 / 共 3 页
字号:
/*================================================================== * uif_selections.c - Sound font item selection management routines * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * 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 <stdio.h>#include <string.h>#include <gtk/gtk.h>#include "uif_selections.h"#include "uif_sfont.h"#include "uif_sftree.h"#include "glade_interface.h"#include "uif_pianospan.h"#include "wavetable.h"#include "sfundo.h"#include "sfdofunc.h"#include "smurfcfg.h"#include "util.h"#include "i18n.h"/* WARNING: Ugly code ahead, proceed with caution :) */enum { UISEL_START, UISEL_CHANGE, UISEL_REPLACE, UISEL_KEEP, UISEL_CANCEL };/* hashes to group duplicates and "remember" user choices */static GHashTable *inst_hash = NULL;static GHashTable *sample_hash = NULL;/* current item awaiting user input */static SFNodeType paste_item_type;static gpointer paste_item_data;/* dialog widget awaiting user input */GtkWidget *dup_item_dialog;/* user requested action for all items of type.. */static gint preset_all_mode;static gint inst_all_mode;static gint sample_all_mode;static GSList *uisel_clone_preset (GSList *lpset, UISFont *dstuisf,				    UISFont *srcuisf, gint mode);static GSList *uisel_clone_inst (GSList *linst, UISFont *dstuisf,				  UISFont *srcuisf, gint mode);static GSList *uisel_clone_sample (GSList *lsam, UISFont *dstuisf,				   UISFont *srcuisf, gint mode);static GSList *uisel_new_preset_from_inst (SFTreeRef *dstref, SFTreeRef *srcref,			UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_new_inst_from_sample (SFTreeRef *dstref, SFTreeRef *srcref,			UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_paste_pzone (GtkCTreeNode *pnode, SFTreeRef *srcref,				UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_paste_izone (GtkCTreeNode *pnode, SFTreeRef *srcref,				UISFont *dstuisf, UISFont *srcuisf, gint mode);static gpointer uisel_vbank_paste (GtkCTreeNode *dstnode, SFPreset *pset,				   SFData *srcsf);static void uisel_dup_item_dialog (gchar *lbl1, ...);static gboolean uisel_cb_dup_item_destroy (GtkWidget *dialog);static void uisel_cb_preset_change_okay (GtkWidget *cfgdialog);static void uisel_cb_inst_change_okay (GtkWidget *cfgdialog);static void uisel_cb_sample_change_okay (GtkWidget *cfgdialog);static void uisel_cb_dup_zone (gpointer data, GtkWidget *popdog);static gboolean uisel_cb_dup_zone_destroy (GtkWidget *popdog);static void uisel_cb_dialog_selection_delete_okay (gpointer data,						   GtkWidget *popdog);voiduisel_paste_items_start (void){  if (sftree_rclicked_itemid == SFITEMID_NONE) return;  uisel_paste_items (sftree_rclicked_itemid, UISEL_START);}/* pastes appropriate selected items to a node */voiduisel_paste_items (SFItemID itemid, gint mode){  static GtkCTreeNode *dstnode;  static GList *sel;  static GList *selp;  UISFont *dstuisf, *srcuisf;  SFTreeRef *dstref, *srcref;  GSList *p;  gint dsttype, srctype;  GtkCTreeNode *n;  gpointer retp;  if (mode == UISEL_START)	/* start? */    {      if (!(dstnode = SFTREE_LOOKUP_ITEMID (itemid))) return;      sel = selp = sftree_get_selection ();      inst_hash = g_hash_table_new (NULL, NULL);      sample_hash = g_hash_table_new (NULL, NULL);      preset_all_mode = inst_all_mode = sample_all_mode = UISEL_START;      sfdo_group (_("Paste sound font items"));      SFTREE_FREEZE ();    }  dstuisf = SFTREE_UPFIND_UISF (dstnode);  dstref = SFTREE_NODE_REF (dstnode);  dsttype = dstref->type;  while (selp)			/* loop over selection */    {      /* get CTree node from item ID */      n = SFTREE_LOOKUP_ITEMID (GPOINTER_TO_INT (selp->data));      if (!n) {			/* node been removed? skip */	mode = UISEL_START;	selp = g_list_next (selp);	continue;      }      srcuisf = SFTREE_UPFIND_UISF (n);      srcref = SFTREE_NODE_REF (n);      p = srcref->dptr;      srctype = srcref->type;      if (srctype == NODE_PRESET && (dsttype == NODE_SFONT          || dsttype == NODE_PRESETROOT || dsttype == NODE_MELODIC          || dsttype == NODE_PERCUSS)) 	/* clone preset */	retp = uisel_clone_preset (p, dstuisf, srcuisf, mode);      else if (srctype == NODE_INST  /* clone instrument */	       && (dsttype == NODE_SFONT || dsttype == NODE_INSTROOT))	retp = uisel_clone_inst (p, dstuisf, srcuisf, mode);      else if (srctype == NODE_SAMPLE && (dsttype == NODE_SFONT	  || dsttype == NODE_SAMPLEROOT || dsttype == NODE_USER	  || dsttype == NODE_ROM)) /* clone sample */	retp = uisel_clone_sample (p, dstuisf, srcuisf, mode);      else if (dsttype == NODE_PRESET && /* paste preset zone */	       (srctype == NODE_INST || srctype == NODE_PZONE))	retp = uisel_paste_pzone (dstnode, srcref, dstuisf, srcuisf, mode);      else if (dsttype == NODE_INST && /* paste instrument zone */	       (srctype == NODE_SAMPLE || srctype == NODE_IZONE))	retp = uisel_paste_izone (dstnode, srcref, dstuisf, srcuisf, mode);      else if (srctype == NODE_INST && (dsttype == NODE_PRESETROOT	  || dsttype == NODE_MELODIC	  || dsttype == NODE_PERCUSS)) /* create preset from instrument */	retp =	  uisel_new_preset_from_inst (dstref, srcref, dstuisf, srcuisf, mode);      else if (srctype == NODE_SAMPLE /* create instrument from sample */	       && (dsttype == NODE_INSTROOT))	retp =	  uisel_new_inst_from_sample (dstref, srcref, dstuisf, srcuisf, mode);      else if (srctype == NODE_PRESET && (dsttype == NODE_VBANK	  || dsttype == NODE_VBNK_MAPROOT || dsttype == NODE_VBNK_MAP))	{			/* paste preset to vbank */	  uisel_vbank_paste (dstnode, (SFPreset *)(p->data), srcuisf->sf);	}      else if (srctype == NODE_SFONT && dsttype == NODE_VBNK_DEFBANK)	{	  UIVBank *uivb = SFTREE_UPFIND_UIVB (dstnode);	  gchar *s = vbank_base_fname (srcuisf->sf->fname);	  vbank_set_defsf (uivb->vbnk, s);	  g_free (s);	}      else	retp = GINT_TO_POINTER (1); /* A non NULL value */      if (mode == UISEL_CANCEL)	/* User requested Cancel? */	{	  sfdo_retract ();	/* undo partially copied selection */	  SFTREE_THAW ();	  g_hash_table_destroy (sample_hash);	  g_hash_table_destroy (inst_hash);	  g_list_free (sel);	  return;	}      if (!retp) return;	/* only NULL if waiting for user input */      mode = UISEL_START;      selp = g_list_next (selp);    }  sfdo_done ();  SFTREE_THAW ();  g_hash_table_destroy (sample_hash);  g_hash_table_destroy (inst_hash);  g_list_free (sel);}static GSList *uisel_clone_preset (GSList *lpset, UISFont *dstuisf, UISFont *srcuisf,		    gint mode){  SFZone *z;  GSList *linst;  GtkCTreeNode *node;  static SFPreset *dup;  static GSList *p;  static gboolean check;  static GSList *duplpset;  if (mode == UISEL_START)    {      dup = sfont_preset_dup ((SFPreset *)(lpset->data), SFDUP_NORMAL);      p = dup->zone;      check = FALSE;    }  if (!check)    {      if (mode == UISEL_START || mode == UISEL_CHANGE)	/* check for duplicate preset (including itself) */	if ((duplpset = sfont_find_preset (dstuisf->sf, dup->name,					   dup->bank, dup->prenum, NULL)))	  {	    if (preset_all_mode == UISEL_START || mode != UISEL_START)	      {		/* if no all mode or mode not UISEL_START */		SFPreset *dup2 = (SFPreset *)(duplpset->data);		gchar *s1, *s2, *s3, *s4;		paste_item_type = NODE_PRESET;		paste_item_data = dup;		s1 = g_strdup_printf ("%d", dup->bank);		s2 = g_strdup_printf ("%d", dup2->bank);		s3 = g_strdup_printf ("%d", dup->prenum);		s4 = g_strdup_printf ("%d", dup2->prenum);		/* Duplicate preset dialog: Change, Replace, Keep, Cancel */		uisel_dup_item_dialog (_("Type"), _("Preset"), NULL,				       _("Name"), dup->name, dup2->name,				       _("Bank"), s1, s2,				       _("Preset"), s3, s4,				       _("Sound font"),				       sfont_get_info (srcuisf->sf, INAM_ID),				       sfont_get_info (dstuisf->sf, INAM_ID),				       _("File name"),				       srcuisf->sf->fname,				       dstuisf->sf->fname,				       NULL);		g_free (s1); g_free (s2); g_free (s3); g_free (s4);		return (NULL);	/* return to wait for user input */	      }	    else mode = preset_all_mode; /* user requested all mode */	}      switch (mode)	{	case UISEL_REPLACE:	/* Replace duplicate preset (not done yet) */	  break;	case UISEL_KEEP:	/* Keep existing duplicate preset */	  sfont_preset_destroy (dup);	  return (duplpset);	case UISEL_CANCEL:	/* Cancel paste operation */	  sfont_preset_destroy (dup);	  return (NULL);	}      check = TRUE;		/* flag duplicate check as done */      mode = UISEL_START;	/* Reset mode */    }  /* if src and dest sound font is different, copy instruments/samples too */  if (dstuisf != srcuisf)    {      while (p)			/* loop over preset zones */	{	  z = (SFZone *)(p->data);	  linst = NULL;	  /* if zone has an inst then duplicate it */	  if (z->instsamp)	    {	      linst = uisel_clone_inst (z->instsamp, dstuisf, srcuisf, mode);	      if (mode == UISEL_CANCEL)	/* catch cancel request */		sfont_preset_destroy (dup);	      /* uisel_clone_inst is waiting for user input or canceled */	      if (!linst) return (NULL);	      mode = UISEL_START; /* Reset mode */	    }	  z->instsamp = linst;	/* assign instrument pointer */	  p = g_slist_next (p);	}    }  /* add the duplicated preset to the destination sound font and the sftree */  sfont_add_preset (dstuisf->sf, dup);  duplpset = g_slist_find (dstuisf->sf->preset, dup);  node = sftree_add_preset_sorted (duplpset, dstuisf->nodes);  /* tell sfundo about our new item */  dofunc_noitem_save (SFTREE_NODE_REF (node)->itemid);  return (duplpset);}static GSList *uisel_clone_inst (GSList *linst, UISFont *dstuisf, UISFont *srcuisf, gint mode){  SFZone *z;  GSList *lsam;  GtkCTreeNode *node;  static SFInst *dup;  static GSList *p;  static gboolean check;  static GSList *duplinst;  if (mode == UISEL_START)    {      /* check if this instrument already processed */      if ((duplinst = g_hash_table_lookup (inst_hash, linst)))	return (duplinst);      dup = sfont_inst_dup ((SFInst *)(linst->data), SFDUP_NORMAL);      p = dup->zone;      check = FALSE;    }  if (!check)    {      if (mode == UISEL_START || mode == UISEL_CHANGE)	/* check for duplicate instrument (including itself) */	if ((duplinst = sfont_find_inst (dstuisf->sf, dup->name, NULL)))	  {	    if (inst_all_mode == UISEL_START || mode != UISEL_START)	      {		/* if no all mode or mode not UISEL_START */		paste_item_type = NODE_INST;		paste_item_data = dup;		/* Duplicate inst dialog: Change, Replace, Keep, Cancel */		uisel_dup_item_dialog (_("Type"), _("Instrument"), NULL,				       _("Name"), dup->name, NULL,				       _("Sound font"),				       sfont_get_info (srcuisf->sf, INAM_ID),				       sfont_get_info (dstuisf->sf, INAM_ID),				       _("File name"),				       srcuisf->sf->fname,				       dstuisf->sf->fname,				       NULL);		return (NULL);	/* return to wait for user input */	      }	    else mode = inst_all_mode; /* user requested all mode */	  }      switch (mode)	{	case UISEL_REPLACE:	/* Replace duplicate inst (not done yet) */	  break;	case UISEL_KEEP:	/* Keep existing duplicate inst */	  /* add ptr to inst hash of the destination inst to keep, it will be	     used for all references to this intrument */	  g_hash_table_insert (inst_hash, linst, duplinst);	  sfont_inst_destroy (dup);	  return (duplinst);	case UISEL_CANCEL:	/* Cancel paste operation */	  sfont_inst_destroy (dup);	  return (NULL);	}      check = TRUE;		/* flag duplicate check as done */      mode = UISEL_START;	/* Reset mode */    }  /* if src and dest sound font is different, copy samples too */  if (dstuisf != srcuisf)    {      while (p)	{			/* loop over inst zones */	  z = (SFZone *)(p->data);	  lsam = NULL;	  /* if zone has a sample duplicate it */	  if (z->instsamp)	    {	      lsam = uisel_clone_sample (z->instsamp, dstuisf, srcuisf, mode);	      if (mode == UISEL_CANCEL)	/* catch cancel request */		sfont_inst_destroy (dup);	      /* uisel_clone_sample is waiting for user input or canceled */	      if (!lsam) return (NULL);	      mode = UISEL_START; /* Reset mode */	    }	  z->instsamp = lsam;	/* assign sample pointer */	  p = g_slist_next (p);	}    }  /* add the duplicated inst to the destination sound font and the sftree */  sfont_add_inst (dstuisf->sf, dup);  duplinst = g_slist_find (dstuisf->sf->inst, dup);  node = sftree_add_inst (duplinst, dstuisf->nodes, SFTREE_NODE_APPEND);

⌨️ 快捷键说明

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