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 = NULL;
37 list <tX_seqpar *> *tX_seqpar :: update = NULL;
38 pthread_mutex_t tX_seqpar :: update_lock = PTHREAD_MUTEX_INITIALIZER;
40 #define tt ((vtt_class *) vtt)
42 #ifdef DEBUG_SEQPAR_LOCK
43 #define seqpar_mutex_lock(lock) { tX_debug("lock: %i", __LINE__); pthread_mutex_lock(lock); }
44 #define seqpar_mutex_unlock(lock) { tX_debug("unlock: %i", __LINE__); pthread_mutex_unlock(lock); }
46 #define seqpar_mutex_lock(lock) pthread_mutex_lock(lock)
47 #define seqpar_mutex_unlock(lock) pthread_mutex_unlock(lock)
50 tX_seqpar :: tX_seqpar () : bound_midi_event()
61 all = new list <tX_seqpar *>();
62 update = new list <tX_seqpar *>();
65 last_event_recorded=NULL;
67 midi_lower_bound_set=false;
68 midi_upper_bound_set=false;
72 void tX_seqpar :: set_mapping_parameters(float max, float min, float scale, int mappable)
80 void tX_seqpar :: handle_mouse_input(float adjustment)
84 tmpvalue=get_value()+adjustment*scale_value;
85 if (tmpvalue>max_value) tmpvalue=max_value;
86 if (tmpvalue<min_value) tmpvalue=min_value;
88 /*printf("Handling %s, max %f, min %f, scale %f, val: %f\n", get_name(), max_value, min_value, scale_value, tmpvalue);*/
90 receive_input_value(tmpvalue);
93 #ifdef USE_ALSA_MIDI_IN
94 void tX_seqpar :: handle_midi_input( const tX_midievent& event )
96 double tmpvalue = -1000;
100 if (midi_upper_bound_set) {
101 max=midi_upper_bound;
104 if (midi_lower_bound_set) {
105 min=midi_lower_bound;
109 switch (event.type) {
110 case tX_midievent::CC:
111 case tX_midievent::CC14:
112 case tX_midievent::PITCHBEND:
113 case tX_midievent::RPN:
114 case tX_midievent::NRPN:
115 tmpvalue = event.value * (max-min) + min;
117 case tX_midievent::NOTE:
118 tmpvalue = event.is_noteon;
124 if (reverse_midi) tmpvalue=(max-tmpvalue)+min;
126 if (tmpvalue>max) tmpvalue=max;
127 else if (tmpvalue<min) tmpvalue=min;
129 tmpvalue=event.value;
132 if (tmpvalue>0) tmpvalue = 0;
139 /* Not using receive() as we want immediate GUI update... */
141 record_value(tmpvalue);
142 do_update_graphics();
146 void tX_seqpar :: set_vtt (void *mytt)
151 tX_seqpar :: ~tX_seqpar()
153 seqpar_mutex_lock(&update_lock);
154 update->remove(this);
155 seqpar_mutex_unlock(&update_lock);
156 sequencer.delete_all_events_for_sp(this, tX_sequencer::DELETE_ALL);
160 void tX_seqpar :: do_touch()
162 if (sequencer.is_recording())
165 touch_timestamp=sequencer.get_timestamp();
169 void tX_seqpar :: untouch_all()
171 list <tX_seqpar *> :: iterator sp;
173 for (sp=all->begin(); sp!=all->end(); sp++) {
178 void tX_seqpar :: create_persistence_ids()
180 list <tX_seqpar *> :: iterator sp;
183 for (sp=all->begin(); sp!=all->end(); sp++) {
185 (*sp)->set_persistence_id(pid);
189 tX_seqpar* tX_seqpar :: get_sp_by_persistence_id(unsigned int pid)
191 list <tX_seqpar *> :: iterator sp;
193 for (sp=all->begin(); sp!=all->end(); sp++) {
194 if ((*sp)->get_persistence_id()==pid) return ((*sp));
197 //tX_error("failed to resolve persistence id [%i].", pid);
202 void tX_seqpar :: record_value(const float value)
204 #define last_event ((tX_event *) last_event_recorded)
206 /* recording more than one event per seqpar for
207 one timestamp doesn't make sense... so if the
208 last_event_recorded was for the current timestamp
209 we simply set that event's value to the current one.
211 if ((last_event) && (last_event->get_timestamp() == sequencer.get_timestamp())) {
212 last_event->set_value(value);
214 last_event_recorded=(void *) sequencer.record(this, value);
218 void tX_seqpar :: receive_gui_value(const float value)
227 void tX_seqpar :: receive_input_value(const float value)
234 void tX_seqpar :: receive_forward_value(const float value)
239 void tX_seqpar :: materialize_forward_values()
241 list <tX_seqpar *> :: iterator sp;
243 for (sp=all->begin(); sp!=all->end(); sp++) {
244 (*sp)->exec_value((*sp)->fwd_value);
249 const char * tX_seqpar :: get_vtt_name()
251 if (vtt) return tt->name;
252 else return "Master Track";
255 void tX_seqpar :: restore_meta(xmlNodePtr node) {
259 buffer=(char *) xmlGetProp(node, (xmlChar *) "id");
260 if (buffer) { sscanf(buffer, "%i", &persistence_id); }
261 else { tX_error("no ID for seqpar %s", this->get_name()); }
263 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiUpperBound");
265 sscanf(buffer, "%lf", &temp);
266 set_upper_midi_bound(temp);
269 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiLowerBound");
271 sscanf(buffer, "%lf", &temp);
272 set_lower_midi_bound(temp);
275 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiType");
277 if (strcmp("cc", buffer)==0) {
278 bound_midi_event.type=tX_midievent::CC;
279 } else if (strcmp("note", buffer)==0) {
280 bound_midi_event.type=tX_midievent::NOTE;
281 } else if (strcmp("pitchbend", buffer)==0) {
282 bound_midi_event.type=tX_midievent::PITCHBEND;
283 } else if (strcmp("cc14", buffer)==0) {
284 bound_midi_event.type=tX_midievent::CC14;
285 } else if (strcmp("rpn", buffer)==0) {
286 bound_midi_event.type=tX_midievent::RPN;
287 } else if (strcmp("nrpn", buffer)==0) {
288 bound_midi_event.type=tX_midievent::NRPN;
290 tX_error("unknown midiType \"%s\" for seqpar %s", buffer, this->get_name());
293 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiChannel");
294 if (buffer) { sscanf(buffer, "%i", &bound_midi_event.channel); }
295 else { tX_error("no midiChannel for seqpar %s", this->get_name()); }
297 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiNumber");
298 if (buffer) { sscanf(buffer, "%i", &bound_midi_event.number); }
299 else { tX_error("no midiNumber for seqpar %s", this->get_name()); }
302 buffer=(char *) xmlGetProp(node, (xmlChar *) "midiReverse");
304 if (strcmp("true", buffer)==0) {
311 /* else: no MIDI init.... */
314 void tX_seqpar :: store_meta(FILE *rc, gzFile rz) {
318 if (bound_midi_event.type!=tX_midievent::NONE) {
321 switch (bound_midi_event.type) {
322 case tX_midievent::NOTE: type="note"; break;
323 case tX_midievent::CC: type="cc"; break;
324 case tX_midievent::PITCHBEND: type="pitchbend"; break;
325 case tX_midievent::CC14: type="cc14"; break;
326 case tX_midievent::RPN: type="rpn"; break;
327 case tX_midievent::NRPN: type="nrpn"; break;
328 default: type="error";
330 sprintf(buffer, "id=\"%i\" midiType=\"%s\" midiChannel=\"%i\" midiNumber=\"%i\" midiReverse=\"%s\"", persistence_id, type, bound_midi_event.channel, bound_midi_event.number, (reverse_midi ? "true" : "false"));
332 sprintf(buffer, "id=\"%i\"", persistence_id);
335 if (midi_upper_bound_set) {
336 sprintf(buffer2, " midiUpperBound=\"%lf\"", midi_upper_bound);
337 strcat(buffer, buffer2);
340 if (midi_lower_bound_set) {
341 sprintf(buffer2, " midiLowerBound=\"%lf\"", midi_lower_bound);
342 strcat(buffer, buffer2);
345 tX_store("%s", buffer);
349 const char * tX_seqpar :: get_name()
351 return "This string means trouble!";
354 float tX_seqpar :: get_value()
356 printf("Ooops. tX_seqpar::get_value() called. Trouble.");
360 void tX_seqpar :: update_graphics(bool gtk_flush)
363 do_update_graphics();
365 while (gtk_events_pending()) gtk_main_iteration(); /* gtk_flush */
370 void tX_seqpar :: update_all_graphics()
372 list <tX_seqpar *> :: iterator sp;
374 seqpar_mutex_lock(&update_lock);
376 if (!update->size()) {
377 seqpar_mutex_unlock(&update_lock);
381 for (sp=update->begin(); sp!=update->end(); sp++) {
382 (*sp)->update_graphics(false);
384 update->erase(update->begin(), update->end());
385 seqpar_mutex_unlock(&update_lock);
387 while (gtk_events_pending()) gtk_main_iteration();
390 void tX_seqpar :: init_all_graphics()
392 list <tX_seqpar *> :: iterator sp;
394 seqpar_mutex_lock(&update_lock);
396 for (sp=all->begin(); sp!=all->end(); sp++) {
397 (*sp)->update_graphics();
399 seqpar_mutex_unlock(&update_lock);
401 while (gtk_events_pending()) gtk_main_iteration();
404 void tX_seqpar_update :: exec_value(const float value)
407 seqpar_mutex_lock(&update_lock);
408 update->push_front(this);
409 seqpar_mutex_unlock(&update_lock);
412 void tX_seqpar_no_update :: exec_value(const float value)
417 void tX_seqpar_no_update :: do_update_graphics()
423 void tX_seqpar_no_update_active_forward :: receive_forward_value(const float value)
429 void tX_seqpar_update_active_forward :: receive_forward_value(const float value)
437 /**** Sequencable Parameter: MASTER VOLUME ****/
439 tX_seqpar_master_volume :: tX_seqpar_master_volume()
441 set_mapping_parameters(2.5, 0, 0.1, 0);
444 void tX_seqpar_master_volume :: do_exec(const float value)
446 vtt_class :: set_master_volume(value);
449 void tX_seqpar_master_volume :: do_update_graphics ()
451 gtk_adjustment_set_value(volume_adj, vtt_class::master_volume);
454 const char * tX_seqpar_master_volume :: get_name()
456 return "Master Volume";
459 /**** Sequencable Parameter: MASTER PITCH ****/
461 tX_seqpar_master_pitch :: tX_seqpar_master_pitch()
463 set_mapping_parameters(3.0, -3.0, 0.1, 0);
466 void tX_seqpar_master_pitch :: do_exec(const float value)
468 vtt_class :: set_master_pitch(value);
471 void tX_seqpar_master_pitch :: do_update_graphics ()
473 gtk_adjustment_set_value(pitch_adj, globals.pitch);
476 const char * tX_seqpar_master_pitch :: get_name()
478 return "Master Pitch";
481 /**** Sequencable Parameter: TURNTABLE SPEED ****/
483 tX_seqpar_vtt_speed :: tX_seqpar_vtt_speed()
485 // min max scale are not required for this parameter
486 set_mapping_parameters(3.0, -3.0, 0.1, 1);
489 /* speed works differently so we need an extra input-handler */
491 void tX_seqpar_vtt_speed :: handle_mouse_input(float adjustment)
493 if (tt->do_scratch) tt->sp_speed.receive_input_value(adjustment);
494 tt->sense_cycles=globals.sense_cycles;
497 void tX_seqpar_vtt_speed :: do_exec(const float value)
499 tt->speed=value*tt->audiofile_pitch_correction;
502 const char * tX_seqpar_vtt_speed :: get_name()
504 return "Speed (Scratching)";
507 /**** Sequencable Parameter: TURNTABLE SPIN ****/
509 tX_seqpar_spin :: tX_seqpar_spin()
511 set_mapping_parameters(1, 0, 0, 0);
514 void tX_seqpar_spin :: do_exec(const float value)
516 if (value > 0) tt->speed=tt->res_pitch;
520 const char * tX_seqpar_spin :: get_name()
522 return "Motor Spin (On/Off)";
525 /**** Sequencable Parameter: TURNTABLE VOLUME ****/
527 tX_seqpar_vtt_volume :: tX_seqpar_vtt_volume()
529 set_mapping_parameters(2.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
532 float tX_seqpar_vtt_volume :: get_value(){ return tt->rel_volume; }
534 void tX_seqpar_vtt_volume :: do_exec(const float value)
536 tt->set_volume(value);
539 void tX_seqpar_vtt_volume :: do_update_graphics ()
541 gtk_adjustment_set_value(tt->gui.volume, 2.0-tt->rel_volume);
544 const char * tX_seqpar_vtt_volume :: get_name()
549 /**** Sequencable Parameter : Pan ****/
551 tX_seqpar_vtt_pan :: tX_seqpar_vtt_pan()
553 set_mapping_parameters(1.0, -1.0, TX_SEQPAR_DEFAULT_SCALE, 1);
556 float tX_seqpar_vtt_pan :: get_value(){ return tt->pan; }
558 void tX_seqpar_vtt_pan :: do_exec(const float value)
563 void tX_seqpar_vtt_pan :: do_update_graphics ()
565 gtk_adjustment_set_value(tt->gui.pan, tt->pan);
568 const char * tX_seqpar_vtt_pan :: get_name()
573 /**** Sequencable Parameter: TURNTABLE PITCH ****/
575 tX_seqpar_vtt_pitch :: tX_seqpar_vtt_pitch()
577 set_mapping_parameters(3.0, -3.0, TX_SEQPAR_DEFAULT_SCALE, 1);
580 float tX_seqpar_vtt_pitch :: get_value(){ return tt->rel_pitch; }
582 void tX_seqpar_vtt_pitch :: do_exec(const float value)
584 tt->set_pitch(value);
587 void tX_seqpar_vtt_pitch :: do_update_graphics ()
589 gtk_adjustment_set_value(tt->gui.pitch, tt->rel_pitch);
592 const char * tX_seqpar_vtt_pitch :: get_name()
597 /**** Sequencable Parameter: TURNTABLE TRIGGER ****/
599 tX_seqpar_vtt_trigger :: tX_seqpar_vtt_trigger()
601 set_mapping_parameters(0.01, 0, 1, 1);
605 void tX_seqpar_vtt_trigger :: do_exec(const float value)
607 if (value > 0) tt->trigger();
611 const char * tX_seqpar_vtt_trigger :: get_name()
613 return "Trigger (Start/Stop)";
616 /**** Sequencable Parameter: TURNTABLE LOOP ****/
618 tX_seqpar_vtt_loop :: tX_seqpar_vtt_loop()
620 set_mapping_parameters(0, 0, 0, 0);
625 void tX_seqpar_vtt_loop :: do_exec(const float value)
627 tt->set_loop(value>0);
630 const char * tX_seqpar_vtt_loop :: get_name()
632 return "Loop (On/Off)";
635 void tX_seqpar_vtt_loop :: do_update_graphics ()
637 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.loop), tt->loop);
640 /**** Sequencable Parameter: TURNTABLE SYNC CLIENT ****/
642 tX_seqpar_vtt_sync_client :: tX_seqpar_vtt_sync_client()
644 set_mapping_parameters(0,0,0,0);
648 void tX_seqpar_vtt_sync_client :: do_exec(const float value)
650 tt->set_sync_client((value>0), tt->sync_cycles);
653 void tX_seqpar_vtt_sync_client :: do_update_graphics ()
655 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.sync_client), tt->is_sync_client);
658 const char * tX_seqpar_vtt_sync_client :: get_name()
660 return "Sync Client (On/Off)";
663 /**** Sequencable Parameter: TURNTABLE SYNC CYCLES ****/
665 tX_seqpar_vtt_sync_cycles :: tX_seqpar_vtt_sync_cycles()
667 set_mapping_parameters(0,0,0,0);
670 void tX_seqpar_vtt_sync_cycles :: do_exec(const float value)
672 tt->set_sync_client(tt->is_sync_client, (int) value);
675 void tX_seqpar_vtt_sync_cycles :: do_update_graphics ()
677 gtk_adjustment_set_value(tt->gui.cycles, tt->sync_cycles);
680 const char * tX_seqpar_vtt_sync_cycles :: get_name()
682 return "Sync Cycles";
685 /**** Sequencable Parameter: TURNTABLE LP ENABLE ****/
687 tX_seqpar_vtt_lp_enable :: tX_seqpar_vtt_lp_enable()
689 set_mapping_parameters(0.01,0,1,1);
693 void tX_seqpar_vtt_lp_enable :: do_exec(const float value)
695 tt->lp_set_enable(value>0);
698 void tX_seqpar_vtt_lp_enable :: do_update_graphics ()
700 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.lp_enable), tt->lp_enable);
703 const char * tX_seqpar_vtt_lp_enable :: get_name()
705 return "Lowpass: Enable (On/Off)";
708 /**** Sequencable Parameter: TURNTABLE LP GAIN ****/
710 tX_seqpar_vtt_lp_gain :: tX_seqpar_vtt_lp_gain()
712 set_mapping_parameters(2.0,0, TX_SEQPAR_DEFAULT_SCALE, 1);
715 float tX_seqpar_vtt_lp_gain :: get_value() { return tt->lp_gain; }
717 void tX_seqpar_vtt_lp_gain :: do_exec(const float value)
719 tt->lp_set_gain(value);
722 const char * tX_seqpar_vtt_lp_gain :: get_name()
724 return "Lowpass: Input Gain";
727 void tX_seqpar_vtt_lp_gain :: do_update_graphics ()
729 gtk_adjustment_set_value(tt->gui.lp_gain, tt->lp_gain);
732 /**** Sequencable Parameter: TURNTABLE LP RESO ****/
734 tX_seqpar_vtt_lp_reso :: tX_seqpar_vtt_lp_reso()
736 set_mapping_parameters(0.99, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
739 float tX_seqpar_vtt_lp_reso :: get_value() { return tt->lp_reso; }
741 void tX_seqpar_vtt_lp_reso :: do_exec(const float value)
743 tt->lp_set_reso(value);
746 void tX_seqpar_vtt_lp_reso :: do_update_graphics ()
748 gtk_adjustment_set_value(tt->gui.lp_reso, tt->lp_reso);
751 const char * tX_seqpar_vtt_lp_reso :: get_name()
753 return "Lowpass: Resonance";
756 /**** Sequencable Parameter: TURNTABLE LP FREQUENCY ****/
758 tX_seqpar_vtt_lp_freq :: tX_seqpar_vtt_lp_freq()
760 set_mapping_parameters(0.99, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
763 float tX_seqpar_vtt_lp_freq :: get_value() { return tt->lp_freq; }
765 void tX_seqpar_vtt_lp_freq :: do_exec(const float value)
767 tt->lp_set_freq(value);
770 const char * tX_seqpar_vtt_lp_freq :: get_name()
772 return "Lowpass: Cutoff Frequency";
775 void tX_seqpar_vtt_lp_freq :: do_update_graphics ()
777 gtk_adjustment_set_value(tt->gui.lp_freq, tt->lp_freq);
780 /**** Sequencable Parameter: TURNTABLE ECHO ENABLE ****/
782 tX_seqpar_vtt_ec_enable :: tX_seqpar_vtt_ec_enable()
784 set_mapping_parameters(0.01,0,1,1);
788 void tX_seqpar_vtt_ec_enable :: do_exec(const float value)
790 tt->ec_set_enable(value>0);
793 void tX_seqpar_vtt_ec_enable :: do_update_graphics ()
795 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.ec_enable), tt->ec_enable);
798 const char * tX_seqpar_vtt_ec_enable :: get_name()
800 return "Echo: Enable (On/Off)";
803 /**** Sequencable Parameter: TURNTABLE ECHO LENGTH ****/
805 tX_seqpar_vtt_ec_length :: tX_seqpar_vtt_ec_length()
807 set_mapping_parameters(1.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
810 float tX_seqpar_vtt_ec_length :: get_value() { return tt->ec_length; }
812 void tX_seqpar_vtt_ec_length :: do_exec(const float value)
814 tt->ec_set_length(value);
817 void tX_seqpar_vtt_ec_length :: do_update_graphics ()
819 gtk_adjustment_set_value(tt->gui.ec_length, tt->ec_length);
822 const char * tX_seqpar_vtt_ec_length :: get_name()
824 return "Echo: Duration";
827 /**** Sequencable Parameter: TURNTABLE ECHO FEEDBACK ****/
829 tX_seqpar_vtt_ec_feedback :: tX_seqpar_vtt_ec_feedback()
831 set_mapping_parameters(1.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
834 float tX_seqpar_vtt_ec_feedback :: get_value() { return tt->ec_feedback; }
836 void tX_seqpar_vtt_ec_feedback :: do_exec(const float value)
838 tt->ec_set_feedback(value);
841 void tX_seqpar_vtt_ec_feedback :: do_update_graphics ()
843 gtk_adjustment_set_value(tt->gui.ec_feedback, tt->ec_feedback);
846 const char * tX_seqpar_vtt_ec_feedback :: get_name()
848 return "Echo: Feedback";
851 /**** Sequencable Parameter: TURNTABLE ECHO PAN ****/
853 tX_seqpar_vtt_ec_pan :: tX_seqpar_vtt_ec_pan()
855 set_mapping_parameters(1.0, -1.0, TX_SEQPAR_DEFAULT_SCALE, 1);
858 float tX_seqpar_vtt_ec_pan :: get_value() { return tt->ec_pan; }
860 void tX_seqpar_vtt_ec_pan :: do_exec(const float value)
862 tt->ec_set_pan(value);
865 void tX_seqpar_vtt_ec_pan :: do_update_graphics ()
867 gtk_adjustment_set_value(tt->gui.ec_pan, tt->ec_pan);
870 const char * tX_seqpar_vtt_ec_pan :: get_name()
875 /**** Sequencable Parameter: TURNTABLE ECHO VOLUME ****/
877 tX_seqpar_vtt_ec_volume :: tX_seqpar_vtt_ec_volume()
879 set_mapping_parameters(0.0, 3.0, TX_SEQPAR_DEFAULT_SCALE, 1);
882 float tX_seqpar_vtt_ec_volume :: get_value() { return tt->ec_volume; }
884 void tX_seqpar_vtt_ec_volume :: do_exec(const float value)
886 tt->ec_set_volume(value);
889 void tX_seqpar_vtt_ec_volume :: do_update_graphics ()
891 gtk_adjustment_set_value(tt->gui.ec_volume, tt->ec_volume);
894 const char * tX_seqpar_vtt_ec_volume :: get_name()
896 return "Echo: Volume";
900 /**** Sequencable Parameter: TURNTABLE MUTE ****/
902 tX_seqpar_vtt_mute :: tX_seqpar_vtt_mute()
904 set_mapping_parameters(0.01,0,1,1);
908 void tX_seqpar_vtt_mute :: do_exec(const float value)
910 tt->set_mute(value>0);
913 const char * tX_seqpar_vtt_mute :: get_name()
915 return "Mute (On/Off)";
918 /** LADSPA fx parameters **/
920 tX_seqpar_vttfx :: tX_seqpar_vttfx()
922 fx_value=(float *) malloc(sizeof(float));
924 set_mapping_parameters(0,0,0,0);
927 tX_seqpar_vttfx :: ~tX_seqpar_vttfx()
932 void tX_seqpar_vttfx :: set_name(const char *n, const char *sn)
935 strcpy(label_name, sn);
939 float tX_seqpar_vttfx :: get_value()
944 void tX_seqpar_vttfx :: create_widget()
946 fprintf(stderr, "tX: Ooops. create_widget() for tX_seqpar_vttfx.\n");
949 const char * tX_seqpar_vttfx :: get_name()
954 void tX_seqpar_vttfx_float :: create_widget()
956 float tmp=max_value - min_value/1000;
959 //myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value+tmp/10, max_value-tmp/10, tmp, tmp, tmp));
960 myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value, max_value, tmp, tmp, tmp));
961 mydial=new tX_extdial(label_name, myadj, this);
962 g_signal_connect(G_OBJECT(myadj), "value_changed", (GtkSignalFunc) tX_seqpar_vttfx_float :: gtk_callback, this);
963 widget = mydial->get_widget();
966 tX_seqpar_vttfx_float :: ~tX_seqpar_vttfx_float()
971 void tX_seqpar_vttfx_float :: do_exec(const float value)
976 void tX_seqpar_vttfx_float :: do_update_graphics()
978 gtk_adjustment_set_value(myadj, *fx_value);
981 GtkSignalFunc tX_seqpar_vttfx_float :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_float *sp)
983 sp->receive_gui_value(sp->myadj->value);
987 #define WID_DYN TRUE, TRUE, 0
988 #define WID_FIX FALSE, FALSE, 0
990 void tX_seqpar_vttfx_int :: create_widget()
995 myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value, max_value, 1, 10, 0));
996 GtkWidget *box=gtk_vbox_new(FALSE, 2);
998 tmpwid=gtk_spin_button_new(myadj,1.0,0);
999 gtk_widget_show(tmpwid);
1000 gtk_box_pack_start(GTK_BOX(box), tmpwid, WID_DYN);
1001 g_signal_connect(G_OBJECT(tmpwid), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, this);
1003 g_signal_connect(G_OBJECT(myadj), "value_changed", (GtkSignalFunc) tX_seqpar_vttfx_int :: gtk_callback, this);
1005 tmpwid=gtk_label_new(label_name);
1006 gtk_widget_show(tmpwid);
1007 gtk_box_pack_start(GTK_BOX(box), tmpwid, WID_FIX);
1009 gtk_widget_show(box);
1011 widget=gtk_event_box_new();
1012 g_signal_connect(G_OBJECT(widget), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, this);
1014 gtk_container_add(GTK_CONTAINER(widget), box);
1017 tX_seqpar_vttfx_int :: ~tX_seqpar_vttfx_int()
1019 gtk_widget_destroy(widget);
1022 void tX_seqpar_vttfx_int :: do_exec(const float value)
1027 void tX_seqpar_vttfx_int :: do_update_graphics()
1029 gtk_adjustment_set_value(myadj, *fx_value);
1032 GtkSignalFunc tX_seqpar_vttfx_int :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_int *sp)
1034 sp->receive_gui_value(sp->myadj->value);
1038 void tX_seqpar_vttfx_bool :: create_widget()
1040 *fx_value=min_value;
1041 widget=gtk_check_button_new_with_label(label_name);
1042 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), 0);
1043 g_signal_connect(G_OBJECT(widget), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, this);
1044 g_signal_connect(G_OBJECT(widget), "clicked", (GtkSignalFunc) tX_seqpar_vttfx_bool :: gtk_callback, this);
1047 tX_seqpar_vttfx_bool :: ~tX_seqpar_vttfx_bool()
1049 gtk_widget_destroy(widget);
1052 void tX_seqpar_vttfx_bool :: do_exec(const float value)
1057 GtkSignalFunc tX_seqpar_vttfx_bool :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_bool *sp)
1059 sp->receive_gui_value(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sp->widget)));
1063 void tX_seqpar_vttfx_bool :: do_update_graphics()
1065 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), *fx_value==max_value);
1068 gboolean tX_seqpar::tX_seqpar_press(GtkWidget *widget, GdkEventButton *event, gpointer data) {
1069 tX_seqpar *sp=(tX_seqpar *) data;
1071 if (event->button==3) {
1072 GtkWidget *menu=gtk_menu_new();
1074 GtkWidget *item=gtk_menu_item_new_with_label(sp->get_name());
1075 gtk_widget_set_sensitive(item, FALSE);
1076 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1077 gtk_widget_show(item);
1079 item = gtk_menu_item_new();
1080 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1081 gtk_widget_set_sensitive (item, FALSE);
1082 gtk_widget_show (item);
1084 item = gtk_menu_item_new_with_label("MIDI Learn");
1085 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1086 gtk_widget_show(item);
1087 #ifdef USE_ALSA_MIDI_IN
1088 g_signal_connect(item, "activate", (GCallback) tX_seqpar::learn_midi_binding, sp);
1090 gtk_widget_set_sensitive(item, FALSE);
1094 item = gtk_menu_item_new_with_label("Remove MIDI Binding");
1095 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1096 gtk_widget_show(item);
1098 if (sp->bound_midi_event.type==tX_midievent::NONE) {
1099 gtk_widget_set_sensitive(item, FALSE);
1101 #ifdef USE_ALSA_MIDI_IN
1102 g_signal_connect(item, "activate", (GCallback) tX_seqpar::remove_midi_binding, sp);
1104 gtk_widget_set_sensitive(item, FALSE);
1107 item = gtk_check_menu_item_new_with_label("Map MIDI Reverse");
1108 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1109 gtk_widget_show(item);
1111 if (sp->bound_midi_event.type==tX_midievent::NONE) {
1112 gtk_widget_set_sensitive(item, FALSE);
1115 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), sp->get_reverse_midi());
1117 #ifdef USE_ALSA_MIDI_IN
1118 g_signal_connect(item, "activate", (GCallback) tX_seqpar::reverse_midi_binding, sp);
1120 gtk_widget_set_sensitive(item, FALSE);
1123 if (!sp->is_boolean) {
1124 item = gtk_menu_item_new();
1125 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1126 gtk_widget_set_sensitive(item, FALSE);
1127 gtk_widget_show(item);
1129 item = gtk_menu_item_new_with_label("Set Upper MIDI Bound");
1130 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1131 gtk_widget_show(item);
1133 #ifdef USE_ALSA_MIDI_IN
1134 g_signal_connect(item, "activate", (GCallback) tX_seqpar::set_midi_upper_bound, sp);
1136 gtk_widget_set_sensitive(item, FALSE);
1139 item = gtk_menu_item_new_with_label("Reset Upper MIDI Bound");
1140 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1141 gtk_widget_show(item);
1142 #ifdef USE_ALSA_MIDI_IN
1143 g_signal_connect(item, "activate", (GCallback) tX_seqpar::reset_midi_upper_bound, sp);
1145 gtk_widget_set_sensitive(item, FALSE);
1148 if (!sp->midi_upper_bound_set) {
1149 gtk_widget_set_sensitive(item, FALSE);
1152 item = gtk_menu_item_new_with_label("Set Lower MIDI Bound");
1153 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1154 gtk_widget_show(item);
1155 #ifdef USE_ALSA_MIDI_IN
1156 g_signal_connect(item, "activate", (GCallback) tX_seqpar::set_midi_lower_bound, sp);
1158 gtk_widget_set_sensitive(item, FALSE);
1161 item = gtk_menu_item_new_with_label("Reset Lower MIDI Bound");
1162 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1163 gtk_widget_show(item);
1164 #ifdef USE_ALSA_MIDI_IN
1165 g_signal_connect(item, "activate", (GCallback) tX_seqpar::reset_midi_lower_bound, sp);
1167 gtk_widget_set_sensitive(item, FALSE);
1170 if (!sp->midi_lower_bound_set) {
1171 gtk_widget_set_sensitive(item, FALSE);
1175 item = gtk_menu_item_new();
1176 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1177 gtk_widget_set_sensitive (item, FALSE);
1178 gtk_widget_show (item);
1180 item = gtk_menu_item_new_with_label("Delete Sequencer Events");
1181 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1182 gtk_widget_show(item);
1183 g_signal_connect(item, "activate", (GCallback) menu_delete_all_events_for_sp, sp);
1185 gtk_widget_show(menu);
1187 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);
1188 //gtk_grab_remove(gtk_grab_get_current());
1196 #ifdef USE_ALSA_MIDI_IN
1197 gboolean tX_seqpar::reverse_midi_binding(GtkWidget *widget, gpointer data) {
1198 tX_seqpar *sp=(tX_seqpar *) data;
1199 sp->set_reverse_midi(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)));
1204 gboolean tX_seqpar::remove_midi_binding(GtkWidget *widget, gpointer data) {
1205 tX_seqpar *sp=(tX_seqpar *) data;
1207 sp->bound_midi_event.type=tX_midievent::NONE;
1208 sp->bound_midi_event.number=0;
1209 sp->bound_midi_event.channel=0;
1214 gboolean tX_seqpar::learn_midi_binding(GtkWidget *widget, gpointer data) {
1215 tX_seqpar *sp=(tX_seqpar *) data;
1217 tX_engine::get_instance()->get_midi()->set_midi_learn_sp(sp);
1222 gboolean tX_seqpar::set_midi_upper_bound(GtkWidget *widget, gpointer data) {
1223 tX_seqpar *sp=(tX_seqpar *) data;
1224 sp->set_upper_midi_bound(sp->get_value());
1229 gboolean tX_seqpar::reset_midi_upper_bound(GtkWidget *widget, gpointer data) {
1230 tX_seqpar *sp=(tX_seqpar *) data;
1231 sp->reset_upper_midi_bound();
1236 gboolean tX_seqpar::set_midi_lower_bound(GtkWidget *widget, gpointer data) {
1237 tX_seqpar *sp=(tX_seqpar *) data;
1238 sp->set_lower_midi_bound(sp->get_value());
1243 gboolean tX_seqpar::reset_midi_lower_bound(GtkWidget *widget, gpointer data) {
1244 tX_seqpar *sp=(tX_seqpar *) data;
1245 sp->reset_lower_midi_bound();
1250 #endif // USE_ALSA_MIDI_IN