📄 uif_piano.c
字号:
/*================================================================== * uif_piano.c - Piano user interface 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 <config.h>#include <stdio.h>#include <gtk/gtk.h>#include <gdk/gdkkeysyms.h>#include "uif_piano.h"#include "widgets/piano.h"#include "smurfcfg.h"#include "sequencer.h"#include "wavetable.h"#include "uiface.h"#include "util.h"#include "i18n.h"static gint uipiano_parse_smurfcfg_octkeys (gchar *str, guint **keys);static void uipiano_set_bank_dummy (gint chan, gint bank);static void uipiano_set_preset_dummy (gint chan, gint preset);static void uipiano_cb_note_on (Piano * piano, guint keynum);static void uipiano_cb_note_off (Piano * piano, guint keynum);static void uipiano_cb_control_selection_done (GtkWidget * menu);static void uipiano_cb_control_value_changed (GtkWidget * adj, GtkWidget *opmenu);static void uipiano_update_spin_button (gint ctrlindex);static void uipiano_chan_value_changed (GtkAdjustment *adj, GtkWidget *spb);static void uipiano_bank_value_changed (GtkAdjustment *adj, GtkWidget *spb);static void uipiano_pset_value_changed (GtkAdjustment *adj, GtkWidget *spb);GtkWidget *uipiano_widg;static gboolean uipiano_actvkeys[128]; /* active piano widget keys */static gint uipiano_adj_changed_handler; /* ctrl changed signal handler id */gint uipiano_chan = 0; /* midi channel of virtual keyboard (starts with 0) *//* default key table */guint uipiano_default_keytable[] ={ /* lower keyboard */ GDK_z, GDK_s, GDK_x, GDK_d, GDK_c, GDK_v, GDK_g, GDK_b, GDK_h, GDK_n, GDK_j, GDK_m, GDK_comma, GDK_l, GDK_period, GDK_semicolon, GDK_slash, /* upper keyboard */ GDK_q, GDK_2, GDK_w, GDK_3, GDK_e, GDK_r, GDK_5, GDK_t, GDK_6, GDK_y, GDK_7, GDK_u, GDK_i, GDK_9, GDK_o, GDK_0, GDK_p, GDK_bracketleft, GDK_equal, GDK_bracketright};/* piano keytable stored here */guint uipiano_keytable[UIPIANO_TOTAL_NUMKEYS];typedef struct _MidiCtrlParms { gchar *name; /* name of MIDI control */ gint lo; /* lowest value */ gint hi; /* highest value */ gint def; /* default */ void (*func)(gint ch, gint val); /* function for setting this control */}MidiCtrlParms;/* --- ! Update if more controls are added to uipiano_ctrl_parms ! --- */enum { UIMIDI_VOLUME, UIMIDI_VELOCITY_ON, UIMIDI_VELOCITY_OFF, UIMIDI_REVERB, UIMIDI_CHORUS, UIMIDI_OCTAVE, UIMIDI_BEND_RANGE, UIMIDI_BANK, UIMIDI_PSET, UIMIDI_CTRL_COUNT };static const MidiCtrlParms uipiano_ctrl_parms[] = { { N_("Volume"), 0, 127, 100, seq_main_volume }, { N_("Velocity On"), 0, 127, 127, NULL }, { N_("Velocity Off"), 0, 127, 127, NULL }, { N_("Reverb"), 0, 127, 0, seq_reverb }, { N_("Chorus"), 0, 127, 0, seq_chorus }, { N_("Octave"), 0, 10, 3, NULL }, { N_("Bend Range"), 0, 127, 2, seq_pitch_bend_range }, { NULL, 0, 127, 0, uipiano_set_bank_dummy }, /* Bank control */ { NULL, 0, 127, 0, uipiano_set_preset_dummy } /* Preset control */};/* 16 arrays (one for each MIDI channel) of integer MIDI control values, [16][UIMIDI_CTRL_COUNT] */static gint (*uipiano_ctrl_vals)[16][UIMIDI_CTRL_COUNT];voiduipiano_create (void){ gint i, c; gchar *s; guint *keyvals; guint *srcvals; /* initialize piano key table low octave */ s = smurfcfg_get_val (SMURFCFG_PIANO_LOWOCTKEYS)->v_string; c = uipiano_parse_smurfcfg_octkeys (s, &keyvals); if (c == UIPIANO_LOW_NUMKEYS) srcvals = keyvals; /* if smurf config variable contains valid # of keys */ else srcvals = uipiano_default_keytable; /* smurfcfg not valid, use default */ for (i = 0; i < UIPIANO_LOW_NUMKEYS; i++) /* copy keys to key table */ uipiano_keytable[i] = srcvals[i]; if (c) g_free (keyvals); /* initialize piano key table hi octave */ s = smurfcfg_get_val (SMURFCFG_PIANO_HIOCTKEYS)->v_string; c = uipiano_parse_smurfcfg_octkeys (s, &keyvals); if (c == UIPIANO_HI_NUMKEYS) srcvals = keyvals; /* if smurf config variable contains valid # of keys */ else /* smurfcfg not valid, use default */ srcvals = &uipiano_default_keytable[UIPIANO_LOW_NUMKEYS]; for (i = 0; i < UIPIANO_HI_NUMKEYS; i++) /* copy keys to key table */ uipiano_keytable[i + UIPIANO_LOW_NUMKEYS] = srcvals[i]; if (c) g_free (keyvals); /* create the piano widget */ for (i = 0; i < 128; i++) uipiano_actvkeys[i] = FALSE; uipiano_widg = piano_new ((gboolean *) & uipiano_actvkeys); gtk_signal_connect (GTK_OBJECT (uipiano_widg), "note-on", GTK_SIGNAL_FUNC (uipiano_cb_note_on), NULL); gtk_signal_connect (GTK_OBJECT (uipiano_widg), "note-off", GTK_SIGNAL_FUNC (uipiano_cb_note_off), NULL);}/* parses a smurfcfg octave keys string (key names seperated by commas) INPUT: str is the string to parse, keys gets a pointer to an array of unsigned integer key values which should be free'd when no longer needed RETURNS: # of key names parsed or 0 on error*/static gintuipiano_parse_smurfcfg_octkeys (gchar *str, guint **keys){ gchar **keynames; guint *keyvals; gint i; /* allocate for array of maximum number of expected keys */ keyvals = g_malloc (SMURFCFG_PIANO_HIOCTKEYS * sizeof (guint)); keynames = g_strsplit (str, ",", SMURFCFG_PIANO_HIOCTKEYS); i = 0; while (keynames[i]) { keyvals[i] = gdk_keyval_from_name (keynames[i]); if (keyvals[i] == GDK_VoidSymbol) /* invalid keyname? */ { g_free (keyvals); g_strfreev (keynames); return (0); } i++; } g_strfreev (keynames); if (i) *keys = keyvals; else g_free (keyvals); return (i);}/* composes a smurfcfg key name string INPUT: keyvals is an array of unsigned integer key values, keycount is the # of keys RET: pointer to key names string or NULL (string should be free'd)*/gchar *uipiano_encode_smurfcfg_octkeys (guint *keyvals, gint keycount){ gchar **keynames; gchar *s; gint i; /* allocate for array of key name strings */ keynames = g_malloc ((keycount + 1) * sizeof (gchar *)); for (i = 0; i < keycount; i++) /* loop over each key */ { keynames[i] = gdk_keyval_name (keyvals[i]); /* get key name */ if (!keynames[i]) /* if no key name for key, fail */ { g_free (keynames); return (NULL); } } keynames[keycount] = NULL; s = g_strjoinv (",", keynames); /* create the comma delimited key string */ g_free (keynames); return (s);}voiduipiano_set_chan (gint chan){ GtkWidget *widg; GtkAdjustment *radj; gint ndx; uipiano_chan = chan - 1; /* uipiano_chan starts at 0 */ /* update current control value for new channel */ widg = gtk_object_get_data (GTK_OBJECT (ui_main_window), "OPTctrl"); UTIL_OPMENU_INDEX (ndx, widg); uipiano_update_spin_button (ndx); /* update Bank and Preset spin buttons */ widg = gtk_object_get_data (GTK_OBJECT (ui_main_window), "SPBbank"); radj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widg)); gtk_signal_handler_block_by_func (GTK_OBJECT (radj), uipiano_bank_value_changed,widg); gtk_spin_button_set_value (GTK_SPIN_BUTTON (widg), (float)((*uipiano_ctrl_vals) [uipiano_chan][UIMIDI_BANK])); gtk_signal_handler_unblock_by_func (GTK_OBJECT (radj), uipiano_bank_value_changed, widg); widg = gtk_object_get_data (GTK_OBJECT (ui_main_window), "SPBpset"); radj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widg)); gtk_signal_handler_block_by_func (GTK_OBJECT (radj), uipiano_pset_value_changed,widg); gtk_spin_button_set_value (GTK_SPIN_BUTTON (widg), (float)((*uipiano_ctrl_vals) [uipiano_chan][UIMIDI_PSET])); gtk_signal_handler_unblock_by_func (GTK_OBJECT (radj), uipiano_pset_value_changed, widg);}voiduipiano_set_bank (gint bank){ GtkWidget *widg; GtkAdjustment *adj; seq_set_bank (uipiano_chan, bank); (*uipiano_ctrl_vals)[uipiano_chan][UIMIDI_BANK] = bank; widg = gtk_object_get_data (GTK_OBJECT (ui_main_window), "SPBbank"); adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widg)); gtk_signal_handler_block_by_func (GTK_OBJECT (adj), uipiano_bank_value_changed, widg); gtk_spin_button_set_value (GTK_SPIN_BUTTON (widg), (float)bank); gtk_signal_handler_unblock_by_func (GTK_OBJECT (adj), uipiano_bank_value_changed, widg);}voiduipiano_set_preset (gint preset){ GtkWidget *widg;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -