📄 uif_wavegen.c
字号:
/*================================================================== * uif_wavegen.c - Waveform generation user interface * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * Some stuff ripped from GTK+ file gtkgamma.c * * 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_wavegen.h"#include "uif_sftree.h"#include "glade_interface.h"#include "pcm.h"#include "smurfcfg.h"#include "sample.h"#include "sfundo.h"#include "sfdofunc.h"#include "util.h"#include "i18n.h"#include "widgets/wavegen.h"#define UIWAVGEN_DEFAULT_SAMPLES 400#define UIWAVGEN_UPDATE_INTERVAL 100 /* play curve update interval (in ms) */enum{ LINEAR, SPLINE, FREE, RESET, NUM_XPMS }; /* xpm enums */static const char *xpm[][27] = { /* spline: */ { /* width height ncolors chars_per_pixel */ "16 16 4 1", /* colors */ ". c None", "B c #000000", "+ c #BC2D2D", "r c #FF0000", /* pixels */ "..............BB", ".........rrrrrrB", ".......rr.......", ".....B+.........", "....BBB.........", "....+B..........", "....r...........", "...r............", "...r............", "..r.............", "..r.............", ".r..............", ".r..............", ".r..............", "B+..............", "BB.............."}, /* linear: */ { /* width height ncolors chars_per_pixel */ "16 16 5 1", /* colors */ ". c None", /* transparent */ "B c #000000", "' c #7F7F7F", "+ c #824141", "r c #FF0000", /* pixels */ "..............BB", "..............+B", "..............r.", ".............r..", ".............r..", "....'B'.....r...", "....BBB.....r...", "....+B+....r....", "....r.r....r....", "...r...r..r.....", "...r...r..r.....", "..r.....rB+.....", "..r.....BBB.....", ".r......'B'.....", "B+..............", "BB.............."}, /* free: */ { /* width height ncolors chars_per_pixel */ "16 16 2 1", /* colors */ ". c None", "r c #FF0000", /* pixels */ "................", "................", "......r.........", "......r.........", ".......r........", ".......r........", ".......r........", "........r.......", "........r.......", "........r.......", ".....r...r.rrrrr", "....r....r......", "...r.....r......", "..r.......r.....", ".r........r.....", "r..............."}, /* reset: */ { /* width height ncolors chars_per_pixel */ "16 16 4 1", /* colors */ ". c None", "B c #000000", "+ c #824141", "r c #FF0000", /* pixels */ "................", "................", "................", "................", "................", "................", ".B............B.", "BBB+rrrrrrrr+BBB", ".B............B.", "................", "................", "................", "................", "................", "................", "................"}};static void uiwavgen_cb_curvetype_button (GtkWidget * btn, gint num);static void uiwavgen_cb_reset_curve (GtkWidget * btn);#if 0static void uiwavgen_cb_spbtn_value_changed (GtkAdjustment *adj, GtkWidget *btn);static void uiwavgen_play (void);static gint uiwavgen_pcm_play_callback (gint count, void *buf);static gboolean uiwavgen_update_play_buffer (void);#endifGtkWidget *uiwavgen_win = NULL;GtkWidget *uiwavgen_curve = NULL;/* GTK_CURVE_TYPE_(SPLINE|LINEAR|FREE) */static gint uiwavgen_type = GTK_CURVE_TYPE_SPLINE;#if 0static guint uiwavgen_samples = UIWAVGEN_DEFAULT_SAMPLES;static gint16 *uiwavgen_playbuf = NULL;static guint uiwavgen_playbuf_size; /* size of play buffer (in samples) */static guint uiwavgen_playbuf_curpos; /* current position (in samples) */static guint uiwavgen_timeout_id;#endifvoiduiwavgen_create (void){ GtkWidget *vbox; GtkWidget *box1, *box2; GtkWidget *HBXicon; GtkWidget *frame; // GtkWidget *lbl; GtkWidget *btn; GtkWidget *pixmapwid; // GtkObject *adj; GtkStyle *style; GdkPixmap *pixmap; GdkBitmap *mask; gint i; if (uiwavgen_win) { gtk_widget_show (uiwavgen_win); gdk_window_raise (GTK_WIDGET (uiwavgen_win)->window); return; } uiwavgen_win = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (uiwavgen_win), _("Waveform Generator")); gtk_window_set_default_size (GTK_WINDOW (uiwavgen_win), 400, 300); gtk_window_set_policy (GTK_WINDOW (uiwavgen_win), TRUE, TRUE, FALSE); vbox = gtk_vbox_new (FALSE, 2); gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (uiwavgen_win), vbox); uiwavgen_curve = wavegen_new (); gtk_widget_show (uiwavgen_curve); gtk_box_pack_start (GTK_BOX (vbox), uiwavgen_curve, TRUE, TRUE, 0); wavegen_set_range (WAVEGEN (uiwavgen_curve), 0, 1, -32768, 32767); frame = gtk_frame_new (NULL); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); box1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (box1); gtk_container_add (GTK_CONTAINER (frame), box1); gtk_container_set_border_width (GTK_CONTAINER (box1), 2); HBXicon = gtk_hbox_new (FALSE, 0); gtk_widget_show (HBXicon); gtk_box_pack_start (GTK_BOX (box1), HBXicon, FALSE, FALSE, 0); box2 = gtk_hbox_new (FALSE, 4); gtk_widget_show (box2); gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0); btn = gtk_button_new_with_label (_("Close")); gtk_widget_show (btn); gtk_box_pack_end (GTK_BOX (box2), btn, FALSE, FALSE, 0); gtk_signal_connect_object (GTK_OBJECT (btn), "clicked", GTK_SIGNAL_FUNC (gtk_widget_hide), GTK_OBJECT (uiwavgen_win)); gtk_widget_show (uiwavgen_win); wavegen_reset (WAVEGEN (uiwavgen_curve)); btn = NULL; /* first button has no group */ for (i = 0; i < 3; i++) { btn = gtk_radio_button_new_from_widget ((GtkRadioButton *) btn); /* don't draw indicator */ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (btn), FALSE); gtk_widget_show (btn); gtk_signal_connect (GTK_OBJECT (btn), "toggled", (GtkSignalFunc) uiwavgen_cb_curvetype_button, GINT_TO_POINTER (i)); style = gtk_widget_get_style (btn); pixmap = gdk_pixmap_create_from_xpm_d (uiwavgen_win->window, &mask, &style->bg[GTK_STATE_NORMAL], (gchar **) xpm[i]); pixmapwid = gtk_pixmap_new (pixmap, mask); gtk_widget_show (pixmapwid); gtk_container_add (GTK_CONTAINER (btn), pixmapwid); gtk_box_pack_start (GTK_BOX (HBXicon), btn, FALSE, FALSE, 0); } btn = gtk_button_new (); gtk_widget_show (btn); gtk_signal_connect (GTK_OBJECT (btn), "clicked", (GtkSignalFunc) uiwavgen_cb_reset_curve, NULL); style = gtk_widget_get_style (btn); pixmap = gdk_pixmap_create_from_xpm_d (uiwavgen_win->window, &mask, &style->bg[GTK_STATE_NORMAL], (gchar **) xpm[3]); pixmapwid = gtk_pixmap_new (pixmap, mask); gtk_widget_show (pixmapwid); gtk_container_add (GTK_CONTAINER (btn), pixmapwid); gtk_box_pack_start (GTK_BOX (HBXicon), btn, FALSE, FALSE, 8);/* currently disabled */#if 0 btn = gtk_button_new_with_label (_("Play")); gtk_widget_show (btn); gtk_box_pack_start (GTK_BOX (HBXicon), btn, FALSE, FALSE, 8); gtk_signal_connect (GTK_OBJECT (btn), "clicked", GTK_SIGNAL_FUNC (uiwavgen_play), NULL); lbl = gtk_label_new (_("Samples:")); gtk_widget_show (lbl); gtk_box_pack_start (GTK_BOX (HBXicon), lbl, FALSE, FALSE, 8); adj = gtk_adjustment_new ((gfloat)UIWAVGEN_DEFAULT_SAMPLES, 32.0, 60000.0, 1.0, 20.0, 0.0); btn = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 0.5, 0); gtk_widget_set_usize (btn, 60, -1); gtk_widget_show (btn); gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiwavgen_cb_spbtn_value_changed), btn); gtk_box_pack_start (GTK_BOX (HBXicon), btn, FALSE, FALSE, 0);#endif}static voiduiwavgen_cb_curvetype_button (GtkWidget * btn, gint num){ switch (num) { case 0: uiwavgen_type = GTK_CURVE_TYPE_SPLINE; break; case 1: uiwavgen_type = GTK_CURVE_TYPE_LINEAR; break; default: uiwavgen_type = GTK_CURVE_TYPE_FREE; break; } wavegen_set_curve_type (WAVEGEN (uiwavgen_curve), uiwavgen_type);}static voiduiwavgen_cb_reset_curve (GtkWidget * btn){ wavegen_reset (WAVEGEN (uiwavgen_curve));}#if 0static voiduiwavgen_cb_spbtn_value_changed (GtkAdjustment *adj, GtkWidget *btn){ uiwavgen_samples = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (btn));}#endifvoiduiwavgen_new_sample (void){ GtkWidget *samwin; SFItemID itemid; GtkCTreeNode *node; if (!uiwavgen_win) { uiwavgen_create (); util_quick_popup (_("A waveform must be created first"), NULL); return; } if (!(itemid = sftree_get_selection_single ())) return; if (!(node = SFTREE_LOOKUP_ITEMID (itemid))) return; /* get id of sound font tree item */ node = sftree_find_parent_by_type (node, NODE_SFONT); itemid = SFTREE_NODE_REF (node)->itemid; samwin = create_wavegen_newsam (); gtk_widget_show (samwin); gtk_object_set_data (GTK_OBJECT (samwin), "itemid", GINT_TO_POINTER (itemid));}voiduiwavgen_cb_new_sample_okay (GtkWidget *btn, GtkWidget *samwin){ SFItemID itemid; GtkCTreeNode *node; UISFont *uisf; SFSample *sam; GSList *p; GtkWidget *widg; gchar *name; gint size, looppad, totalsize; /* sizes are in samples */ gboolean loop; gint16 *buf; itemid = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (samwin), "itemid")); node = SFTREE_LOOKUP_ITEMID (itemid); if (!node) /* did sfont get closed on us? */ { gtk_widget_destroy (samwin); return; } uisf = SFTREE_SFNODE_UISF (node); /* get UI sfont structure */ widg = gtk_object_get_data (GTK_OBJECT (samwin), "ENname"); name = gtk_entry_get_text (GTK_ENTRY (widg)); if (!strlen (name)) { util_quick_popup (_("Sample name is required"), NULL); return; } if (sfont_find_sample (uisf->sf, name, NULL)) { util_quick_popup (_("A sample already exists with that name"), NULL); return; } widg = gtk_object_get_data (GTK_OBJECT (samwin), "SPBsize"); size = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widg)); widg = gtk_object_get_data (GTK_OBJECT (samwin), "CHKloop"); loop = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widg)); if (loop) /* set up loop on generated sample? */ { looppad = smurfcfg_get_val (SMURFCFG_SAM_MINLOOPPAD)->v_int; totalsize = size + looppad * 2; } else totalsize = size; buf = g_malloc (totalsize * sizeof (gint16)); uiwavgen_get_curve_data (buf, size); if (loop) /* if loop, then duplicate 2 * min loop padding sample data */ memcpy (&buf[size], buf, 2 * looppad * sizeof (gint16)); sam = sam_create_sample (name, 44100, buf, totalsize, uisf->sf); g_free (buf); if (loop) /* set up loop points? */ { sam->loopstart = looppad; sam->loopend = size + looppad; } p = g_slist_find (uisf->sf->sample, sam); node = sftree_add_sample (p, uisf->nodes, SFTREE_NODE_APPEND); sfdo_group (_("Generate sample")); /* tell sfundo about our new item */ dofunc_noitem_save (SFTREE_NODE_REF (node)->itemid); sfdo_done (); gtk_widget_destroy (samwin);}/* get an audio representation of the waveform, given sample length */voiduiwavgen_get_curve_data (gint16 * buf, gint size){ float *fbuf; gint i; fbuf = g_malloc (sizeof (float) * size); wavegen_get_vector (WAVEGEN (uiwavgen_curve), size, fbuf); for (i = 0; i < size; i++) buf[i] = fbuf[i]; g_free (fbuf);}/* disabled until we have PCM support */#if 0static voiduiwavgen_play (void){ if (!uiwavgen_curve) return; uiwavgen_update_play_buffer (); pcm_play (16, TRUE, 1, 44100, uiwavgen_pcm_play_callback); uiwavgen_timeout_id = g_timeout_add (UIWAVGEN_UPDATE_INTERVAL, (GSourceFunc)uiwavgen_update_play_buffer, NULL);}/* pcm_play callback (supplies audio data) */static gintuiwavgen_pcm_play_callback (gint count, void *buf){ gint i = count; while (i > 0) { *(((gint16 *)buf)++) = uiwavgen_playbuf [uiwavgen_playbuf_curpos++]; if (uiwavgen_playbuf_curpos >= uiwavgen_playbuf_size) uiwavgen_playbuf_curpos = 0; i--; } return (count);}/* updates the wavegen audio play buffer (if needed) */static gbooleanuiwavgen_update_play_buffer (void){ /* play buffer needs updating? */ if (!(((Wavegen *)uiwavgen_curve)->changed || uiwavgen_playbuf_size != uiwavgen_samples)) return (TRUE); /* did play buffer change size? */ if (uiwavgen_playbuf && uiwavgen_playbuf_size != uiwavgen_samples) { g_free (uiwavgen_playbuf); uiwavgen_playbuf = NULL; uiwavgen_playbuf_curpos = 0; } uiwavgen_playbuf_size = uiwavgen_samples; /* allocate play buffer if not already */ if (!uiwavgen_playbuf) uiwavgen_playbuf = g_malloc (uiwavgen_playbuf_size * sizeof (gint16)); /* fill play buffer with curve data */ uiwavgen_get_curve_data (uiwavgen_playbuf, uiwavgen_playbuf_size); return (TRUE);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -