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 "sequenceable parameters".
24 #include "tX_seqpar.h"
27 #include "tX_mastergui.h"
28 #include "tX_global.h"
29 #include "tX_sequencer.h"
30 #include "tX_extdial.h"
31 #include "tX_engine.h"
34 #define TX_SEQPAR_DEFAULT_SCALE 0.05
36 list <tX_seqpar *> tX_seqpar :: all;
37 list <tX_seqpar *> tX_seqpar :: update;
38 pthread_mutex_t tX_seqpar :: update_lock = PTHREAD_MUTEX_INITIALIZER;
40 #define tt ((vtt_class *) vtt)
42 tX_seqpar :: tX_seqpar () : bound_midi_event()
53 last_event_recorded=NULL;
55 midi_lower_bound_set=false;
56 midi_upper_bound_set=false;
59 void tX_seqpar :: set_mapping_parameters(float max, float min, float scale, int mappable)
67 void tX_seqpar :: handle_mouse_input(float adjustment)
71 tmpvalue=get_value()+adjustment*scale_value;
72 if (tmpvalue>max_value) tmpvalue=max_value;
73 if (tmpvalue<min_value) tmpvalue=min_value;
75 /*printf("Handling %s, max %f, min %f, scale %f, val: %f\n", get_name(), max_value, min_value, scale_value, tmpvalue);*/
77 receive_input_value(tmpvalue);
80 #ifdef USE_ALSA_MIDI_IN
81 void tX_seqpar :: handle_midi_input( const tX_midievent& event )
83 double tmpvalue = -1000;
87 if (midi_upper_bound_set) {
91 if (midi_lower_bound_set) {
97 case tX_midievent::CC:
98 case tX_midievent::CC14:
99 case tX_midievent::PITCHBEND:
100 case tX_midievent::RPN:
101 case tX_midievent::NRPN:
102 tmpvalue = event.value * (max-min) + min;
104 case tX_midievent::NOTE:
105 tmpvalue = event.is_noteon;
111 if (tmpvalue>max) tmpvalue=max;
112 else if (tmpvalue<min) tmpvalue=min;
114 tmpvalue=event.value;
119 /* Not using receive() as we want immediate GUI update... */
121 record_value(tmpvalue);
122 do_update_graphics();
126 void tX_seqpar :: set_vtt (void *mytt)
131 tX_seqpar :: ~tX_seqpar()
133 pthread_mutex_lock(&update_lock);
135 pthread_mutex_unlock(&update_lock);
136 sequencer.delete_all_events_for_sp(this, tX_sequencer::DELETE_ALL);
140 void tX_seqpar :: do_touch()
142 if (sequencer.is_recording())
145 touch_timestamp=sequencer.get_timestamp();
149 void tX_seqpar :: untouch_all()
151 list <tX_seqpar *> :: iterator sp;
153 for (sp=all.begin(); sp!=all.end(); sp++)
159 void tX_seqpar :: create_persistence_ids()
161 list <tX_seqpar *> :: iterator sp;
164 for (sp=all.begin(); sp!=all.end(); sp++)
167 (*sp)->set_persistence_id(pid);
171 tX_seqpar* tX_seqpar :: get_sp_by_persistence_id(unsigned int pid)
173 list <tX_seqpar *> :: iterator sp;
175 for (sp=all.begin(); sp!=all.end(); sp++)
177 if ((*sp)->get_persistence_id()==pid) return ((*sp));
180 fprintf (stderr, "oops: failed to lookup persistence id [%i].\n", pid);
185 void tX_seqpar :: record_value(const float value)
187 #define last_event ((tX_event *) last_event_recorded)
189 /* recording more than one event per seqpar for
190 one timestamp doesn't make sense... so if the
191 last_event_recorded was for the current timestamp
192 we simply set that event's value to the current one.
194 if ((last_event) && (last_event->get_timestamp() == sequencer.get_timestamp()))
196 last_event->set_value(value);
198 else last_event_recorded=(void *) sequencer.record(this, value);
201 void tX_seqpar :: receive_gui_value(const float value)
211 void tX_seqpar :: receive_input_value(const float value)
218 void tX_seqpar :: receive_forward_value(const float value)
223 void tX_seqpar :: materialize_forward_values()
225 list <tX_seqpar *> :: iterator sp;
227 for (sp=all.begin(); sp!=all.end(); sp++)
229 (*sp)->exec_value((*sp)->fwd_value);
234 char * tX_seqpar :: get_vtt_name()
236 if (vtt) return tt->name;
237 else return "Master Track";
240 void tX_seqpar :: restore_meta(xmlNodePtr node) {
244 buffer=(char *) xmlGetProp(node, (xmlChar *) "id");
245 if (buffer) { sscanf(buffer, "%i", &persistence_id); }
246 else { tX_error("no ID for seqpar %s", this->get_name()); }
248 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiUpperBound");
250 sscanf(buffer, "%lf", &temp);
251 set_upper_midi_bound(temp);
254 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiLowerBound");
256 sscanf(buffer, "%lf", &temp);
257 set_lower_midi_bound(temp);
260 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiType");
262 if (strcmp("cc", buffer)==0) {
263 bound_midi_event.type=tX_midievent::CC;
264 } else if (strcmp("note", buffer)==0) {
265 bound_midi_event.type=tX_midievent::NOTE;
266 } else if (strcmp("pitchbend", buffer)==0) {
267 bound_midi_event.type=tX_midievent::PITCHBEND;
268 } else if (strcmp("cc14", buffer)==0) {
269 bound_midi_event.type=tX_midievent::CC14;
270 } else if (strcmp("rpn", buffer)==0) {
271 bound_midi_event.type=tX_midievent::RPN;
272 } else if (strcmp("nrpn", buffer)==0) {
273 bound_midi_event.type=tX_midievent::NRPN;
275 tX_error("unknown midiType \"%s\" for seqpar %s", buffer, this->get_name());
278 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiChannel");
279 if (buffer) { sscanf(buffer, "%i", &bound_midi_event.channel); }
280 else { tX_error("no midiChannel for seqpar %s", this->get_name()); }
282 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiNumber");
283 if (buffer) { sscanf(buffer, "%i", &bound_midi_event.number); }
284 else { tX_error("no midiNumber for seqpar %s", this->get_name()); }
286 /* else: no MIDI init.... */
289 void tX_seqpar :: store_meta(FILE *rc, gzFile rz) {
293 if (bound_midi_event.type!=tX_midievent::NONE) {
296 switch (bound_midi_event.type) {
297 case tX_midievent::NOTE: type="note"; break;
298 case tX_midievent::CC: type="cc"; break;
299 case tX_midievent::PITCHBEND: type="pitchbend"; break;
300 case tX_midievent::CC14: type="cc14"; break;
301 case tX_midievent::RPN: type="rpn"; break;
302 case tX_midievent::NRPN: type="nrpn"; break;
303 default: type="error";
305 sprintf(buffer, "id=\"%i\" midiType=\"%s\" midiChannel=\"%i\" midiNumber=\"%i\"", persistence_id, type, bound_midi_event.channel, bound_midi_event.number);
307 sprintf(buffer, "id=\"%i\"", persistence_id);
310 if (midi_upper_bound_set) {
311 sprintf(buffer2, " midiUpperBound=\"%lf\"", midi_upper_bound);
312 strcat(buffer, buffer2);
315 if (midi_lower_bound_set) {
316 sprintf(buffer2, " midiLowerBound=\"%lf\"", midi_lower_bound);
317 strcat(buffer, buffer2);
324 const char * tX_seqpar :: get_name()
326 return "This string means trouble!";
329 float tX_seqpar :: get_value()
331 printf("Ooops. tX_seqpar::get_value() called. Trouble.");
335 void tX_seqpar :: update_graphics()
338 do_update_graphics();
339 while (gtk_events_pending()) gtk_main_iteration(); /* gtk_flush */
343 void tX_seqpar :: update_all_graphics()
345 list <tX_seqpar *> :: iterator sp;
347 pthread_mutex_lock(&update_lock);
351 pthread_mutex_unlock(&update_lock);
355 while (gtk_events_pending()) gtk_main_iteration();
356 for (sp=update.begin(); sp!=update.end(); sp++)
358 (*sp)->update_graphics();
360 update.erase(update.begin(), update.end());
361 pthread_mutex_unlock(&update_lock);
364 void tX_seqpar :: init_all_graphics()
366 list <tX_seqpar *> :: iterator sp;
368 pthread_mutex_lock(&update_lock);
370 for (sp=all.begin(); sp!=all.end(); sp++)
372 (*sp)->update_graphics();
374 while (gtk_events_pending()) gtk_main_iteration();
376 pthread_mutex_unlock(&update_lock);
379 void tX_seqpar_update :: exec_value(const float value)
382 pthread_mutex_lock(&update_lock);
383 update.push_front(this);
384 pthread_mutex_unlock(&update_lock);
387 void tX_seqpar_no_update :: exec_value(const float value)
392 void tX_seqpar_no_update :: do_update_graphics()
398 void tX_seqpar_no_update_active_forward :: receive_forward_value(const float value)
404 void tX_seqpar_update_active_forward :: receive_forward_value(const float value)
412 /**** Sequencable Parameter: MASTER VOLUME ****/
414 tX_seqpar_master_volume :: tX_seqpar_master_volume()
416 set_mapping_parameters(2.5, 0, 0.1, 0);
419 void tX_seqpar_master_volume :: do_exec(const float value)
421 vtt_class :: set_master_volume(value);
424 void tX_seqpar_master_volume :: do_update_graphics ()
426 gtk_adjustment_set_value(volume_adj, vtt_class::master_volume);
429 const char * tX_seqpar_master_volume :: get_name()
431 return "Master Volume";
434 /**** Sequencable Parameter: MASTER PITCH ****/
436 tX_seqpar_master_pitch :: tX_seqpar_master_pitch()
438 set_mapping_parameters(3.0, -3.0, 0.1, 0);
441 void tX_seqpar_master_pitch :: do_exec(const float value)
443 vtt_class :: set_master_pitch(value);
446 void tX_seqpar_master_pitch :: do_update_graphics ()
448 gtk_adjustment_set_value(pitch_adj, globals.pitch);
451 const char * tX_seqpar_master_pitch :: get_name()
453 return "Master Pitch";
456 /**** Sequencable Parameter: TURNTABLE SPEED ****/
458 tX_seqpar_vtt_speed :: tX_seqpar_vtt_speed()
460 // min max scale are not required for this parameter
461 set_mapping_parameters(3.0, -3.0, 0.1, 1);
464 /* speed works differently so we need an extra input-handler */
466 void tX_seqpar_vtt_speed :: handle_mouse_input(float adjustment)
468 if (tt->do_scratch) tt->sp_speed.receive_input_value(adjustment);
469 tt->sense_cycles=globals.sense_cycles;
472 void tX_seqpar_vtt_speed :: do_exec(const float value)
474 tt->speed=value*tt->audiofile_pitch_correction;
477 const char * tX_seqpar_vtt_speed :: get_name()
479 return "Speed (Scratching)";
482 /**** Sequencable Parameter: TURNTABLE SPIN ****/
484 tX_seqpar_spin :: tX_seqpar_spin()
486 set_mapping_parameters(1, 0, 0, 0);
489 void tX_seqpar_spin :: do_exec(const float value)
491 if (value > 0) tt->speed=tt->res_pitch;
495 const char * tX_seqpar_spin :: get_name()
497 return "Motor Spin (On/Off)";
500 /**** Sequencable Parameter: TURNTABLE VOLUME ****/
502 tX_seqpar_vtt_volume :: tX_seqpar_vtt_volume()
504 set_mapping_parameters(2.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
507 float tX_seqpar_vtt_volume :: get_value(){ return tt->rel_volume; }
509 void tX_seqpar_vtt_volume :: do_exec(const float value)
511 tt->set_volume(value);
514 void tX_seqpar_vtt_volume :: do_update_graphics ()
516 gtk_adjustment_set_value(tt->gui.volume, 2.0-tt->rel_volume);
519 const char * tX_seqpar_vtt_volume :: get_name()
524 /**** Sequencable Parameter : Pan ****/
526 tX_seqpar_vtt_pan :: tX_seqpar_vtt_pan()
528 set_mapping_parameters(1.0, -1.0, TX_SEQPAR_DEFAULT_SCALE, 1);
531 float tX_seqpar_vtt_pan :: get_value(){ return tt->pan; }
533 void tX_seqpar_vtt_pan :: do_exec(const float value)
538 void tX_seqpar_vtt_pan :: do_update_graphics ()
540 gtk_adjustment_set_value(tt->gui.pan, tt->pan);
543 const char * tX_seqpar_vtt_pan :: get_name()
548 /**** Sequencable Parameter: TURNTABLE PITCH ****/
550 tX_seqpar_vtt_pitch :: tX_seqpar_vtt_pitch()
552 set_mapping_parameters(3.0, -3.0, TX_SEQPAR_DEFAULT_SCALE, 1);
555 float tX_seqpar_vtt_pitch :: get_value(){ return tt->rel_pitch; }
557 void tX_seqpar_vtt_pitch :: do_exec(const float value)
559 tt->set_pitch(value);
562 void tX_seqpar_vtt_pitch :: do_update_graphics ()
564 gtk_adjustment_set_value(tt->gui.pitch, tt->rel_pitch);
567 const char * tX_seqpar_vtt_pitch :: get_name()
572 /**** Sequencable Parameter: TURNTABLE TRIGGER ****/
574 tX_seqpar_vtt_trigger :: tX_seqpar_vtt_trigger()
576 set_mapping_parameters(0.01, 0, 1, 1);
580 void tX_seqpar_vtt_trigger :: do_exec(const float value)
582 if (value > 0) tt->trigger();
586 const char * tX_seqpar_vtt_trigger :: get_name()
588 return "Trigger (Start/Stop)";
591 /**** Sequencable Parameter: TURNTABLE LOOP ****/
593 tX_seqpar_vtt_loop :: tX_seqpar_vtt_loop()
595 set_mapping_parameters(0, 0, 0, 0);
600 void tX_seqpar_vtt_loop :: do_exec(const float value)
602 tt->set_loop(value>0);
605 const char * tX_seqpar_vtt_loop :: get_name()
607 return "Loop (On/Off)";
610 void tX_seqpar_vtt_loop :: do_update_graphics ()
612 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.loop), tt->loop);
615 /**** Sequencable Parameter: TURNTABLE SYNC CLIENT ****/
617 tX_seqpar_vtt_sync_client :: tX_seqpar_vtt_sync_client()
619 set_mapping_parameters(0,0,0,0);
623 void tX_seqpar_vtt_sync_client :: do_exec(const float value)
625 tt->set_sync_client((value>0), tt->sync_cycles);
628 void tX_seqpar_vtt_sync_client :: do_update_graphics ()
630 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.sync_client), tt->is_sync_client);
633 const char * tX_seqpar_vtt_sync_client :: get_name()
635 return "Sync Client (On/Off)";
638 /**** Sequencable Parameter: TURNTABLE SYNC CYCLES ****/
640 tX_seqpar_vtt_sync_cycles :: tX_seqpar_vtt_sync_cycles()
642 set_mapping_parameters(0,0,0,0);
645 void tX_seqpar_vtt_sync_cycles :: do_exec(const float value)
647 tt->set_sync_client(tt->is_sync_client, (int) value);
650 void tX_seqpar_vtt_sync_cycles :: do_update_graphics ()
652 gtk_adjustment_set_value(tt->gui.cycles, tt->sync_cycles);
655 const char * tX_seqpar_vtt_sync_cycles :: get_name()
657 return "Sync Cycles";
660 /**** Sequencable Parameter: TURNTABLE LP ENABLE ****/
662 tX_seqpar_vtt_lp_enable :: tX_seqpar_vtt_lp_enable()
664 set_mapping_parameters(0.01,0,1,1);
668 void tX_seqpar_vtt_lp_enable :: do_exec(const float value)
670 tt->lp_set_enable(value>0);
673 void tX_seqpar_vtt_lp_enable :: do_update_graphics ()
675 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.lp_enable), tt->lp_enable);
678 const char * tX_seqpar_vtt_lp_enable :: get_name()
680 return "Lowpass: Enable (On/Off)";
683 /**** Sequencable Parameter: TURNTABLE LP GAIN ****/
685 tX_seqpar_vtt_lp_gain :: tX_seqpar_vtt_lp_gain()
687 set_mapping_parameters(2.0,0, TX_SEQPAR_DEFAULT_SCALE, 1);
690 float tX_seqpar_vtt_lp_gain :: get_value() { return tt->lp_gain; }
692 void tX_seqpar_vtt_lp_gain :: do_exec(const float value)
694 tt->lp_set_gain(value);
697 const char * tX_seqpar_vtt_lp_gain :: get_name()
699 return "Lowpass: Input Gain";
702 void tX_seqpar_vtt_lp_gain :: do_update_graphics ()
704 gtk_adjustment_set_value(tt->gui.lp_gain, tt->lp_gain);
707 /**** Sequencable Parameter: TURNTABLE LP RESO ****/
709 tX_seqpar_vtt_lp_reso :: tX_seqpar_vtt_lp_reso()
711 set_mapping_parameters(0.99, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
714 float tX_seqpar_vtt_lp_reso :: get_value() { return tt->lp_reso; }
716 void tX_seqpar_vtt_lp_reso :: do_exec(const float value)
718 tt->lp_set_reso(value);
721 void tX_seqpar_vtt_lp_reso :: do_update_graphics ()
723 gtk_adjustment_set_value(tt->gui.lp_reso, tt->lp_reso);
726 const char * tX_seqpar_vtt_lp_reso :: get_name()
728 return "Lowpass: Resonance";
731 /**** Sequencable Parameter: TURNTABLE LP FREQUENCY ****/
733 tX_seqpar_vtt_lp_freq :: tX_seqpar_vtt_lp_freq()
735 set_mapping_parameters(0.99, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
738 float tX_seqpar_vtt_lp_freq :: get_value() { return tt->lp_freq; }
740 void tX_seqpar_vtt_lp_freq :: do_exec(const float value)
742 tt->lp_set_freq(value);
745 const char * tX_seqpar_vtt_lp_freq :: get_name()
747 return "Lowpass: Cutoff Frequency";
750 void tX_seqpar_vtt_lp_freq :: do_update_graphics ()
752 gtk_adjustment_set_value(tt->gui.lp_freq, tt->lp_freq);
755 /**** Sequencable Parameter: TURNTABLE ECHO ENABLE ****/
757 tX_seqpar_vtt_ec_enable :: tX_seqpar_vtt_ec_enable()
759 set_mapping_parameters(0.01,0,1,1);
763 void tX_seqpar_vtt_ec_enable :: do_exec(const float value)
765 tt->ec_set_enable(value>0);
768 void tX_seqpar_vtt_ec_enable :: do_update_graphics ()
770 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.ec_enable), tt->ec_enable);
773 const char * tX_seqpar_vtt_ec_enable :: get_name()
775 return "Echo: Enable (On/Off)";
778 /**** Sequencable Parameter: TURNTABLE ECHO LENGTH ****/
780 tX_seqpar_vtt_ec_length :: tX_seqpar_vtt_ec_length()
782 set_mapping_parameters(1.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
785 float tX_seqpar_vtt_ec_length :: get_value() { return tt->ec_length; }
787 void tX_seqpar_vtt_ec_length :: do_exec(const float value)
789 tt->ec_set_length(value);
792 void tX_seqpar_vtt_ec_length :: do_update_graphics ()
794 gtk_adjustment_set_value(tt->gui.ec_length, tt->ec_length);
797 const char * tX_seqpar_vtt_ec_length :: get_name()
799 return "Echo: Duration";
802 /**** Sequencable Parameter: TURNTABLE ECHO FEEDBACK ****/
804 tX_seqpar_vtt_ec_feedback :: tX_seqpar_vtt_ec_feedback()
806 set_mapping_parameters(1.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
809 float tX_seqpar_vtt_ec_feedback :: get_value() { return tt->ec_feedback; }
811 void tX_seqpar_vtt_ec_feedback :: do_exec(const float value)
813 tt->ec_set_feedback(value);
816 void tX_seqpar_vtt_ec_feedback :: do_update_graphics ()
818 gtk_adjustment_set_value(tt->gui.ec_feedback, tt->ec_feedback);
821 const char * tX_seqpar_vtt_ec_feedback :: get_name()
823 return "Echo: Feedback";
826 /**** Sequencable Parameter: TURNTABLE ECHO PAN ****/
828 tX_seqpar_vtt_ec_pan :: tX_seqpar_vtt_ec_pan()
830 set_mapping_parameters(1.0, -1.0, TX_SEQPAR_DEFAULT_SCALE, 1);
833 float tX_seqpar_vtt_ec_pan :: get_value() { return tt->ec_pan; }
835 void tX_seqpar_vtt_ec_pan :: do_exec(const float value)
837 tt->ec_set_pan(value);
840 void tX_seqpar_vtt_ec_pan :: do_update_graphics ()
842 gtk_adjustment_set_value(tt->gui.ec_pan, tt->ec_pan);
845 const char * tX_seqpar_vtt_ec_pan :: get_name()
850 /**** Sequencable Parameter: TURNTABLE ECHO VOLUME ****/
852 tX_seqpar_vtt_ec_volume :: tX_seqpar_vtt_ec_volume()
854 set_mapping_parameters(0.0, 3.0, TX_SEQPAR_DEFAULT_SCALE, 1);
857 float tX_seqpar_vtt_ec_volume :: get_value() { return tt->ec_volume; }
859 void tX_seqpar_vtt_ec_volume :: do_exec(const float value)
861 tt->ec_set_volume(value);
864 void tX_seqpar_vtt_ec_volume :: do_update_graphics ()
866 gtk_adjustment_set_value(tt->gui.ec_volume, tt->ec_volume);
869 const char * tX_seqpar_vtt_ec_volume :: get_name()
871 return "Echo: Volume";
875 /**** Sequencable Parameter: TURNTABLE MUTE ****/
877 tX_seqpar_vtt_mute :: tX_seqpar_vtt_mute()
879 set_mapping_parameters(0.01,0,1,1);
883 void tX_seqpar_vtt_mute :: do_exec(const float value)
885 tt->set_mute(value>0);
888 const char * tX_seqpar_vtt_mute :: get_name()
890 return "Mute (On/Off)";
893 /** LADSPA fx parameters **/
895 tX_seqpar_vttfx :: tX_seqpar_vttfx()
897 fx_value=(float *) malloc(sizeof(float));
899 set_mapping_parameters(0,0,0,0);
902 tX_seqpar_vttfx :: ~tX_seqpar_vttfx()
907 void tX_seqpar_vttfx :: set_name(const char *n, const char *sn)
910 strcpy(label_name, sn);
914 float tX_seqpar_vttfx :: get_value()
919 void tX_seqpar_vttfx :: create_widget()
921 fprintf(stderr, "tX: Ooops. create_widget() for tX_seqpar_vttfx.\n");
924 const char * tX_seqpar_vttfx :: get_name()
929 void tX_seqpar_vttfx_float :: create_widget()
931 float tmp=max_value - min_value/1000;
934 //myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value+tmp/10, max_value-tmp/10, tmp, tmp, tmp));
935 myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value, max_value, tmp, tmp, tmp));
936 mydial=new tX_extdial(label_name, myadj, this);
937 g_signal_connect(G_OBJECT(myadj), "value_changed", (GtkSignalFunc) tX_seqpar_vttfx_float :: gtk_callback, this);
938 widget = mydial->get_widget();
941 tX_seqpar_vttfx_float :: ~tX_seqpar_vttfx_float()
946 void tX_seqpar_vttfx_float :: do_exec(const float value)
951 void tX_seqpar_vttfx_float :: do_update_graphics()
953 gtk_adjustment_set_value(myadj, *fx_value);
956 GtkSignalFunc tX_seqpar_vttfx_float :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_float *sp)
958 sp->receive_gui_value(sp->myadj->value);
962 #define WID_DYN TRUE, TRUE, 0
963 #define WID_FIX FALSE, FALSE, 0
965 void tX_seqpar_vttfx_int :: create_widget()
967 float tmp=max_value - min_value/1000;
971 myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value, max_value, 1, 10, tmp));
972 GtkWidget *box=gtk_vbox_new(FALSE, 2);
974 tmpwid=gtk_spin_button_new(myadj,1.0,0);
975 gtk_widget_show(tmpwid);
976 gtk_box_pack_start(GTK_BOX(box), tmpwid, WID_DYN);
977 g_signal_connect(G_OBJECT(tmpwid), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, this);
979 g_signal_connect(G_OBJECT(myadj), "value_changed", (GtkSignalFunc) tX_seqpar_vttfx_int :: gtk_callback, this);
981 tmpwid=gtk_label_new(label_name);
982 gtk_widget_show(tmpwid);
983 gtk_box_pack_start(GTK_BOX(box), tmpwid, WID_FIX);
985 gtk_widget_show(box);
987 widget=gtk_event_box_new();
988 g_signal_connect(G_OBJECT(widget), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, this);
990 gtk_container_add(GTK_CONTAINER(widget), box);
993 tX_seqpar_vttfx_int :: ~tX_seqpar_vttfx_int()
995 gtk_widget_destroy(widget);
998 void tX_seqpar_vttfx_int :: do_exec(const float value)
1003 void tX_seqpar_vttfx_int :: do_update_graphics()
1005 gtk_adjustment_set_value(myadj, *fx_value);
1008 GtkSignalFunc tX_seqpar_vttfx_int :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_int *sp)
1010 sp->receive_gui_value(sp->myadj->value);
1014 void tX_seqpar_vttfx_bool :: create_widget()
1016 *fx_value=min_value;
1017 widget=gtk_check_button_new_with_label(label_name);
1018 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), 0);
1019 g_signal_connect(G_OBJECT(widget), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, this);
1020 g_signal_connect(G_OBJECT(widget), "clicked", (GtkSignalFunc) tX_seqpar_vttfx_bool :: gtk_callback, this);
1023 tX_seqpar_vttfx_bool :: ~tX_seqpar_vttfx_bool()
1025 gtk_widget_destroy(widget);
1028 void tX_seqpar_vttfx_bool :: do_exec(const float value)
1033 GtkSignalFunc tX_seqpar_vttfx_bool :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_bool *sp)
1035 sp->receive_gui_value(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sp->widget)));
1039 void tX_seqpar_vttfx_bool :: do_update_graphics()
1041 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), *fx_value==max_value);
1044 gboolean tX_seqpar::tX_seqpar_press(GtkWidget *widget, GdkEventButton *event, gpointer data) {
1045 tX_seqpar *sp=(tX_seqpar *) data;
1047 if (event->button==3) {
1048 GtkWidget *menu=gtk_menu_new();
1050 GtkWidget *item=gtk_menu_item_new_with_label(sp->get_name());
1051 gtk_widget_set_sensitive(item, FALSE);
1052 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1053 gtk_widget_show(item);
1055 item = gtk_menu_item_new();
1056 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1057 gtk_widget_set_sensitive (item, FALSE);
1058 gtk_widget_show (item);
1060 item = gtk_menu_item_new_with_label("MIDI Learn");
1061 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1062 gtk_widget_show(item);
1063 #ifdef USE_ALSA_MIDI_IN
1064 g_signal_connect(item, "activate", (GCallback) tX_seqpar::learn_midi_binding, sp);
1066 gtk_widget_set_sensitive(item, FALSE);
1069 item = gtk_menu_item_new_with_label("Remove MIDI Binding");
1070 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1071 gtk_widget_show(item);
1073 if (sp->bound_midi_event.type==tX_midievent::NONE) {
1074 gtk_widget_set_sensitive(item, FALSE);
1076 #ifdef USE_ALSA_MIDI_IN
1077 g_signal_connect(item, "activate", (GCallback) tX_seqpar::remove_midi_binding, sp);
1079 gtk_widget_set_sensitive(item, FALSE);
1081 if (!sp->is_boolean) {
1082 item = gtk_menu_item_new();
1083 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1084 gtk_widget_set_sensitive(item, FALSE);
1085 gtk_widget_show(item);
1087 item = gtk_menu_item_new_with_label("Set Upper MIDI Bound");
1088 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1089 gtk_widget_show(item);
1091 #ifdef USE_ALSA_MIDI_IN
1092 g_signal_connect(item, "activate", (GCallback) tX_seqpar::set_midi_upper_bound, sp);
1094 gtk_widget_set_sensitive(item, FALSE);
1097 item = gtk_menu_item_new_with_label("Reset Upper MIDI Bound");
1098 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1099 gtk_widget_show(item);
1100 #ifdef USE_ALSA_MIDI_IN
1101 g_signal_connect(item, "activate", (GCallback) tX_seqpar::reset_midi_upper_bound, sp);
1103 gtk_widget_set_sensitive(item, FALSE);
1106 if (!sp->midi_upper_bound_set) {
1107 gtk_widget_set_sensitive(item, FALSE);
1110 item = gtk_menu_item_new_with_label("Set Lower MIDI Bound");
1111 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1112 gtk_widget_show(item);
1113 #ifdef USE_ALSA_MIDI_IN
1114 g_signal_connect(item, "activate", (GCallback) tX_seqpar::set_midi_lower_bound, sp);
1116 gtk_widget_set_sensitive(item, FALSE);
1119 item = gtk_menu_item_new_with_label("Reset Lower MIDI Bound");
1120 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1121 gtk_widget_show(item);
1122 #ifdef USE_ALSA_MIDI_IN
1123 g_signal_connect(item, "activate", (GCallback) tX_seqpar::reset_midi_lower_bound, sp);
1125 gtk_widget_set_sensitive(item, FALSE);
1128 if (!sp->midi_lower_bound_set) {
1129 gtk_widget_set_sensitive(item, FALSE);
1133 item = gtk_menu_item_new();
1134 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1135 gtk_widget_set_sensitive (item, FALSE);
1136 gtk_widget_show (item);
1138 item = gtk_menu_item_new_with_label("Delete Sequencer Events");
1139 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1140 gtk_widget_show(item);
1141 g_signal_connect(item, "activate", (GCallback) menu_delete_all_events_for_sp, sp);
1143 gtk_widget_show(menu);
1145 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);
1146 //gtk_grab_remove(gtk_grab_get_current());
1154 #ifdef USE_ALSA_MIDI_IN
1156 gboolean tX_seqpar::remove_midi_binding(GtkWidget *widget, gpointer data) {
1157 tX_seqpar *sp=(tX_seqpar *) data;
1159 sp->bound_midi_event.type=tX_midievent::NONE;
1160 sp->bound_midi_event.number=0;
1161 sp->bound_midi_event.channel=0;
1166 gboolean tX_seqpar::learn_midi_binding(GtkWidget *widget, gpointer data) {
1167 tX_seqpar *sp=(tX_seqpar *) data;
1169 tX_engine::get_instance()->get_midi()->set_midi_learn_sp(sp);
1174 gboolean tX_seqpar::set_midi_upper_bound(GtkWidget *widget, gpointer data) {
1175 tX_seqpar *sp=(tX_seqpar *) data;
1176 sp->set_upper_midi_bound(sp->get_value());
1181 gboolean tX_seqpar::reset_midi_upper_bound(GtkWidget *widget, gpointer data) {
1182 tX_seqpar *sp=(tX_seqpar *) data;
1183 sp->reset_upper_midi_bound();
1188 gboolean tX_seqpar::set_midi_lower_bound(GtkWidget *widget, gpointer data) {
1189 tX_seqpar *sp=(tX_seqpar *) data;
1190 sp->set_lower_midi_bound(sp->get_value());
1195 gboolean tX_seqpar::reset_midi_lower_bound(GtkWidget *widget, gpointer data) {
1196 tX_seqpar *sp=(tX_seqpar *) data;
1197 sp->reset_lower_midi_bound();
1202 #endif // USE_ALSA_MIDI_IN