Including Darrick's Anit-Clip-Device and limiting Lowpass Freq to 0.99
[terminatorX.git] / src / tX_seqpar.cc
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999, 2000 Alexander K├Ânig
4  
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.
9  
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.
14  
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.
18  
19     File: tX_seqpar.cc
20  
21     Description: This implements the "sequenceable parameters".
22 */    
23
24 #include "tX_seqpar.h"
25 #include "tX_vtt.h"
26 #include <stdio.h>
27 #include "tX_mastergui.h"
28 #include "tX_global.h"
29 #include "tX_sequencer.h"
30 #include "tX_extdial.h"
31 #include <malloc.h>
32
33 #define TX_SEQPAR_DEFAULT_SCALE 0.05
34
35 list <tX_seqpar *> tX_seqpar :: all;
36 list <tX_seqpar *> tX_seqpar :: update;
37 pthread_mutex_t tX_seqpar :: update_lock = PTHREAD_MUTEX_INITIALIZER;
38
39 #define tt ((vtt_class *) vtt)
40
41 void tX_seqpar :: default_constructor()
42 {
43         touched=0;
44         gui_active=1;
45         vtt=NULL;
46         max_value=0;
47         min_value=0;
48         scale_value=0;
49         is_boolean=false;
50         is_mappable=1;
51         all.push_back(this);
52         last_event_recorded=NULL;
53 }
54
55 tX_seqpar :: tX_seqpar ()
56 {
57         default_constructor();
58 }
59
60 /*
61 tX_seqpar :: tX_seqpar (void * mytt)
62 {
63         default_constructor();
64         vtt=mytt;
65 }
66
67 tX_seqpar :: tX_seqpar (float max, float min, float scale, int mappable)
68 {
69         default_constructor();
70         max_value=max;
71         min_value=min;
72         scale_value=scale;
73         is_mappable=mappable;
74 }*/
75
76 void tX_seqpar :: set_mapping_parameters(float max, float min, float scale, int mappable)
77 {
78         max_value=max;
79         min_value=min;
80         scale_value=scale;
81         is_mappable=mappable;
82 }
83
84 /*
85 tX_seqpar :: tX_seqpar (void *mytt, float max, float min, float scale, int mappable)
86 {
87         default_constructor();
88         vtt=mytt;
89         max_value=max;
90         min_value=min;
91         scale_value=scale;
92         is_mappable=mappable;   
93 }
94 */
95
96 void tX_seqpar :: handle_mouse_input(float adjustment)
97 {
98         float tmpvalue;
99         
100         tmpvalue=get_value()+adjustment*scale_value;
101         if (tmpvalue>max_value) tmpvalue=max_value;
102         if (tmpvalue<min_value) tmpvalue=min_value;
103         
104         /*printf("Handling %s, max %f, min %f, scale %f,  val: %f\n", get_name(), max_value, min_value, scale_value, tmpvalue);*/
105         
106         receive_input_value(tmpvalue);
107 }
108
109 #ifdef USE_ALSA_MIDI_IN
110 void tX_seqpar :: handle_midi_input( const tX_midievent& event )
111 {
112         float tmpvalue = -1000;
113
114         //event.print( (string(__FUNCTION__) + " - " + get_name()).c_str() );
115         
116         if( !is_boolean )
117         {
118                 if( event.type == tX_midievent::CC || event.type == tX_midievent::PITCHBEND )
119                 {       
120                         tmpvalue = event.value * (max_value-min_value) + min_value;
121                 }
122                 else if( event.type == tX_midievent::NOTE )
123                 {
124                         tmpvalue = event.is_noteon;
125                 }
126                 else
127                 {
128                         return;
129                 }
130
131                 if (tmpvalue>max_value) tmpvalue=max_value;
132                 if (tmpvalue<min_value) tmpvalue=min_value;
133         }
134         else
135         {
136                 tmpvalue=event.value;
137         }
138                 
139         receive_input_value(tmpvalue);
140 }
141 #endif
142
143 void tX_seqpar :: set_vtt (void *mytt)
144 {
145         vtt=mytt;
146 }
147
148 tX_seqpar :: ~tX_seqpar()
149 {
150         pthread_mutex_lock(&update_lock);
151         update.remove(this);
152         pthread_mutex_unlock(&update_lock);
153         sequencer.delete_all_events_for_sp(this);
154         all.remove(this);
155 }
156
157 void tX_seqpar :: do_touch()
158 {
159         if (sequencer.is_recording())
160         {
161                 touched=1;
162                 touch_timestamp=sequencer.get_timestamp();
163         }
164 }
165
166 void tX_seqpar :: untouch_all()
167 {
168         list <tX_seqpar *> :: iterator sp;
169         
170         for (sp=all.begin(); sp!=all.end(); sp++)
171         {
172                 (*sp)->untouch();
173         }
174 }
175
176 void tX_seqpar :: create_persistence_ids()
177 {
178         list <tX_seqpar *> :: iterator sp;
179         int pid=0;
180         
181         for (sp=all.begin(); sp!=all.end(); sp++)
182         {
183                 pid++;
184                 (*sp)->set_persistence_id(pid);
185         }
186 }
187
188 tX_seqpar* tX_seqpar :: get_sp_by_persistence_id(unsigned int pid)
189 {
190         list <tX_seqpar *> :: iterator sp;
191         
192         for (sp=all.begin(); sp!=all.end(); sp++)
193         {
194                 if ((*sp)->get_persistence_id()==pid) return ((*sp));
195         }
196         
197         fprintf (stderr, "oops: failed to lookup persistence id [%i].\n", pid); 
198         return (NULL);
199 }
200
201
202 void tX_seqpar :: record_value(const float value)
203 {
204 #define last_event ((tX_event *) last_event_recorded)
205
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.
210         */
211         if ((last_event) && (last_event->get_timestamp() == sequencer.get_timestamp()))
212         {
213                 last_event->set_value(value);
214         }
215         else last_event_recorded=(void *) sequencer.record(this, value);
216 }
217
218 void tX_seqpar :: receive_gui_value(const float value)
219 {
220         if (gui_active)
221         {
222                 touch();
223                 do_exec(value);
224                 record_value(value);
225         }
226 }
227
228 void tX_seqpar :: receive_input_value(const float value)
229 {
230         touch();
231         exec_value(value);
232         record_value(value);
233 }
234
235 void tX_seqpar :: receive_forward_value(const float value)
236 {
237         fwd_value=value;
238 }
239
240 void tX_seqpar :: materialize_forward_values()
241 {
242         list <tX_seqpar *> :: iterator sp;
243         
244         for (sp=all.begin(); sp!=all.end(); sp++)
245         {
246                 (*sp)->exec_value((*sp)->fwd_value);
247         }       
248         gdk_flush();
249 }
250
251 char * tX_seqpar :: get_vtt_name()
252 {       
253         if (vtt) return tt->name;
254         else return "Master Track";
255 }
256
257 const char * tX_seqpar :: get_name()
258 {
259         return "This string means trouble!";
260 }
261
262 float tX_seqpar :: get_value()
263 {
264         printf("Ooops. tX_seqpar::get_value() called. Trouble.");
265         return 0.0;     
266 }
267
268 void tX_seqpar :: do_exec(const float value)
269 {
270         fprintf(stderr, "oops: called do_exec() of tX_seqpar.\n");
271 }
272
273 void tX_seqpar :: exec_value(const float value)
274 {
275         fprintf(stderr, "oops: called exec_value() of tX_seqpar.\n");
276 }
277
278 void tX_seqpar :: do_update_graphics()
279 {
280         fprintf(stderr, "oops: called do_update_graphics() of tX_seqpar.\n");
281 }
282
283 void tX_seqpar :: update_graphics()
284 {
285         gui_active=0;
286         do_update_graphics();
287         while (gtk_events_pending()) gtk_main_iteration();      /* gtk_flush */
288         gui_active=1;
289 }
290
291 void tX_seqpar :: update_all_graphics()
292 {
293         list <tX_seqpar *> :: iterator sp;
294
295         pthread_mutex_lock(&update_lock);
296
297         if (!update.size())
298         {
299                 pthread_mutex_unlock(&update_lock);
300                 return; 
301         }
302         
303         while (gtk_events_pending()) gtk_main_iteration();      
304         for (sp=update.begin(); sp!=update.end(); sp++)
305         {
306                 (*sp)->update_graphics();
307         }
308         update.erase(update.begin(), update.end());
309         pthread_mutex_unlock(&update_lock);
310 }
311
312 void tX_seqpar :: init_all_graphics()
313 {
314         list <tX_seqpar *> :: iterator sp;
315
316         pthread_mutex_lock(&update_lock);
317         
318         for (sp=all.begin(); sp!=all.end(); sp++)
319         {
320                 (*sp)->update_graphics();
321         }
322         while (gtk_events_pending()) gtk_main_iteration();      
323
324         pthread_mutex_unlock(&update_lock);
325 }
326
327 void tX_seqpar_update :: exec_value(const float value)
328 {
329         do_exec(value);
330         pthread_mutex_lock(&update_lock);
331         update.push_front(this);
332         pthread_mutex_unlock(&update_lock);
333 }
334
335 void tX_seqpar_no_update :: exec_value(const float value)
336 {
337         do_exec(value);
338 }
339
340 void tX_seqpar_no_update :: do_update_graphics()
341 {
342         /* NOP */
343 }
344
345
346 void tX_seqpar_no_update_active_forward :: receive_forward_value(const float value)
347 {
348         fwd_value=value;
349         do_exec(value);
350 }       
351
352 void tX_seqpar_update_active_forward :: receive_forward_value(const float value)
353 {
354         fwd_value=value;
355         do_exec(value);
356 }
357
358 /* "real" classes */
359
360 /**** Sequencable Parameter: MASTER VOLUME ****/
361
362 tX_seqpar_master_volume :: tX_seqpar_master_volume()
363 {
364         set_mapping_parameters(2.5, 0, 0.1, 0);
365 }
366
367 void tX_seqpar_master_volume :: do_exec(const float value)
368 {
369         vtt_class :: set_master_volume(value);
370 }
371
372 void tX_seqpar_master_volume :: do_update_graphics ()
373 {
374         gtk_adjustment_set_value(volume_adj, vtt_class::master_volume);
375 }
376
377 const char * tX_seqpar_master_volume :: get_name()
378 {
379         return "Master Volume";
380 }
381
382 /**** Sequencable Parameter: MASTER PITCH ****/
383
384 tX_seqpar_master_pitch :: tX_seqpar_master_pitch()
385 {
386         set_mapping_parameters(3.0, -3.0, 0.1, 0);
387 }
388
389 void tX_seqpar_master_pitch :: do_exec(const float value)
390 {
391         vtt_class :: set_master_pitch(value);
392 }
393
394 void tX_seqpar_master_pitch :: do_update_graphics ()
395 {
396         gtk_adjustment_set_value(pitch_adj, globals.pitch);
397 }
398
399 const char * tX_seqpar_master_pitch :: get_name()
400 {
401         return "Master Pitch";
402 }
403
404 /**** Sequencable Parameter: TURNTABLE SPEED ****/
405
406 tX_seqpar_vtt_speed :: tX_seqpar_vtt_speed()
407 {
408         // min max scale are not required for this parameter
409         set_mapping_parameters(3.0, -3.0, 0.1, 1);
410 }
411
412 /* speed works differently so we need an extra input-handler */
413
414 void tX_seqpar_vtt_speed :: handle_mouse_input(float adjustment)
415 {
416         if (tt->do_scratch) tt->sp_speed.receive_input_value(adjustment);
417         tt->sense_cycles=globals.sense_cycles;
418 }
419
420 void tX_seqpar_vtt_speed :: do_exec(const float value)
421 {
422         tt->speed=value*tt->audiofile_pitch_correction;
423 }
424
425 const char * tX_seqpar_vtt_speed :: get_name()
426 {
427         return "Speed (Scratching)";
428 }
429
430 /**** Sequencable Parameter: TURNTABLE SPIN ****/
431
432 tX_seqpar_spin :: tX_seqpar_spin()
433 {
434         set_mapping_parameters(1, 0, 0, 0);
435 }
436
437 void tX_seqpar_spin :: do_exec(const float value)
438 {
439         if (value > 0) tt->speed=tt->res_pitch;
440         else tt->speed=0;
441 }
442
443 const char * tX_seqpar_spin :: get_name()
444 {
445         return "Motor Spin (On/Off)";
446 }
447
448 /**** Sequencable Parameter: TURNTABLE VOLUME ****/
449
450 tX_seqpar_vtt_volume :: tX_seqpar_vtt_volume()
451 {
452         set_mapping_parameters(2.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
453 }
454
455 float tX_seqpar_vtt_volume :: get_value(){ return tt->rel_volume; }
456
457 void tX_seqpar_vtt_volume :: do_exec(const float value)
458 {
459         tt->set_volume(value);
460 }
461
462 void tX_seqpar_vtt_volume :: do_update_graphics ()
463 {
464         gtk_adjustment_set_value(tt->gui.volume, 2.0-tt->rel_volume);
465 }
466
467 const char * tX_seqpar_vtt_volume :: get_name()
468 {
469         return "Volume";
470 }
471
472 /**** Sequencable Parameter : Pan ****/
473
474 tX_seqpar_vtt_pan :: tX_seqpar_vtt_pan()
475 {
476         set_mapping_parameters(1.0, -1.0, TX_SEQPAR_DEFAULT_SCALE, 1);
477 }
478
479 float tX_seqpar_vtt_pan :: get_value(){ return tt->pan; }
480
481 void tX_seqpar_vtt_pan :: do_exec(const float value)
482 {
483         tt->set_pan(value);
484 }
485
486 void tX_seqpar_vtt_pan :: do_update_graphics ()
487 {
488         gtk_adjustment_set_value(tt->gui.pan, tt->pan);
489 }
490
491 const char * tX_seqpar_vtt_pan :: get_name()
492 {
493         return "Pan";
494 }
495
496 /**** Sequencable Parameter: TURNTABLE PITCH ****/
497
498 tX_seqpar_vtt_pitch :: tX_seqpar_vtt_pitch()
499 {
500         set_mapping_parameters(3.0, -3.0, TX_SEQPAR_DEFAULT_SCALE, 1);
501 }
502
503 float tX_seqpar_vtt_pitch :: get_value(){ return tt->rel_pitch; }
504
505 void tX_seqpar_vtt_pitch :: do_exec(const float value)
506 {
507         tt->set_pitch(value);
508 }
509
510 void tX_seqpar_vtt_pitch :: do_update_graphics ()
511 {
512         gtk_adjustment_set_value(tt->gui.pitch, tt->rel_pitch);
513 }
514
515 const char * tX_seqpar_vtt_pitch :: get_name()
516 {
517         return "Pitch";
518 }
519
520 /**** Sequencable Parameter: TURNTABLE TRIGGER ****/
521
522 tX_seqpar_vtt_trigger :: tX_seqpar_vtt_trigger()
523 {
524         set_mapping_parameters(0.01, 0, 1, 1);
525         is_boolean=true;
526 }
527
528 void tX_seqpar_vtt_trigger :: do_exec(const float value)
529 {
530         if (value > 0) tt->trigger();
531         else tt->stop();
532 }
533
534 const char * tX_seqpar_vtt_trigger :: get_name()
535 {
536         return "Trigger (Start/Stop)";
537 }
538
539 /**** Sequencable Parameter: TURNTABLE LOOP ****/
540
541 tX_seqpar_vtt_loop :: tX_seqpar_vtt_loop()
542 {
543         set_mapping_parameters(0, 0, 0, 0);
544         
545         is_boolean=true;
546 }
547
548 void tX_seqpar_vtt_loop :: do_exec(const float value)
549 {
550         tt->set_loop(value>0);
551 }
552
553 const char * tX_seqpar_vtt_loop :: get_name()
554 {
555         return "Loop (On/Off)";
556 }
557
558 void tX_seqpar_vtt_loop :: do_update_graphics ()
559 {
560         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.loop), tt->loop);
561 }
562
563 /**** Sequencable Parameter: TURNTABLE SYNC CLIENT ****/
564
565 tX_seqpar_vtt_sync_client :: tX_seqpar_vtt_sync_client()
566 {
567         set_mapping_parameters(0,0,0,0);
568 }
569
570 void tX_seqpar_vtt_sync_client :: do_exec(const float value)
571 {
572         tt->set_sync_client((value>0), tt->sync_cycles);
573 }
574
575 void tX_seqpar_vtt_sync_client :: do_update_graphics ()
576 {
577         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.sync_client), tt->is_sync_client);
578 }
579
580 const char * tX_seqpar_vtt_sync_client :: get_name()
581 {
582         return "Sync Client (On/Off)";
583 }
584
585 /**** Sequencable Parameter: TURNTABLE SYNC CYCLES ****/
586
587 tX_seqpar_vtt_sync_cycles :: tX_seqpar_vtt_sync_cycles()
588 {
589         set_mapping_parameters(0,0,0,0);
590 }
591
592 void tX_seqpar_vtt_sync_cycles :: do_exec(const float value)
593 {
594         tt->set_sync_client(tt->is_sync_client, (int) value);
595 }
596
597 void tX_seqpar_vtt_sync_cycles :: do_update_graphics ()
598 {
599         gtk_adjustment_set_value(tt->gui.cycles, tt->sync_cycles);
600 }
601
602 const char * tX_seqpar_vtt_sync_cycles :: get_name()
603 {
604         return "Sync Cycles";
605 }
606
607 /**** Sequencable Parameter: TURNTABLE LP ENABLE ****/
608
609 tX_seqpar_vtt_lp_enable :: tX_seqpar_vtt_lp_enable()
610 {
611         set_mapping_parameters(0.01,0,1,1);
612         is_boolean=true;
613 }
614
615 void tX_seqpar_vtt_lp_enable :: do_exec(const float value)
616 {
617         tt->lp_set_enable(value>0);
618 }
619
620 void tX_seqpar_vtt_lp_enable :: do_update_graphics ()
621 {
622         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.lp_enable), tt->lp_enable);
623 }
624
625 const char * tX_seqpar_vtt_lp_enable :: get_name()
626 {
627         return "Lowpass: Enable (On/Off)";
628 }
629
630 /**** Sequencable Parameter: TURNTABLE LP GAIN ****/
631
632 tX_seqpar_vtt_lp_gain :: tX_seqpar_vtt_lp_gain()
633 {
634         set_mapping_parameters(2.0,0, TX_SEQPAR_DEFAULT_SCALE, 1);
635 }
636
637 float tX_seqpar_vtt_lp_gain :: get_value() { return tt->lp_gain; }
638
639 void tX_seqpar_vtt_lp_gain :: do_exec(const float value)
640 {
641         tt->lp_set_gain(value);
642 }
643
644 const char * tX_seqpar_vtt_lp_gain :: get_name()
645 {
646         return "Lowpass: Input Gain";
647 }
648
649 void tX_seqpar_vtt_lp_gain :: do_update_graphics ()
650 {
651         gtk_adjustment_set_value(tt->gui.lp_gain, tt->lp_gain);
652 }
653
654 /**** Sequencable Parameter: TURNTABLE LP RESO ****/
655
656 tX_seqpar_vtt_lp_reso :: tX_seqpar_vtt_lp_reso()
657 {
658         set_mapping_parameters(0.99, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
659 }
660
661 float tX_seqpar_vtt_lp_reso :: get_value() { return tt->lp_reso; }
662
663 void tX_seqpar_vtt_lp_reso :: do_exec(const float value)
664 {
665         tt->lp_set_reso(value);
666 }
667
668 void tX_seqpar_vtt_lp_reso :: do_update_graphics ()
669 {
670         gtk_adjustment_set_value(tt->gui.lp_reso, tt->lp_reso);
671 }
672
673 const char * tX_seqpar_vtt_lp_reso :: get_name()
674 {
675         return "Lowpass: Resonance";
676 }
677
678 /**** Sequencable Parameter: TURNTABLE LP FREQUENCY ****/
679
680 tX_seqpar_vtt_lp_freq :: tX_seqpar_vtt_lp_freq()
681 {
682         set_mapping_parameters(0.99, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
683 }
684
685 float tX_seqpar_vtt_lp_freq :: get_value() { return tt->lp_freq; }
686
687 void tX_seqpar_vtt_lp_freq :: do_exec(const float value)
688 {
689         tt->lp_set_freq(value);
690 }
691
692 const char * tX_seqpar_vtt_lp_freq :: get_name()
693 {
694         return "Lowpass: Cutoff Frequency";
695 }
696
697 void tX_seqpar_vtt_lp_freq :: do_update_graphics ()
698 {
699         gtk_adjustment_set_value(tt->gui.lp_freq, tt->lp_freq);
700 }
701
702 /**** Sequencable Parameter: TURNTABLE ECHO ENABLE ****/
703
704 tX_seqpar_vtt_ec_enable :: tX_seqpar_vtt_ec_enable()
705 {
706         set_mapping_parameters(0.01,0,1,1);
707         is_boolean=true;
708 }
709
710 void tX_seqpar_vtt_ec_enable :: do_exec(const float value)
711 {
712         tt->ec_set_enable(value>0);
713 }
714
715 void tX_seqpar_vtt_ec_enable :: do_update_graphics ()
716 {
717         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tt->gui.ec_enable), tt->ec_enable);
718 }
719
720 const char * tX_seqpar_vtt_ec_enable :: get_name()
721 {
722         return "Echo: Enable (On/Off)";
723 }
724
725 /**** Sequencable Parameter: TURNTABLE ECHO LENGTH ****/
726
727 tX_seqpar_vtt_ec_length :: tX_seqpar_vtt_ec_length()
728 {
729         set_mapping_parameters(1.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
730 }
731
732 float tX_seqpar_vtt_ec_length :: get_value() { return tt->ec_length; }
733
734 void tX_seqpar_vtt_ec_length :: do_exec(const float value)
735 {
736         tt->ec_set_length(value);
737 }
738
739 void tX_seqpar_vtt_ec_length :: do_update_graphics ()
740 {
741         gtk_adjustment_set_value(tt->gui.ec_length, tt->ec_length);
742 }
743
744 const char * tX_seqpar_vtt_ec_length :: get_name()
745 {
746         return "Echo: Duration";
747 }
748
749 /**** Sequencable Parameter: TURNTABLE ECHO FEEDBACK ****/
750
751 tX_seqpar_vtt_ec_feedback :: tX_seqpar_vtt_ec_feedback()
752 {
753         set_mapping_parameters(1.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
754 }
755
756 float tX_seqpar_vtt_ec_feedback :: get_value() { return tt->ec_feedback; }
757
758 void tX_seqpar_vtt_ec_feedback :: do_exec(const float value)
759 {
760         tt->ec_set_feedback(value);
761 }
762
763 void tX_seqpar_vtt_ec_feedback :: do_update_graphics ()
764 {
765         gtk_adjustment_set_value(tt->gui.ec_feedback, tt->ec_feedback);
766 }
767
768 const char * tX_seqpar_vtt_ec_feedback :: get_name()
769 {
770         return "Echo: Feedback";
771 }
772
773 /**** Sequencable Parameter: TURNTABLE ECHO PAN ****/
774
775 tX_seqpar_vtt_ec_pan :: tX_seqpar_vtt_ec_pan()
776 {
777         set_mapping_parameters(1.0, -1.0, TX_SEQPAR_DEFAULT_SCALE, 1);
778 }
779
780 float tX_seqpar_vtt_ec_pan :: get_value() { return tt->ec_pan; }
781
782 void tX_seqpar_vtt_ec_pan :: do_exec(const float value)
783 {
784         tt->ec_set_pan(value);
785 }
786
787 void tX_seqpar_vtt_ec_pan :: do_update_graphics ()
788 {
789         gtk_adjustment_set_value(tt->gui.ec_pan, tt->ec_pan);
790 }
791
792 const char * tX_seqpar_vtt_ec_pan :: get_name()
793 {
794         return "Echo: Pan";
795 }
796
797 /**** Sequencable Parameter: TURNTABLE ECHO VOLUME ****/
798
799 tX_seqpar_vtt_ec_volume :: tX_seqpar_vtt_ec_volume()
800 {
801         set_mapping_parameters(0.0, 3.0, TX_SEQPAR_DEFAULT_SCALE, 1);
802 }
803
804 float tX_seqpar_vtt_ec_volume :: get_value() { return tt->ec_volume; }
805
806 void tX_seqpar_vtt_ec_volume :: do_exec(const float value)
807 {
808         tt->ec_set_volume(value);
809 }
810
811 void tX_seqpar_vtt_ec_volume :: do_update_graphics ()
812 {
813         gtk_adjustment_set_value(tt->gui.ec_volume, tt->ec_volume);
814 }
815
816 const char * tX_seqpar_vtt_ec_volume :: get_name()
817 {
818         return "Echo: Volume";
819 }
820
821
822 /**** Sequencable Parameter: TURNTABLE MUTE ****/
823
824 tX_seqpar_vtt_mute :: tX_seqpar_vtt_mute()
825 {
826         set_mapping_parameters(0.01,0,1,1);
827         is_boolean=true;
828 }
829
830 void tX_seqpar_vtt_mute :: do_exec(const float value)
831 {
832         tt->set_mute(value>0);
833 }
834
835 const char * tX_seqpar_vtt_mute :: get_name()
836 {
837         return "Mute (On/Off)";
838 }
839
840 /** LADSPA fx parameters **/
841
842 tX_seqpar_vttfx :: tX_seqpar_vttfx()
843 {
844         fx_value=(float *) malloc(sizeof(float));
845         *fx_value=0;
846         set_mapping_parameters(0,0,0,0);        
847 }
848
849 tX_seqpar_vttfx :: ~tX_seqpar_vttfx()
850 {
851         free(fx_value);
852 }
853
854 void tX_seqpar_vttfx :: set_name(const char *n, const char *sn)
855 {
856         strcpy(name, n);
857         strcpy(label_name, sn);
858         create_widget();
859 }
860
861 float tX_seqpar_vttfx :: get_value()
862 {
863         return *fx_value;
864 }
865
866 void tX_seqpar_vttfx :: create_widget()
867 {
868         fprintf(stderr, "tX: Ooops. create_widget() for tX_seqpar_vttfx.\n");
869 }
870
871 const char * tX_seqpar_vttfx :: get_name()
872 {
873         return name;    
874 }
875
876 void tX_seqpar_vttfx_float :: create_widget()
877 {
878         float tmp=max_value - min_value/1000;
879
880         *fx_value=min_value;
881         myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value, max_value, tmp, tmp, tmp));
882         mydial=new tX_extdial(label_name, myadj);
883         gtk_signal_connect(GTK_OBJECT(myadj), "value_changed", (GtkSignalFunc) tX_seqpar_vttfx_float :: gtk_callback, this);
884         widget = mydial->get_widget();  
885 }
886
887 tX_seqpar_vttfx_float :: ~tX_seqpar_vttfx_float()
888 {
889         delete mydial;  
890 }
891
892 void tX_seqpar_vttfx_float :: do_exec(const float value)
893 {
894         *fx_value=value;
895 }
896
897 void tX_seqpar_vttfx_float :: do_update_graphics()
898 {
899         gtk_adjustment_set_value(myadj, *fx_value);
900 }
901
902 GtkSignalFunc tX_seqpar_vttfx_float :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_float *sp)
903 {
904         sp->receive_gui_value(sp->myadj->value);        
905         return NULL;    
906 }
907
908 #define WID_DYN TRUE, TRUE, 0
909 #define WID_FIX FALSE, FALSE, 0
910
911 void tX_seqpar_vttfx_int :: create_widget()
912 {
913         float tmp=max_value - min_value/1000;
914         GtkWidget *tmpwid;
915
916         *fx_value=min_value;
917         myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value, max_value, tmp, tmp, tmp));
918         widget=gtk_hbox_new(FALSE, 2);
919         tmpwid=gtk_label_new(label_name);
920         gtk_widget_show(tmpwid);
921         gtk_box_pack_start(GTK_BOX(widget), tmpwid, WID_FIX);
922
923         tmpwid=gtk_spin_button_new(myadj,1.0,0);
924         gtk_widget_show(tmpwid);
925         gtk_box_pack_start(GTK_BOX(widget), tmpwid, WID_DYN);
926         
927         gtk_signal_connect(GTK_OBJECT(myadj), "value_changed", (GtkSignalFunc) tX_seqpar_vttfx_int :: gtk_callback, this);
928 }
929
930 tX_seqpar_vttfx_int :: ~tX_seqpar_vttfx_int()
931 {
932         gtk_widget_destroy(widget);
933 }
934
935 void tX_seqpar_vttfx_int :: do_exec(const float value)
936 {
937         *fx_value=value;
938 }
939
940 void tX_seqpar_vttfx_int :: do_update_graphics()
941 {
942         gtk_adjustment_set_value(myadj, *fx_value);
943 }
944
945 GtkSignalFunc tX_seqpar_vttfx_int :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_int *sp)
946 {
947         sp->receive_gui_value(sp->myadj->value);        
948         return NULL;
949 }
950
951 void tX_seqpar_vttfx_bool :: create_widget()
952 {
953         *fx_value=min_value;
954         widget=gtk_check_button_new_with_label(label_name);
955         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), 0);
956         gtk_signal_connect(GTK_OBJECT(widget), "clicked", (GtkSignalFunc) tX_seqpar_vttfx_bool :: gtk_callback, this);
957 }
958
959 tX_seqpar_vttfx_bool :: ~tX_seqpar_vttfx_bool()
960 {
961         gtk_widget_destroy(widget);
962 }
963
964 void tX_seqpar_vttfx_bool :: do_exec(const float value)
965 {
966         *fx_value=value;
967 }
968
969 GtkSignalFunc tX_seqpar_vttfx_bool :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_bool *sp)
970 {
971         sp->receive_gui_value(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sp->widget)));     
972         return NULL;
973 }
974
975 void tX_seqpar_vttfx_bool :: do_update_graphics()
976 {
977         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), *fx_value==max_value);
978 }