📄 uif_samview.c
字号:
/*================================================================== * uif_samview.c - Sample viewer 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 <stdlib.h>#include <gtk/gtk.h>#include "uiface.h"#include "uif_samview.h"#include "uif_sfont.h"#include "widgets/samview.h"#include "widgets/ptrstrip.h"#include "wavetable.h"#include "sample.h"#include "sfont.h"#include "smurfcfg.h"#include "util.h"#include "i18n.h"/* order of markers determines order of overlap (last = on top) */enum{ MARK_SAMLOOPSTART, MARK_SAMLOOPEND, /* IZonely, sam loop/end, not settable */ MARK_SAMSTARTOFS, MARK_SAMENDOFS, /* IZONE only, sample start/end ofs */ MARK_LOOPSTART, MARK_LOOPEND, /* SAMPLE mode loop start/end, IZONE loop ofs */ MARK_COUNT};/* pointer index enumerations */enum{ PTR_LOOPSTART, PTR_LOOPEND, PTR_SAMSTARTOFS, PTR_SAMENDOFS, PTR_COUNT };gint samview_mode = SAMVIEW_INACTIVE;GtkWidget *samview_win; /* top level sample view widget */GtkWidget *samview_widg; /* the actual samview widget */GtkWidget *samview_ptrstrip; /* the pointer strip widget for sample view */GtkWidget *samview_loopbtn; /* loop on/off toggle button */GtkWidget *samview_cut_btn; /* the sample "cut" button *//* 4 spinbtns for LOOPSTART, LOOPEND, SAMSTARTOFS and SAMENDOFS, 2 are NULL */GtkWidget *samview_spbtns[MARK_COUNT] = {NULL, NULL, NULL, NULL, NULL, NULL};static GtkWidget *samview_create_spbtn (gint markenum);static void samview_update_spbtn (gint markenum);static void samview_update_spin_buttons (void);static void samview_spbtn_set_value_nosig (gint markenum, gint val);static void samview_cb_loopbtn_toggled (GtkWidget * btn);static void samview_cb_cut_button_clicked (GtkWidget * btn);static void samview_get_samplemark_bounds(gint markenum, gint *pmin, gint *pmax, gint *pminpad, gint *pmaxpad);static gint samview_clamp_samplemark_pos (gint markenum, gint val);static void samview_cb_spbtn_value_changed (GtkAdjustment *adj, gint markenum);static void samview_cb_ptrstrip_select (GtkWidget * widg, guint ptrndx);static void samview_cb_ptrstrip_unselect (GtkWidget * widg, guint ptrndx);static void samview_cb_ptrstrip_change (GtkWidget * widg, guint ptrndx);static void samview_cb_samview_change (SamView * samview);/******** User interface functions ********/voidsamview_set_mode (gint mode){ gint i; if (mode == samview_mode) return; /* mode change needed? */ switch (mode) { case SAMVIEW_INACTIVE: /* inactive mode */ /* set samview sample data pointer to NULL before anything else! */ samview_set_data (SAMVIEW (samview_widg), NULL, 0); for (i = 0; i < MARK_COUNT; i++) { /* disable markers */ samview_set_marker (SAMVIEW (samview_widg), i, -1); if (samview_spbtns[i]) { /* disable spin buttons */ samview_spbtn_set_value_nosig(i, 0); gtk_widget_set_sensitive (samview_spbtns[i], FALSE); } } for (i = 0; i < PTR_COUNT; i++) ptrstrip_set_pointer (PTRSTRIP (samview_ptrstrip), i, -1); /* don't trigger loop button handler */ gtk_signal_handler_block_by_func (GTK_OBJECT (samview_loopbtn), (GtkSignalFunc) samview_cb_loopbtn_toggled, NULL); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (samview_loopbtn), FALSE); /* re-enable handler */ gtk_signal_handler_unblock_by_func (GTK_OBJECT (samview_loopbtn), (GtkSignalFunc) samview_cb_loopbtn_toggled, NULL); gtk_widget_set_sensitive (samview_loopbtn, FALSE); /* hide the sample cut button */ gtk_widget_hide (samview_cut_btn); break; case SAMVIEW_SAMPLE: /* sample view mode */ /* disable sample start/end and sample loop start/end */ samview_set_marker (SAMVIEW (samview_widg), MARK_SAMSTARTOFS, -1); samview_set_marker (SAMVIEW (samview_widg), MARK_SAMENDOFS, -1); samview_set_marker (SAMVIEW (samview_widg), MARK_SAMLOOPSTART, -1); samview_set_marker (SAMVIEW (samview_widg), MARK_SAMLOOPEND, -1); ptrstrip_set_pointer (PTRSTRIP (samview_ptrstrip), PTR_SAMSTARTOFS, -1); ptrstrip_set_pointer (PTRSTRIP (samview_ptrstrip), PTR_SAMENDOFS, -1); /* make used spin buttons sensitive */ gtk_widget_set_sensitive (samview_spbtns[MARK_LOOPSTART], TRUE); gtk_widget_set_sensitive (samview_spbtns[MARK_LOOPEND], TRUE); /* clear and disable unused spin buttons */ samview_spbtn_set_value_nosig (MARK_SAMSTARTOFS, 0); gtk_widget_set_sensitive (samview_spbtns[MARK_SAMSTARTOFS], FALSE); samview_spbtn_set_value_nosig (MARK_SAMENDOFS, 0); gtk_widget_set_sensitive (samview_spbtns[MARK_SAMENDOFS], FALSE); gtk_widget_set_sensitive (samview_loopbtn, TRUE); /* don't trigger loop button handler */ gtk_signal_handler_block_by_func (GTK_OBJECT (samview_loopbtn), (GtkSignalFunc) samview_cb_loopbtn_toggled, NULL); /* set loop toggle to state of wtbl_loop_sam_as_inst which determines if samples loaded as instruments are looped or not */ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (samview_loopbtn), wtbl_loop_sam_as_inst); /* re-enable handler */ gtk_signal_handler_unblock_by_func (GTK_OBJECT (samview_loopbtn), (GtkSignalFunc) samview_cb_loopbtn_toggled, NULL); /* show sample cut button */ gtk_widget_show (samview_cut_btn); break; case SAMVIEW_IZONE: /* instrument zone view mode */ /* enable all spin buttons */ gtk_widget_set_sensitive (samview_spbtns[MARK_LOOPSTART], TRUE); gtk_widget_set_sensitive (samview_spbtns[MARK_LOOPEND], TRUE); gtk_widget_set_sensitive (samview_spbtns[MARK_SAMSTARTOFS], TRUE); gtk_widget_set_sensitive (samview_spbtns[MARK_SAMENDOFS], TRUE); gtk_widget_set_sensitive (samview_loopbtn, TRUE); /* hide the sample cut button */ gtk_widget_hide (samview_cut_btn); break; } samview_mode = mode;}/* update the sample view for the current mode */voidsamview_update (void){ SFGenAmount *amt; gboolean b; guint pos; if (samview_mode == SAMVIEW_INACTIVE) return; if (!sam_in_view) { samview_set_mode (SAMVIEW_INACTIVE); return; } /* set the sample data to view (must be done before other samview stuff!) */ samview_set_data (SAMVIEW (samview_widg), sam_data_in_view, sam_in_view->end + 1); if (samview_mode == SAMVIEW_SAMPLE) { /* sample view mode */ pos = samview_get_samplemark_pos (MARK_LOOPSTART); samview_set_marker (SAMVIEW (samview_widg), MARK_LOOPSTART, pos); pos = samview_get_samplemark_pos (MARK_LOOPEND); samview_set_marker (SAMVIEW (samview_widg), MARK_LOOPEND, pos); /* update pointer strip */ samview_cb_samview_change (SAMVIEW (samview_widg)); } else { /* instrument zone view mode */ SFSample *sam; /* get sample for this instrument zone */ sam = (SFSample *) (uisf_selected_zone->instsamp->data); /* set the sample loop start/end markers (user cannot change them) */ samview_set_marker (SAMVIEW (samview_widg), MARK_SAMLOOPSTART, samview_get_samplemark_pos (MARK_SAMLOOPSTART)); samview_set_marker (SAMVIEW (samview_widg), MARK_SAMLOOPEND, samview_get_samplemark_pos (MARK_SAMLOOPEND)); /* set the 4 other markers in the view and set up spin buttons */ pos = samview_get_samplemark_pos (MARK_LOOPSTART); pos += samview_get_samplemark_pos (MARK_SAMLOOPSTART); samview_set_marker (SAMVIEW (samview_widg), MARK_LOOPSTART, pos); pos = samview_get_samplemark_pos (MARK_LOOPEND); pos += samview_get_samplemark_pos (MARK_SAMLOOPEND); samview_set_marker (SAMVIEW (samview_widg), MARK_LOOPEND, pos); pos = samview_get_samplemark_pos (MARK_SAMSTARTOFS); samview_set_marker (SAMVIEW (samview_widg), MARK_SAMSTARTOFS, pos); pos = samview_get_samplemark_pos (MARK_SAMENDOFS); pos += sam_in_view->end; samview_set_marker (SAMVIEW (samview_widg), MARK_SAMENDOFS, pos); /* update pointer strip */ samview_cb_samview_change (SAMVIEW (samview_widg)); amt = sfont_gen_get (uisf_selected_zone, Gen_SampleModes); if (!amt || !(amt->uword & SF_SAMPMODES_LOOP)) b = FALSE; else b = TRUE; gtk_widget_set_sensitive (samview_loopbtn, TRUE); gtk_signal_handler_block_by_func (GTK_OBJECT (samview_loopbtn), (GtkSignalFunc) samview_cb_loopbtn_toggled, NULL); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (samview_loopbtn), b); gtk_signal_handler_unblock_by_func (GTK_OBJECT (samview_loopbtn), (GtkSignalFunc) samview_cb_loopbtn_toggled, NULL); } /* update spin buttons */ samview_update_spin_buttons ();}static GtkWidget *samview_create_spbtn (gint markenum){ GtkObject *adj; GtkWidget *spbtn; adj = gtk_adjustment_new (0.0, 0.0, 0.0, 1.0, 10.0, 0.0); spbtn = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1, 0); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spbtn), TRUE); gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spbtn), GTK_UPDATE_IF_VALID); gtk_widget_set_usize (spbtn, 80, -1); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", (GtkSignalFunc) samview_cb_spbtn_value_changed, GINT_TO_POINTER (markenum)); gtk_widget_show (spbtn); return (spbtn);}/* update spin buttons */static voidsamview_update_spbtn (gint markenum){ GtkAdjustment *adj; gint pos, min, max, minpad, maxpad; samview_get_samplemark_bounds (markenum, &min, &max, &minpad, &maxpad); adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (samview_spbtns [markenum])); adj->lower = min + minpad; adj->upper = max + maxpad; gtk_adjustment_changed (adj); pos = samview_get_samplemark_pos (markenum); samview_spbtn_set_value_nosig (markenum, pos);}static voidsamview_update_spin_buttons (void){ if (samview_mode == SAMVIEW_SAMPLE) { samview_update_spbtn (MARK_LOOPSTART); samview_update_spbtn (MARK_LOOPEND); } else if (samview_mode == SAMVIEW_IZONE) { samview_update_spbtn (MARK_LOOPSTART); samview_update_spbtn (MARK_LOOPEND); samview_update_spbtn (MARK_SAMSTARTOFS); samview_update_spbtn (MARK_SAMENDOFS); }}/* set value of mark spin button and without causing value-changed signal */static voidsamview_spbtn_set_value_nosig (gint markenum, gint val){ GtkAdjustment *adj; adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (samview_spbtns [markenum])); gtk_signal_handler_block_by_func (GTK_OBJECT (adj), (GtkSignalFunc)samview_cb_spbtn_value_changed, GINT_TO_POINTER (markenum)); gtk_adjustment_set_value (adj, (float) val); gtk_signal_handler_unblock_by_func (GTK_OBJECT (adj), (GtkSignalFunc)samview_cb_spbtn_value_changed, GINT_TO_POINTER (markenum));}GtkWidget *samview_create (void){ GtkWidget *main_box; GtkWidget *box, *vbox; GtkWidget *lbl; GtkWidget *sbar; GtkWidget *frame; GdkColor clr; main_box = gtk_vbox_new (FALSE, 0); box = gtk_hbox_new (FALSE, 2); gtk_widget_show (box); samview_loopbtn = gtk_check_button_new_with_label (_("Loop:")); gtk_signal_connect (GTK_OBJECT (samview_loopbtn), "toggled", (GtkSignalFunc) samview_cb_loopbtn_toggled, NULL); gtk_widget_show (samview_loopbtn); gtk_box_pack_start (GTK_BOX (box), samview_loopbtn, FALSE, FALSE, 0); /* loop start spin button */ samview_spbtns[MARK_LOOPSTART] = samview_create_spbtn (MARK_LOOPSTART); gtk_box_pack_start (GTK_BOX (box), samview_spbtns[MARK_LOOPSTART], FALSE, FALSE, 0); /* loop end spin button */ samview_spbtns[MARK_LOOPEND] = samview_create_spbtn (MARK_LOOPEND); gtk_box_pack_start (GTK_BOX (box), samview_spbtns[MARK_LOOPEND], FALSE, FALSE, 0); lbl = gtk_label_new (_("Sample:")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (box), lbl, FALSE, FALSE, 0); /* sample start offset spin button */ samview_spbtns[MARK_SAMSTARTOFS] = samview_create_spbtn (MARK_SAMSTARTOFS); gtk_box_pack_start (GTK_BOX (box), samview_spbtns[MARK_SAMSTARTOFS], FALSE, FALSE, 0); /* sample end offset spin button */ samview_spbtns[MARK_SAMENDOFS] = samview_create_spbtn (MARK_SAMENDOFS); gtk_box_pack_start (GTK_BOX (box), samview_spbtns[MARK_SAMENDOFS], FALSE, FALSE, 0); /* cut button */ samview_cut_btn = gtk_button_new_with_label (_("Cut")); gtk_widget_show (samview_cut_btn); gtk_signal_connect (GTK_OBJECT (samview_cut_btn), "clicked", (GtkSignalFunc) samview_cb_cut_button_clicked, NULL); gtk_box_pack_start (GTK_BOX (box), samview_cut_btn, FALSE, FALSE, 0); /* vbox to set vertical spacing of upper outtie frame */ vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox); gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 2); /* upper outtie frame, with sample mark text entries etc. */ frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); gtk_container_set_border_width (GTK_CONTAINER (frame), 0); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (main_box), frame, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frame), vbox); /* lower inset frame for sample viewer */ frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_container_set_border_width (GTK_CONTAINER (frame), 0); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (main_box), frame, TRUE, TRUE, 0); /* vbox within frame to put samview and mark pointer strip */ vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (frame), vbox); samview_ptrstrip = ptrstrip_new (); ptrstrip_new_pointer (PTRSTRIP (samview_ptrstrip), -1); ptrstrip_new_pointer (PTRSTRIP (samview_ptrstrip), -1); ptrstrip_new_pointer (PTRSTRIP (samview_ptrstrip), -1); ptrstrip_new_pointer (PTRSTRIP (samview_ptrstrip), -1); gtk_signal_connect (GTK_OBJECT (samview_ptrstrip), "pointer_select", (GtkSignalFunc) samview_cb_ptrstrip_select, NULL); gtk_signal_connect (GTK_OBJECT (samview_ptrstrip), "pointer_unselect", (GtkSignalFunc) samview_cb_ptrstrip_unselect, NULL); gtk_signal_connect (GTK_OBJECT (samview_ptrstrip), "pointer_change", (GtkSignalFunc) samview_cb_ptrstrip_change, NULL); gtk_widget_show (samview_ptrstrip); gtk_box_pack_start (GTK_BOX (vbox), samview_ptrstrip, FALSE, FALSE, 1); samview_widg = samview_new (); gtk_signal_connect_after (GTK_OBJECT (samview_widg), "view_change", (GtkSignalFunc) samview_cb_samview_change, NULL); /* MARK sample loop START/END (not interactive) */ RGB2GDK (clr, 80, 160, 80); samview_new_marker (SAMVIEW (samview_widg), &clr); samview_new_marker (SAMVIEW (samview_widg), &clr); /* MARK sample START/END OFS */ RGB2GDK (clr, 255, 0, 0); samview_new_marker (SAMVIEW (samview_widg), &clr); samview_new_marker (SAMVIEW (samview_widg), &clr); /* MARK loop START/END */ RGB2GDK (clr, 0, 255, 0); samview_new_marker (SAMVIEW (samview_widg), &clr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -