2 terminatorX - realtime audio scratching software
3 Copyright (C) 1999, 2000 Alexander König
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 Description: This implements the gtk+ GUI for the virtual turntable
22 class implemented in tX_vtt.cc. This code is not in tX_vtt.cc
23 for mainly to keep the GUI code divided from the audio-rendering
24 code and as gtk+ callback to C++ method call wrapper.
29 #include "tX_vttgui.h"
31 #include "tX_widget.h"
32 #include "tX_mastergui.h"
33 #include "tX_loaddlg.h"
34 #include "tX_prelis.h"
35 #include "tX_pbutton.h"
36 #include "tX_global.h"
37 #include "tX_extdial.h"
39 #include "tX_ladspa.h"
50 #define WID_DYN TRUE, TRUE, 0
51 #define WID_FIX FALSE, FALSE, 0
53 #define FILENAME_BUTTON_MAX 20
55 void nicer_filename(char *dest, char *source)
61 fn=strrchr(source, '/');
67 fn=strrchr(temp, '.');
70 if (strlen(temp) > FILENAME_BUTTON_MAX)
72 temp[FILENAME_BUTTON_MAX-3]='.';
73 temp[FILENAME_BUTTON_MAX-2]='.';
74 temp[FILENAME_BUTTON_MAX-1]='.';
75 temp[FILENAME_BUTTON_MAX]=0;
80 GtkSignalFunc name_changed(GtkWidget *wid, vtt_class *vtt)
82 vtt->set_name(gtk_entry_get_text(GTK_ENTRY(wid)));
85 GtkSignalFunc volume_changed(GtkWidget *wid, vtt_class *vtt)
87 vtt->sp_volume.receive_gui_value(2.0-GTK_ADJUSTMENT(wid)->value);
90 GtkSignalFunc pitch_changed(GtkWidget *wid, vtt_class *vtt)
92 vtt->sp_pitch.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
95 GtkSignalFunc trigger_prelis(GtkWidget *w)
99 fs=GTK_FILE_SELECTION(gtk_widget_get_toplevel(w));
101 prelis_start(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
105 void cancel_load_file(GtkWidget *wid, vtt_class *vtt)
109 vtt->gui.file_dialog=NULL;
110 if (vtt->gui.fs) gtk_widget_destroy(GTK_WIDGET(vtt->gui.fs));
113 int quit_load_file(GtkWidget *wid, vtt_class *vtt)
115 //vtt->gui.file_dialog=NULL;
120 char global_filename_buffer[PATH_MAX];
122 void load_part(char *newfile, vtt_class *vtt)
127 ld_create_loaddlg(TX_LOADDLG_MODE_SINGLE, 1);
128 ld_set_filename(newfile);
130 ret = vtt->load_file(newfile);
137 case TX_AUDIO_ERR_ALLOC:
138 tx_note("Error loading file: failed to allocate memory");
140 case TX_AUDIO_ERR_PIPE_READ:
141 tx_note("Error loading file: broken pipe (File not supported/corrupt?)");
143 case TX_AUDIO_ERR_SOX:
144 tx_note("Error loading file: couldn't execute sox");
146 case TX_AUDIO_ERR_MPG123:
147 tx_note("Error loading file: couldn't execute mpg123");
149 case TX_AUDIO_ERR_WAV_NOTFOUND:
150 tx_note("Error loading file: file not found");
152 case TX_AUDIO_ERR_NOT_16BIT:
153 tx_note("Error loading file: RIFF/WAV is not 16 Bit.");
155 case TX_AUDIO_ERR_NOT_MONO:
156 tx_note("Error loading file: RIFF/WAV is not mono");
158 case TX_AUDIO_ERR_WAV_READ:
159 tx_note("Error loading file: RIFF/WAV corrupt?");
161 case TX_AUDIO_ERR_NOT_SUPPORTED:
162 tx_note("Error loading file: filetype not supported.");
165 tx_note("OOPS: An unknown error occured - This shouldn't happen :(");
170 nicer_filename(global_filename_buffer, newfile);
171 // strcpy(global_filename_buffer, fn);
173 gtk_label_set(GTK_LABEL(GTK_BUTTON(vtt->gui.file)->child), global_filename_buffer);
177 GtkSignalFunc do_load_file(GtkWidget *wid, vtt_class *vtt)
180 char newfile[PATH_MAX];
181 char buffer[1024]="Couldn't open loop file: ";
182 char fn[FILENAME_BUTTON_MAX];
185 unsigned int newsize;
189 strcpy(newfile, gtk_file_selection_get_filename(GTK_FILE_SELECTION(vtt->gui.fs)));
190 gtk_widget_destroy(GTK_WIDGET(vtt->gui.fs));
192 load_part(newfile, vtt);
194 vtt->gui.file_dialog=NULL;
197 GtkSignalFunc drop_file(GtkWidget *widget, GdkDragContext *context,
198 gint x, gint y, GtkSelectionData *selection_data,
199 guint info, guint time, vtt_class *vtt)
201 char filename[PATH_MAX];
206 strncpy(filename, (char *) selection_data->data, (size_t) selection_data->length);
207 filename[selection_data->length]=0;
209 fn = strchr (filename, '\r');
212 fn = strchr (filename, ':');
213 if (fn) fn++; else fn=(char *) selection_data->data;
219 GtkSignalFunc load_file(GtkWidget *wid, vtt_class *vtt)
223 if (vtt->gui.file_dialog)
226 gdk_window_raise(vtt->gui.file_dialog);
230 sprintf(buffer, "Select Audio File for %s", vtt->name);
231 vtt->gui.fs=gtk_file_selection_new(buffer);
233 if (strlen(vtt->filename) > 0)
235 gtk_file_selection_set_filename(GTK_FILE_SELECTION(vtt->gui.fs), vtt->filename);
238 gtk_widget_show(GTK_WIDGET(vtt->gui.fs));
240 vtt->gui.file_dialog=vtt->gui.fs->window;
242 gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(vtt->gui.fs)->ok_button), "clicked", GTK_SIGNAL_FUNC(do_load_file), vtt);
243 gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(vtt->gui.fs)->cancel_button), "clicked", GTK_SIGNAL_FUNC (cancel_load_file), vtt);
244 gtk_signal_connect (GTK_OBJECT(vtt->gui.fs), "delete-event", GTK_SIGNAL_FUNC(quit_load_file), vtt);
245 gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(vtt->gui.fs)->file_list), "select_row", GTK_SIGNAL_FUNC(trigger_prelis), vtt->gui.fs);
249 GtkSignalFunc delete_vtt(GtkWidget *wid, vtt_class *vtt)
251 if (audioon) tx_note("Sorry, you'll have to stop playback first.");
256 GtkSignalFunc edit_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
258 char command[2*PATH_MAX];
260 if (vtt->samples_in_buffer == 0)
262 tx_note("Nothing to edit.");
265 if (strlen(globals.file_editor)>0)
267 sprintf(command, "%s \"%s\" &", globals.file_editor, vtt->filename);
268 system(command); /*) tx_note("Failed to run the soundfile editor."); */
272 tx_note("No soundfile editor configured.");
276 GtkSignalFunc reload_vtt_buffer(GtkWidget *wid, vtt_class *vtt)
278 char reload_buffer[PATH_MAX];
280 while (gtk_events_pending()) gtk_main_iteration();
282 // puts(vtt->filename);
283 if (vtt->samples_in_buffer > 0)
285 strcpy(reload_buffer, vtt->filename);
286 load_part(reload_buffer, vtt);
288 else tx_note("Nothing to reload.");
291 GtkSignalFunc clone_vtt(GtkWidget *wid, vtt_class *vtt)
296 GtkSignalFunc trigger_vtt(GtkWidget *wid, vtt_class *vtt)
298 vtt->sp_trigger.receive_gui_value((float) 1.0);
301 GtkSignalFunc stop_vtt(GtkWidget *wid, vtt_class *vtt)
303 vtt->sp_trigger.receive_gui_value((float) 0.0);
306 GtkSignalFunc autotrigger_toggled(GtkWidget *wid, vtt_class *vtt)
308 vtt->set_autotrigger(GTK_TOGGLE_BUTTON(wid)->active);
311 GtkSignalFunc loop_toggled(GtkWidget *wid, vtt_class *vtt)
313 vtt->sp_loop.receive_gui_value(GTK_TOGGLE_BUTTON(wid)->active);
316 GtkSignalFunc lp_enabled(GtkWidget *wid, vtt_class *vtt)
318 vtt->sp_lp_enable.receive_gui_value(GTK_TOGGLE_BUTTON(wid)->active);
321 GtkSignalFunc lp_gain_changed(GtkWidget *wid, vtt_class *vtt)
323 vtt->sp_lp_gain.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
326 GtkSignalFunc lp_reso_changed(GtkWidget *wid, vtt_class *vtt)
328 vtt->sp_lp_reso.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
331 GtkSignalFunc lp_freq_changed(GtkWidget *wid, vtt_class *vtt)
333 vtt->sp_lp_freq.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
336 GtkSignalFunc ec_enabled(GtkWidget *wid, vtt_class *vtt)
338 vtt->sp_ec_enable.receive_gui_value(GTK_TOGGLE_BUTTON(wid)->active);
341 GtkSignalFunc ec_length_changed(GtkWidget *wid, vtt_class *vtt)
343 vtt->sp_ec_length.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
346 GtkSignalFunc ec_feedback_changed(GtkWidget *wid, vtt_class *vtt)
348 vtt->sp_ec_feedback.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
351 GtkSignalFunc master_setup(GtkWidget *wid, vtt_class *vtt)
353 vtt->set_sync_master(GTK_TOGGLE_BUTTON(wid)->active);
356 GtkSignalFunc client_setup(GtkWidget *wid, vtt_class *vtt)
360 client=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(vtt->gui.sync_client));
361 vtt->sp_sync_client.receive_gui_value(client);
364 GtkSignalFunc client_setup_number(GtkWidget *wid, vtt_class *vtt)
368 cycles=(int) GTK_ADJUSTMENT(vtt->gui.cycles)->value;
370 vtt->sp_sync_cycles.receive_gui_value(cycles);
374 GtkSignalFunc control_changed(GtkWidget *wid, vtt_class *vtt)
377 vtt_gui *g=&vtt->gui;
379 if (GTK_TOGGLE_BUTTON(g->x_scratch)->active) x=CONTROL_SCRATCH;
380 else if (GTK_TOGGLE_BUTTON(g->x_volume)->active) x=CONTROL_VOLUME;
381 else if (GTK_TOGGLE_BUTTON(g->x_lp_cutoff)->active) x=CONTROL_CUTOFF;
382 else if (GTK_TOGGLE_BUTTON(g->x_ec_feedback)->active) x=CONTROL_FEEDBACK;
383 else if (GTK_TOGGLE_BUTTON(g->x_nothing)->active) x=CONTROL_NOTHING;
385 if (GTK_TOGGLE_BUTTON(g->y_scratch)->active) y=CONTROL_SCRATCH;
386 else if (GTK_TOGGLE_BUTTON(g->y_volume)->active) y=CONTROL_VOLUME;
387 else if (GTK_TOGGLE_BUTTON(g->y_lp_cutoff)->active) y=CONTROL_CUTOFF;
388 else if (GTK_TOGGLE_BUTTON(g->y_ec_feedback)->active) y=CONTROL_FEEDBACK;
389 else if (GTK_TOGGLE_BUTTON(g->y_nothing)->active) y=CONTROL_NOTHING;
391 vtt->set_controls(x,y);
395 void vg_display_xcontrol(vtt_class *vtt)
401 strcpy(buffer, vtt->x_par->get_name());
402 if (strlen(buffer)>35)
409 gtk_label_set(GTK_LABEL(GTK_BUTTON(vtt->gui.x_control)->child), buffer);
413 gtk_label_set(GTK_LABEL(GTK_BUTTON(vtt->gui.x_control)->child), "Nothing");
417 void vg_display_ycontrol(vtt_class *vtt)
423 strcpy(buffer, vtt->y_par->get_name());
424 if (strlen(buffer)>26)
431 gtk_label_set(GTK_LABEL(GTK_BUTTON(vtt->gui.y_control)->child), buffer);
435 gtk_label_set(GTK_LABEL(GTK_BUTTON(vtt->gui.y_control)->child), "Nothing");
439 GtkSignalFunc vg_xcontrol_dis(GtkWidget *wid, vtt_class *vtt)
441 vtt->set_x_input_parameter(NULL);
444 GtkSignalFunc vg_ycontrol_dis(GtkWidget *wid, vtt_class *vtt)
446 vtt->set_y_input_parameter(NULL);
449 GtkSignalFunc vg_xcontrol_set(GtkWidget *wid, tX_seqpar *sp)
451 vtt_class *vtt=(vtt_class *) sp->vtt;
452 vtt->set_x_input_parameter(sp);
455 GtkSignalFunc vg_ycontrol_set(GtkWidget *wid, tX_seqpar *sp)
457 vtt_class *vtt=(vtt_class *) sp->vtt;
458 vtt->set_y_input_parameter(sp);
461 void vg_control_menu_popup(vtt_class *vtt, int axis)
463 list <tX_seqpar *> :: iterator sp;
464 vtt_gui *g=&vtt->gui;
467 if (g->par_menu) gtk_object_destroy(GTK_OBJECT(g->par_menu));
468 g->par_menu=gtk_menu_new();
470 item = gtk_menu_item_new_with_label("Nothing");
471 gtk_menu_append(GTK_MENU(g->par_menu), item);
472 gtk_widget_show(item);
473 if (axis) gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(vg_xcontrol_dis), vtt);
474 else gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(vg_ycontrol_dis), vtt);
477 for (sp=tX_seqpar::all.begin(); sp!=tX_seqpar::all.end(); sp++)
479 if (((*sp)->is_mappable) && ((*sp)->vtt) == (void*) vtt)
481 item = gtk_menu_item_new_with_label((*sp)->get_name());
482 gtk_menu_append(GTK_MENU(g->par_menu), item);
483 gtk_widget_show(item);
484 if (axis) gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(vg_xcontrol_set), (void*) (*sp));
485 else gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(vg_ycontrol_set), (void*) (*sp));
488 gtk_menu_popup (GTK_MENU(g->par_menu), NULL, NULL, NULL, NULL, 0, 0);
491 GtkSignalFunc vg_xcontrol_popup(GtkWidget *wid, vtt_class *vtt)
493 vg_control_menu_popup(vtt, 1);
496 GtkSignalFunc vg_ycontrol_popup(GtkWidget *wid, vtt_class *vtt)
498 vg_control_menu_popup(vtt, 0);
501 static vtt_class * fx_vtt;
503 GtkSignalFunc new_effect(GtkWidget *wid, LADSPA_Plugin *plugin)
505 fx_vtt->add_effect(plugin);
508 GtkSignalFunc fx_button_pressed(GtkWidget *wid, vtt_class *vtt)
510 vtt_gui *g=&vtt->gui;
513 LADSPA_Plugin *plugin;
515 char oldfile[1024]="";
518 fx_vtt=vtt; /* AAAAARGH - Long live ugly code */
520 if (g->ladspa_menu) gtk_object_destroy(GTK_OBJECT(g->ladspa_menu));
521 g->ladspa_menu=gtk_menu_new();
523 for (i=0; i<LADSPA_Plugin::getPluginCount(); i++)
525 plugin=LADSPA_Plugin::getPluginByIndex(i);
526 if (strcmp(plugin->get_file_name(), oldfile))
528 strcpy(oldfile, plugin->get_file_name());
529 item = gtk_menu_item_new_with_label(oldfile);
530 submenu=gtk_menu_new();
531 gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
532 gtk_menu_append(GTK_MENU(g->ladspa_menu), item);
533 gtk_widget_show(item);
535 sprintf(buffer, "%s - [%i, %s]", plugin->getName(), plugin->getUniqueID(), plugin->getLabel());
536 item=gtk_menu_item_new_with_label(buffer);
537 gtk_menu_append(GTK_MENU(submenu), item);
538 gtk_widget_show(item);
539 gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(new_effect), plugin);
542 gtk_menu_popup (GTK_MENU(g->ladspa_menu), NULL, NULL, NULL, NULL, 0, 0);
545 #define connect_entry(wid, func); gtk_signal_connect(GTK_OBJECT(g->wid), "activate", (GtkSignalFunc) func, (void *) vtt);
546 #define connect_adj(wid, func); gtk_signal_connect(GTK_OBJECT(g->wid), "value_changed", (GtkSignalFunc) func, (void *) vtt);
547 #define connect_button(wid, func); gtk_signal_connect(GTK_OBJECT(g->wid), "clicked", (GtkSignalFunc) func, (void *) vtt);
548 #define connect_press_button(wid, func); gtk_signal_connect(GTK_OBJECT(g->wid), "pressed", (GtkSignalFunc) func, (void *) vtt);
549 #define connect_rel_button(wid, func); gtk_signal_connect(GTK_OBJECT(g->wid), "released", (GtkSignalFunc) func, (void *) vtt);
551 GtkWidget *vg_create_fx_bar(vtt_class *vtt, vtt_fx *effect, int showdel);
553 void gui_connect_signals(vtt_class *vtt)
555 vtt_gui *g=&vtt->gui;
557 connect_entry(name, name_changed);
558 connect_adj(volume, volume_changed);
559 connect_button(edit, edit_vtt_buffer);
560 connect_button(reload, reload_vtt_buffer);
561 connect_adj(pitch, pitch_changed);
562 connect_button(file, load_file);
564 connect_button(del, delete_vtt);
565 // connect_button(clone, clone_vtt);
566 connect_button(trigger, trigger_vtt);
567 connect_button(stop, stop_vtt);
568 connect_button(autotrigger, autotrigger_toggled);
569 connect_button(loop, loop_toggled);
570 connect_button(sync_master, master_setup);
571 connect_button(sync_client, client_setup);
572 connect_adj(cycles, client_setup_number);
574 connect_button(x_scratch, control_changed);
575 connect_button(x_volume, control_changed);
576 connect_button(x_lp_cutoff, control_changed);
577 connect_button(x_ec_feedback, control_changed);
578 connect_button(x_nothing, control_changed);
580 connect_button(y_scratch, control_changed);
581 connect_button(y_volume, control_changed);
582 connect_button(y_lp_cutoff, control_changed);
583 connect_button(y_ec_feedback, control_changed);
584 connect_button(y_nothing, control_changed);
586 connect_button(fx_button, fx_button_pressed);
588 connect_button(lp_enable, lp_enabled);
589 connect_adj(lp_gain, lp_gain_changed);
590 connect_adj(lp_reso, lp_reso_changed);
591 connect_adj(lp_freq, lp_freq_changed);
593 connect_button(ec_enable, ec_enabled);
594 connect_adj(ec_length, ec_length_changed);
595 connect_adj(ec_feedback, ec_feedback_changed);
596 connect_button(x_control, vg_xcontrol_popup);
597 connect_button(y_control, vg_ycontrol_popup);
599 static GtkTargetEntry drop_types [] = {
600 { "text/uri-list", 0, 0}
602 static gint n_drop_types = sizeof (drop_types) / sizeof(drop_types[0]);
604 gtk_drag_dest_set (GTK_WIDGET (g->file), (GtkDestDefaults) (GTK_DEST_DEFAULT_MOTION |GTK_DEST_DEFAULT_HIGHLIGHT |GTK_DEST_DEFAULT_DROP),
605 drop_types, n_drop_types,
608 gtk_signal_connect (GTK_OBJECT (g->file), "drag_data_received",
609 GTK_SIGNAL_FUNC(drop_file), (void *) vtt);
611 gtk_drag_dest_set (GTK_WIDGET (g->display), (GtkDestDefaults) (GTK_DEST_DEFAULT_MOTION |GTK_DEST_DEFAULT_HIGHLIGHT |GTK_DEST_DEFAULT_DROP),
612 drop_types, n_drop_types,
615 gtk_signal_connect (GTK_OBJECT (g->display), "drag_data_received",
616 GTK_SIGNAL_FUNC(drop_file), (void *) vtt);
620 void build_vtt_gui(vtt_class *vtt)
625 char nice_name[FILENAME_BUTTON_MAX];
634 /* Building Audio Box */
635 g->audio_box=gtk_vbox_new(FALSE,2);
636 gtk_widget_show(g->audio_box);
638 tempbox=gtk_hbox_new(FALSE,2);
639 gtk_widget_show(tempbox);
640 gtk_box_pack_start(GTK_BOX(g->audio_box), tempbox, WID_FIX);
642 g->audio_label=gtk_label_new(vtt->name);
643 gtk_widget_show(g->audio_label);
644 gtk_box_pack_start(GTK_BOX(tempbox), g->audio_label, WID_DYN);
646 dummy=gtk_vseparator_new();
647 gtk_widget_show(dummy);
648 gtk_box_pack_start(GTK_BOX(tempbox), dummy, WID_FIX);
650 nicer_filename(nice_name, vtt->filename);
651 g->file = gtk_button_new_with_label(nice_name);
652 gtk_widget_show(g->file);
653 gui_set_tooltip(g->file, "Click here to load an audiofile into this turntable. As an alternative you may drop an audiofile over this button or the audio-data display.");
654 gtk_box_pack_start(GTK_BOX(tempbox), g->file, WID_DYN);
656 g->edit=tx_xpm_button_new(TX_ICON_EDIT, "Edit", 0);
657 gtk_widget_show(g->edit);
658 gui_set_tooltip(g->edit, "Click this button to run the soundfile editor for the audiofile loaded into this turntable. You can configure which soundfile editor to use in the Options dialog.");
659 gtk_box_pack_start(GTK_BOX(tempbox), g->edit, WID_FIX);
661 g->reload=tx_xpm_button_new(TX_ICON_RELOAD, "Reload", 0);
662 gtk_widget_show(g->reload);
663 gui_set_tooltip(g->reload, "Click here to reload the audiofile loaded into this turntable.");
664 gtk_box_pack_start(GTK_BOX(tempbox), g->reload, WID_FIX);
666 dummy=gtk_vseparator_new();
667 gtk_widget_show(dummy);
668 gtk_box_pack_start(GTK_BOX(tempbox), dummy, WID_FIX);
670 dummy=gtk_label_new("X:");
671 gtk_widget_show(dummy);
672 gtk_box_pack_start(GTK_BOX(tempbox), dummy, WID_FIX);
674 g->x_control=gtk_button_new_with_label(vtt->x_par->get_name());
675 gtk_widget_show(g->x_control);
676 gui_set_tooltip(g->x_control, "Select which parameter should be controlled for this turntable (in grab mode) by mouse motion (x-axis: left <-> right).");
677 gtk_box_pack_start(GTK_BOX(tempbox), g->x_control, WID_DYN);
679 dummy=gtk_label_new("Y:");
680 gtk_widget_show(dummy);
681 gtk_box_pack_start(GTK_BOX(tempbox), dummy, WID_FIX);
683 g->y_control=gtk_button_new_with_label(vtt->y_par->get_name());
684 gtk_widget_show(g->y_control);
685 gui_set_tooltip(g->y_control, "Select which parameter should be controlled for this turntable (in grab mode) by mouse motion (x-axis: up <-> down).");
687 gtk_box_pack_start(GTK_BOX(tempbox), g->y_control, WID_DYN);
689 g->display=gtk_tx_new(vtt->buffer, vtt->samples_in_buffer);
690 gtk_box_pack_start(GTK_BOX(g->audio_box), g->display, WID_DYN);
691 gtk_widget_show(g->display);
693 /* Building Control Box */
695 g->control_box=gtk_vbox_new(FALSE,2);
696 gtk_widget_show(g->control_box);
698 g->control_label=gtk_label_new(vtt->name);
699 gtk_widget_show(g->control_label);
700 gtk_box_pack_start(GTK_BOX(g->control_box), g->control_label, WID_FIX);
702 g->scrolled_win=gtk_scrolled_window_new (NULL, NULL);
703 gtk_container_set_border_width (GTK_CONTAINER (g->scrolled_win), 0);
704 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (g->scrolled_win),
705 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
706 gtk_widget_show(g->scrolled_win);
707 gtk_box_pack_start(GTK_BOX(g->control_box), g->scrolled_win, WID_DYN);
709 g->control_subbox=gtk_vbox_new(FALSE,0);
710 gtk_scrolled_window_add_with_viewport (
711 GTK_SCROLLED_WINDOW (g->scrolled_win), g->control_subbox);
712 gtk_widget_show(g->control_subbox);
717 tX_panel *p=new tX_panel("Main", g->control_subbox);
720 g->name = gtk_entry_new_with_max_length(256);
721 gtk_entry_set_text(GTK_ENTRY(g->name), vtt->name);
722 p->add_client_widget(g->name);
723 gui_set_tooltip(g->name, "Enter the turntable's name here.");
724 gtk_widget_set_usize(g->name, 40, g->name->requisition.height);
726 g->del=gtk_button_new_with_label("Delete");
727 gui_set_tooltip(g->del, "Click here to annihilate this turntable. All events recorded for this turntable will be erased, too.");
728 p->add_client_widget(g->del);
730 // g->show_audio=gtk_toggle_button_new_with_label("Show Audio");
731 // p->add_client_widget(g->show_audio);
733 gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
735 p=new tX_panel("Trigger", g->control_subbox);
738 g->trigger=gtk_button_new_with_label("Trigger!");
739 gui_set_tooltip(g->trigger, "Click here to trigger this turntable right now. If the audio engine is disabled this turntable will be triggerd as soon as the engine is turned on.");
740 p->add_client_widget(g->trigger);
742 g->stop=gtk_button_new_with_label("Stop.");
743 gui_set_tooltip(g->stop, "Stop this turntable's playback.");
744 p->add_client_widget(g->stop);
746 g->autotrigger=gtk_check_button_new_with_label("Auto");
747 p->add_client_widget(g->autotrigger);
748 gui_set_tooltip(g->autotrigger, "If turned on, this turntable will be automagically triggered whenever the audio engine is turned on.");
749 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->autotrigger), vtt->autotrigger);
751 g->loop=gtk_check_button_new_with_label("Loop");
752 p->add_client_widget(g->loop);
753 gui_set_tooltip(g->loop, "Enable this option to make the turntable loop the audio data.");
754 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->loop), vtt->loop);
756 g->sync_master=gtk_check_button_new_with_label("Master");
757 p->add_client_widget(g->sync_master);
758 gui_set_tooltip(g->sync_master, "Click here to make this turntable the sync-master. All turntables marked as sync-clients will be (re-)triggered in relation to the sync-master. Note that only *one* turntable can be the sync-master.");
759 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->sync_master), vtt->is_sync_master);
761 g->sync_client=gtk_check_button_new_with_label("Client");
762 p->add_client_widget(g->sync_client);
763 gui_set_tooltip(g->sync_client, "If enabled this turntable will be (re-)triggerd in relation to the sync-master turntable.");
764 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->sync_client), vtt->is_sync_client);
766 g->cycles=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->sync_cycles, 0, 10.0, 1,1,1));
767 dummy=gtk_spin_button_new(g->cycles, 1.0, 0);
768 p->add_client_widget(dummy);
769 gui_set_tooltip(dummy, "Determines how often a sync-client turntable gets triggered. 0 -> this turntable will be triggered with every trigger of the sync-master table, 1 -> the table will be triggered every 2nd master trigger and so on.");
771 gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
773 dummy=gtk_button_new_with_label("FX");
774 gtk_widget_show(dummy);
776 gui_set_tooltip(g->fx_button, "Click here to load a LADSPA plugin. You will get a menu from which you can choose which plugin to load.");
777 gtk_box_pack_start(GTK_BOX(g->control_subbox), dummy, WID_FIX);
781 p=new tX_panel("Lowpass", g->control_subbox);
784 g->lp_enable=gtk_check_button_new_with_label("Enable");
785 gui_set_tooltip(g->lp_enable, "Click here to enable the built-in lowpass effect.");
786 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->lp_enable), vtt->lp_enable);
787 p->add_client_widget(vg_create_fx_bar(vtt, vtt->lp_fx, 0));
789 p->add_client_widget(g->lp_enable);
791 g->lp_gain=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_gain, 0, 2, 0.1, 0.01, 0.01));
792 g->lp_reso=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_reso, 0, 0.99, 0.1, 0.01, 0.01));
793 g->lp_freq=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->lp_freq, 0, 1, 0.1, 0.01, 0.01));
795 g->lp_gaind=new tX_extdial("Input Gain", g->lp_gain);
796 p->add_client_widget(g->lp_gaind->get_widget());
797 gui_set_tooltip(g->lp_gaind->get_entry(), "Adjust the input gain. with this parameter you can either amplify or damp the input-signal for the lowpass effect.");
799 g->lp_freqd=new tX_extdial("Frequency", g->lp_freq);
800 p->add_client_widget(g->lp_freqd->get_widget());
801 gui_set_tooltip(g->lp_freqd->get_entry(), "Adjust the cutoff frequency of the lowpass filter. 0 is 0 Hz, 1 is 22.1 kHz.");
803 g->lp_resod=new tX_extdial("Resonance", g->lp_reso);
804 p->add_client_widget(g->lp_resod->get_widget());
805 gui_set_tooltip(g->lp_resod->get_entry(), "Adjust the resonance of the lowpass filter. This value determines how much the signal at the cutoff frequency will be amplified.");
807 gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
811 p=new tX_panel("Echo", g->control_subbox);
814 p->add_client_widget(vg_create_fx_bar(vtt, vtt->ec_fx, 0));
816 g->ec_enable=gtk_check_button_new_with_label("Enable");
817 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->ec_enable), vtt->ec_enable);
818 p->add_client_widget(g->ec_enable);
819 gui_set_tooltip(g->ec_enable, "Enable the built-in echo effect.");
821 g->ec_length=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_length, 0, 1, 0.1, 0.01, 0.001));
822 g->ec_feedback=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->ec_feedback, 0, 1, 0.1, 0.01, 0.001));
824 g->ec_lengthd=new tX_extdial("Duration", g->ec_length);
825 p->add_client_widget(g->ec_lengthd->get_widget());
826 gui_set_tooltip(g->ec_lengthd->get_entry(), "Adjust the length of the echo buffer.");
829 g->ec_feedbackd=new tX_extdial("Feedback", g->ec_feedback);
830 p->add_client_widget(g->ec_feedbackd->get_widget());
831 gui_set_tooltip(g->ec_feedbackd->get_entry(), "Adjust the feedback of the echo effect. Note that a value of 1 will result in a constant signal.");
833 gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
837 tempbox=gtk_hbox_new(FALSE,2);
838 gtk_widget_show(tempbox);
839 gtk_box_pack_end(GTK_BOX(g->control_box), tempbox, WID_FIX);
841 tempbox2=gtk_vbox_new(FALSE,0);
842 gtk_widget_show(tempbox2);
843 gtk_box_pack_start(GTK_BOX(tempbox), tempbox2, WID_FIX);
845 g->pitch=GTK_ADJUSTMENT(gtk_adjustment_new(vtt->rel_pitch, -3, +3, 0.1, 0.01, 0.001));
846 g->pan=GTK_ADJUSTMENT(gtk_adjustment_new(0, -1, 1, 0.1, 0.01, 0.001));
848 g->pitchd=new tX_extdial("Pitch", g->pitch);
849 gui_set_tooltip(g->pitchd->get_entry(), "Adjust this turntable's pitch.");
851 gtk_box_pack_start(GTK_BOX(tempbox2), g->pitchd->get_widget(), WID_FIX);
853 g->pand=new tX_extdial("Pan", g->pan);
854 gtk_box_pack_start(GTK_BOX(tempbox2), g->pand->get_widget(), WID_FIX);
855 gui_set_tooltip(g->pand->get_entry(), "SORRY. terminatorX does not yet support stereo yet. This parameter is plain fake.");
857 tempbox2=gtk_hbox_new(FALSE,0);
858 gtk_widget_show(tempbox2);
859 gtk_box_pack_start(GTK_BOX(tempbox), tempbox2, WID_FIX);
861 g->volume=GTK_ADJUSTMENT(gtk_adjustment_new(2.0-vtt->rel_volume, 0, 2, 0.01, 0.01, 0.01));
862 dummy=gtk_vscale_new(GTK_ADJUSTMENT(g->volume));
863 gtk_scale_set_draw_value(GTK_SCALE(dummy), False);
864 gui_set_tooltip(dummy, "Adjust this turntable's volume.");
866 gtk_box_pack_start(GTK_BOX(tempbox2), dummy, WID_FIX);
867 gtk_widget_show(dummy);
869 g->flash=gtk_tx_flash_new();
870 gtk_box_pack_start(GTK_BOX(tempbox2), g->flash, WID_FIX);
871 gtk_widget_show(g->flash);
875 // gtk_notebook_set_page(GTK_NOTEBOOK(vtt->gui.notebook), g->current_gui);
877 gui_connect_signals(vtt);
880 GtkSignalFunc fx_up(GtkWidget *wid, vtt_fx *effect)
884 vtt=(vtt_class*)effect->get_vtt();
885 vtt->effect_up(effect);
888 GtkSignalFunc fx_down(GtkWidget *wid, vtt_fx *effect)
892 vtt=(vtt_class*)effect->get_vtt();
893 vtt->effect_down(effect);
897 GtkSignalFunc fx_kill(GtkWidget *wid, vtt_fx_ladspa *effect)
901 vtt=(vtt_class*)effect->get_vtt();
902 vtt->effect_remove(effect);
905 GtkWidget *vg_create_fx_bar(vtt_class *vtt, vtt_fx *effect, int showdel)
911 box=gtk_hbox_new(FALSE,0);
915 button=gtk_button_new();
916 pixmap=tx_pixmap_widget(TX_ICON_FX_CLOSE);
917 gtk_container_add (GTK_CONTAINER (button), pixmap);
918 gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
919 gtk_widget_show(pixmap);
920 gtk_widget_show(button);
921 gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) fx_kill, (void *) effect);
924 button=gtk_button_new();
925 pixmap=tx_pixmap_widget(TX_ICON_FX_DOWN);
926 gtk_container_add (GTK_CONTAINER (button), pixmap);
927 gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
928 gtk_widget_show(pixmap);
929 gtk_widget_show(button);
930 gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) fx_down, (void *) effect);
932 button=gtk_button_new();
933 pixmap=tx_pixmap_widget(TX_ICON_FX_UP);
934 gtk_container_add (GTK_CONTAINER (button), pixmap);
935 gtk_box_pack_end(GTK_BOX(box), button, WID_FIX);
936 gtk_widget_show(pixmap);
937 gtk_widget_show(button);
938 gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) fx_up, (void *) effect);
940 gtk_widget_show(box);
946 int gtk_box_get_widget_pos(GtkBox *box, GtkWidget *child)
951 list = box->children;
954 GtkBoxChild *child_info;
955 child_info = (GtkBoxChild *) list->data;
956 if (child_info->widget == child)
958 list = list->next; i++;
963 void vg_move_fx_panel_up(GtkWidget *wid, vtt_class *vtt)
965 int pos=gtk_box_get_widget_pos(GTK_BOX(vtt->gui.control_subbox), wid);
966 gtk_box_reorder_child(GTK_BOX(vtt->gui.control_subbox), wid, pos-1);
969 void vg_move_fx_panel_down(GtkWidget *wid, vtt_class *vtt)
971 int pos=gtk_box_get_widget_pos(GTK_BOX(vtt->gui.control_subbox), wid);
972 gtk_box_reorder_child(GTK_BOX(vtt->gui.control_subbox), wid, pos+1);
975 GtkSignalFunc vg_show_fx_info(GtkWidget *wid, vtt_fx *effect)
977 tx_l_note(effect->get_info_string());
980 void vg_create_fx_gui(vtt_class *vtt, vtt_fx_ladspa *effect, LADSPA_Plugin *plugin)
987 list <tX_seqpar_vttfx *> :: iterator sp;
989 strcpy(buffer, plugin->getLabel());
990 if (strlen(buffer) > 8)
998 p=new tX_panel(buffer, g->control_subbox);
1000 p->add_client_widget(vg_create_fx_bar(vtt, effect, 1));
1002 for (sp = effect->controls.begin(); sp != effect->controls.end(); sp++)
1004 p->add_client_widget((*sp)->get_widget());
1007 gtk_signal_connect(GTK_OBJECT(p->get_labelbutton()), "clicked", (GtkSignalFunc) vg_show_fx_info, (void *) effect);
1008 gui_set_tooltip(p->get_labelbutton(), "Click here to learn more about this plugin.");
1009 effect->set_panel_widget(p->get_widget());
1010 effect->set_panel(p);
1012 gtk_box_pack_start(GTK_BOX(g->control_subbox), p->get_widget(), WID_FIX);
1015 void gui_set_name(vtt_class *vtt, char *newname)
1017 gtk_label_set_text(GTK_LABEL(vtt->gui.audio_label), newname);
1018 gtk_label_set_text(GTK_LABEL(vtt->gui.control_label), newname);
1019 gtk_entry_set_text(GTK_ENTRY(vtt->gui.name), newname);
1022 void gui_set_filename (vtt_class *vtt, char *newname)
1024 gtk_label_set(GTK_LABEL(GTK_BUTTON(vtt->gui.file)->child), newname);
1027 void gui_update_display(vtt_class *vtt)
1029 nicer_filename(global_filename_buffer, vtt->filename);
1030 gtk_label_set(GTK_LABEL(GTK_BUTTON(vtt->gui.file)->child), global_filename_buffer);
1031 gtk_tx_set_data(GTK_TX(vtt->gui.display), vtt->buffer, vtt->samples_in_buffer);
1034 void delete_gui(vtt_class *vtt)
1036 delete vtt->gui.main_panel;
1037 delete vtt->gui.trigger_panel;
1039 delete vtt->gui.pitchd;
1040 delete vtt->gui.pand;
1042 delete vtt->gui.lp_gaind;
1043 delete vtt->gui.lp_resod;
1044 delete vtt->gui.lp_freqd;
1045 delete vtt->gui.lp_panel;
1047 delete vtt->gui.ec_lengthd;
1048 delete vtt->gui.ec_feedbackd;
1049 delete vtt->gui.ec_panel;
1051 gtk_widget_destroy(vtt->gui.control_box);
1052 gtk_widget_destroy(vtt->gui.audio_box);
1056 void recreate_gui(vtt_class *vtt, GtkWidget *ctrl, GtkWidget *audio)
1059 // gtk_notebook_set_page(GTK_NOTEBOOK(vtt->gui.notebook), g->current_gui);
1060 gtk_box_pack_start(GTK_BOX(daddy), vtt->gui.frame, TRUE, TRUE, 0);
1061 gtk_widget_show(vtt->gui.frame);
1064 void delete_gui(vtt_class *vtt)
1066 gtk_widget_destroy(vtt->gui.frame);
1069 void update_all_vtts()
1071 list <vtt_class *> :: iterator vtt;
1074 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1076 if ((*vtt)->is_playing)
1078 gtk_tx_update_pos_display(GTK_TX((*vtt)->gui.display), (*vtt)->pos_i, (*vtt)->mute);
1080 temp=(*vtt)->max_value*(*vtt)->res_volume*vtt_class::vol_channel_adjust;
1081 (*vtt)->max_value=0;
1082 gtk_tx_flash_set_level((*vtt)->gui.flash, temp);
1088 void cleanup_vtt(vtt_class *vtt)
1090 gtk_tx_cleanup_pos_display(GTK_TX(vtt->gui.display));
1092 gtk_tx_flash_set_level(vtt->gui.flash, 0.0);
1093 gtk_tx_flash_clear(vtt->gui.flash);
1097 void cleanup_all_vtts()
1099 list <vtt_class *> :: iterator vtt;
1101 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1103 if ((*vtt)->buffer) gtk_tx_cleanup_pos_display(GTK_TX((*vtt)->gui.display));
1105 gtk_tx_flash_set_level((*vtt)->gui.flash, 0.0);
1106 gtk_tx_flash_clear((*vtt)->gui.flash);
1111 void gui_clear_master_button(vtt_class *vtt)
1113 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vtt->gui.sync_master), 0);
1116 void gui_show_frame(vtt_class *vtt, int show)
1118 gtk_tx_show_frame(GTK_TX(vtt->gui.display), show);
1121 void show_all_guis(int show)
1123 list <vtt_class *> :: iterator vtt;
1125 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1129 gtk_widget_show((*vtt)->gui.notebook);
1133 gtk_widget_hide((*vtt)->gui.notebook);
1139 void vg_update_sync(void *p)
1141 vtt_class *vtt=(vtt_class*) p;
1143 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vtt->gui.sync_client), vtt->is_sync_client);
1144 // gtk_adjustment_set_value(vtt->gui.cycles
1147 #define vgui (*vtt)->gui
1150 void vg_enable_critical_buttons(int enable)
1152 list <vtt_class *> :: iterator vtt;
1153 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1155 gtk_widget_set_sensitive(vgui.del, enable);
1156 gtk_widget_set_sensitive(vgui.sync_master, enable);
1161 int vg_get_current_page(vtt_class *vtt)
1166 void vg_set_current_page(vtt_class *vtt, int page)
1168 vtt->gui.current_gui=page;
1171 void vg_init_all_non_seqpars()
1173 list <vtt_class *> :: iterator vtt;
1175 for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++)
1177 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON((*vtt)->gui.autotrigger), (*vtt)->autotrigger);
1178 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON((*vtt)->gui.sync_master), (*vtt)->is_sync_master);